[DK] 化学竞赛的大奖
https://www.luogu.org/problemnew/show/T16502
无向图 缩点 树的直径 到直径两个端点的距离的较大值
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; const int N = 2e5 + 10; #define yxy getchar() int n, m, now = 1, now_2 = 1, Tarjan_tim, Top, Bel_tim, Root, Max_d; int head[N], head_2[N], Stack[N], Dfn[N], Low[N], Bel[N], dis[N], dist[N]; bool vis[N]; struct Node {int u, v, w, nxt;} E[N << 1]; struct Node_2 {int u, v, w, nxt;} G[N << 1]; inline int read(){ int x = 0; char c = yxy; while(c < '0' || c > '9') c = yxy; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = yxy; return x; } void add_E(int u, int v, int w){ E[now].v = v; E[now].w = w; E[now].nxt = head[u]; head[u] = now ++; } void Tarjan(int u, int fa){ Dfn[u] = Low[u] = ++ Tarjan_tim; vis[u] = 1; Stack[++ Top] = u; for(int i = head[u]; ~ i; i = E[i].nxt) { int v = E[i].v; if(!Dfn[v]){ Tarjan(v, u); Low[u] = min(Low[u], Low[v]); } else if(vis[v] && v != fa) Low[u] = min(Low[u], Low[v]); } if(Dfn[u] == Low[u]){ ++ Bel_tim; Bel[u] = Bel_tim; vis[u] = 0; while(Stack[Top] != u){ Bel[Stack[Top]] = Bel_tim; vis[Stack[Top]] = 0; Top --; } Top --; } } void add_G(int u, int v, int w){ G[now_2].v = v; G[now_2].w = w; G[now_2].nxt = head_2[u]; head_2[u] = now_2 ++; } void Build_G(){ for(int i = 1; i <= n; i ++) head_2[i] = -1; for(int u = 1; u <= n; u ++) for(int i = head[u]; ~ i; i = E[i].nxt) if(Bel[u] != Bel[E[i].v]) add_G(Bel[u], Bel[E[i].v], E[i].w); } void dfs_first(int u, int fa){ for(int i = head_2[u]; ~ i; i = G[i].nxt){ int v = G[i].v; if(v == fa) continue ; dis[v] = dis[u] + G[i].w; if(dis[v] > Max_d) Max_d = dis[v], Root = v; dfs_first(v, u); } } void dfs_second(int u, int fa){ for(int i = head_2[u]; ~ i; i = G[i].nxt){ int v = G[i].v; if(v == fa) continue ; dist[v] = dist[u] + G[i].w; dfs_second(v, u); } } void Get_Answer(){ dfs_first(1, -1); memset(dis, 0, sizeof dis); Max_d = 0; dfs_first(Root, -1); Max_d = 0; dfs_second(Root, -1); for(int i = 1; i <= n; i ++) printf("%d\n", max(dis[Bel[i]], dist[Bel[i]])); } int main() { n = read(); m = read(); for(int i = 1; i <= n; i ++) head[i] = -1; for(int i = 1; i <= m; i ++){ int u = read(), v = read(), w = read(); add_E(u, v, w); add_E(v, u, w); } for(int i = 1; i <= n; i ++) if(!Dfn[i]) Tarjan(i, 0); Build_G(); Get_Answer(); return 0; }