首页 > 技术文章 > 2017-5-14 湘潭市赛 Highway 先获得直径S,T。则一开始S,T相连,然后其他的点如果离S更远那么连在S,否则T;

xiaochaoqun 2017-05-15 14:01 原文

Highway
Accepted : 33           Submit : 137
Time Limit : 4000 MS           Memory Limit : 65536 KB

Highway

In ICPCCamp there were n towns conveniently numbered with 1,2,…,n connected with (n−1) roads. The i-th road connecting towns ai and bi has length ci. It is guaranteed that any two cities reach each other using only roads.

Bobo would like to build (n−1) highways so that any two towns reach each using only highways. Building a highway between towns x and y costs him δ(x,y) cents, where δ(x,y) is the length of the shortest path between towns x and y using roads.

As Bobo is rich, he would like to find the most expensive way to build the (n−1) highways.
Input

The input contains zero or more test cases and is terminated by end-of-file. For each test case:

The first line contains an integer n. The i-th of the following (n−1) lines contains three integers ai, bi and ci.

    1≤n≤105
    1≤ai,bi≤n
    1≤ci≤108
    The number of test cases does not exceed 10.

Output

For each test case, output an integer which denotes the result.
Sample Input

5
1 2 2
1 3 1
2 4 2
3 5 1
5
1 2 2
1 4 1
3 4 1
4 5 2

Sample Output

19
15


Source
XTU OnlineJudge 

/**
题目:Highway
链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1267
题意:给定n个点,以及n-1条边,就是一颗无根树。两点之间的距离为他们的最短距离。现在要利用n个点之间的各自的最短距离,把他们转化为另一颗无根树,使得所有点有n-1条边相连,且边的长度和最大。
即:新的无根树,两个点之间的距离为原来无根树他们的最短距离。如何构造无根树,才能使边的总长度最大。求出这个长度值。
思路:
先获得直径S,T。则一开始S,T相连,然后其他的点如果离S更远那么连在S,否则T;


*/

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
const int maxn = 1e5+100;
vector<P> G[maxn];
LL dis[maxn], disS[maxn], disT[maxn];
void dfs(int u,int &x,int f)
{
    if(dis[u]>dis[x]) x = u;
    int len = G[u].size();
    for(int i = 0; i < len; i++){
        int v = G[u][i].first, w = G[u][i].second;
        if(v==f) continue;
        dis[v] = dis[u]+w;
        dfs(v,x,u);
    }
}
void dfs1(int u,int f)
{
    int len = G[u].size();
    for(int i = 0; i < len; i++){
        int v = G[u][i].first, w = G[u][i].second;
        if(v==f) continue;
        disS[v] = disS[u]+w;
        dfs1(v,u);
    }
}
void dfs2(int u,int f)
{
    int len = G[u].size();
    for(int i = 0; i < len; i++){
        int v = G[u][i].first, w = G[u][i].second;
        if(v==f) continue;
        disT[v] = disT[u]+w;
        dfs2(v,u);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        int u, v, w;
        for(int i = 1; i <= n; i++) G[i].clear();
        for(int i = 1; i < n; i++){
            scanf("%d%d%d",&u,&v,&w);
            G[u].push_back(P(v,w));
            G[v].push_back(P(u,w));
        }
        int S = 1, T;
        dis[1] = 0;
        dfs(1,S,1);
        dis[S] = 0;
        T = S;
        dfs(S,T,S);
        memset(disS, 0, sizeof disS);
        dfs1(S,S);
        memset(disT, 0, sizeof disT);
        dfs2(T,T);
        LL ans = disS[T];
        for(int i = 1; i <= n; i++){
            if(i!=S&&i!=T) ans += max(disS[i],disT[i]);
        }
        cout<<ans<<endl;
    }
    return 0;
}

 

推荐阅读