[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;
}

 

posted @ 2018-01-16 16:35  xayata  阅读(152)  评论(0编辑  收藏  举报