卧薪尝胆,厚积薄发。
免费航班
Date: Sat Oct 27 16:18:24 CST 2018 In Category: NoCategory

Description:

如果有两个点之间有两条及以上路径,那么他们在一个国家内,一个国家内的边不需要费用,问离每个城市最远的城市距离是多少。
$1\leqslant n\leqslant 20000,1\leqslant m\leqslant 200000$

Solution:

发现一个国家就是一个边双,于是边双缩点 $+$ 树形 $DP$ 就行了。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cctype>
#include<cstring>
using namespace std;
#define R register
inline int rd()
{
R int res = 0,f = 1;
R char c = getchar();
while(!isdigit(c))
{
if(c == '-')f = -1;
c = getchar();
}
while(isdigit(c))
{
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res * f;
}
int n,m;
#define MAXN 20010
#define MAXM 200010
struct edge
{
int to,nxt,v;
}e[MAXM << 1],ve[MAXN << 1];
int edgenum = 0;
int lin[MAXN] = {0};
inline void add(int a,int b,int c)
{
e[edgenum] = (edge){b,lin[a],c};lin[a] = edgenum++;
e[edgenum] = (edge){a,lin[b],c};lin[b] = edgenum++;
return;
}
int vedgenum = 0;
int vlin[MAXN] = {0};
inline void vadd(int a,int b,int c)
{
ve[vedgenum] = (edge){b,vlin[a],c};vlin[a] = vedgenum++;
return;
}
int dfn[MAXN],low[MAXN],tot = 0;
bool bridge[MAXM << 1];
void tarjan(int k,int ine)
{
dfn[k] = low[k] = ++tot;
for(int i = lin[k];i != -1;i = e[i].nxt)
{
if(i == (ine ^ 1))continue;
if(dfn[e[i].to] == 0)
{
tarjan(e[i].to,i);
low[k] = min(low[k],low[e[i].to]);
if(low[e[i].to] > dfn[k])
{
bridge[i] = bridge[i ^ 1] = true;
}
}
else
{
low[k] = min(low[k],dfn[e[i].to]);
}
}
return;
}
bool v[MAXN];
int edcc = 0,ins[MAXN];
void dfs(int k)
{
v[k] = true;ins[k] = edcc;
for(int i = lin[k];i != -1;i = e[i].nxt)
{
if(!bridge[i] && !v[e[i].to])
{
dfs(e[i].to);
}
}
return;
}
int f[MAXN];
void dp1(int k)
{
v[k] = true;
for(int i = vlin[k];i != -1;i = ve[i].nxt)
{
if(v[ve[i].to])continue;
dp1(ve[i].to);
f[k] = max(f[k],f[ve[i].to] + ve[i].v);
}
return;
}
int g[MAXN];
void dp2(int k)
{
v[k] = true;
int fr,len,maxv = 0;
for(int i = vlin[k];i != -1;i = ve[i].nxt)
{
if(v[ve[i].to])continue;
if(f[ve[i].to] + ve[i].v > maxv)
{
maxv = f[ve[i].to] + ve[i].v;
fr = ve[i].to;len = ve[i].v;
}
}
for(int i = vlin[k];i != -1;i = ve[i].nxt)
{
if(v[ve[i].to])continue;
g[ve[i].to] = g[k] + ve[i].v;
if(ve[i].to != fr)g[ve[i].to] = max(g[ve[i].to],maxv + ve[i].v);
}
for(int i = vlin[k];i != -1;i = ve[i].nxt)
{
if(v[ve[i].to] || ve[i].to == fr)continue;
g[fr] = max(g[fr],f[ve[i].to] + ve[i].v + len);
}
for(int i = vlin[k];i != -1;i = ve[i].nxt)
{
if(v[ve[i].to])continue;
dp2(ve[i].to);
}
return;
}
int main()
{
memset(lin,-1,sizeof(lin));
memset(vlin,-1,sizeof(vlin));
n = rd();m = rd();
int a,b,c;
for(int i = 1;i <= m;++i)
{
a = rd();b = rd();c = rd();
add(a,b,c);
}
tarjan(1,-1);
for(int i = 1;i <= n;++i)
{
if(!v[i])
{
++edcc;
dfs(i);
}
}
for(int k = 1;k <= n;++k)
for(int i = lin[k];i != -1;i = e[i].nxt)
if(bridge[i])vadd(ins[k],ins[e[i].to],e[i].v);
memset(v,false,sizeof(v));
dp1(1);
memset(v,false,sizeof(v));
dp2(1);
for(int i = 1;i <= n;++i)
{
printf("%d\n",max(f[ins[i]],g[ins[i]]));
}
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡