zoukankan      html  css  js  c++  java
  • UvaLive 5026 Building Roads

    传送门

    Time Limit: 3000MS

    Description

    There is a magic planet in the space. There is a magical country on the planet. There are N cities in the country. The country is magical because there are exactly N −1 magic roads between the N cities, and from each city, it is possible to visit any other city. But after the huge expansion of the country, the road system seems to be messy. The moderator decided to rebuild the road system. As a worker, I cannot do too much things. I could just move one road to another position connecting arbitrary 2 cities using my magic, keeping its length unchanged. Of course, afterwards all the N cities have to be still connected. I wonder how to move in order to make the farthest distance between any two cities minimum. Could you solve it for me?

    Input

    The first line of the input is one integer T (T ≤ 10), and then T test cases follow. Each test case begins with a line contains only one integer N (N ≤ 2500), means there are N magic cities. The cities are numbered from 0 to N − 1. Following N − 1 lines, each line has 3 integers a, b and c, means there is a magic road between a and b with distance c. (0 ≤ a, b < N, 0 < c ≤ 1000)

    Output

    For each test case, output the case number and the corresponding minimum farthest distance. See sample for detailed format.

    Sample Input

    2

    4

    0 1 2

    1 2 2

    2 3 2

    5

    0 1 1

    1 2 2

    2 3 3

    3 4 4

    Sample Output

    Case 1: 4

    Case 2: 7

    -----------------------------------------------------------

    这是2010年天津站的B题

    题意:给定一棵带边权的树,可将其中的一条边重连,形成一棵新树,求新树中最长路的最小值。

    Solution:

    枚举边,求重连该边后新树中最长路径的最小值。

    求法:

    设删去长为c的边(u,v)后形成的两子树的点集分别是 L, R

    分别求两子树中从每个节点u出发的最长距离d[u](复杂度O(n), 参考这篇博客), 显然新边应连在两子树中d最小的两节点之间。

    这样得到的新树中的最长路径就是max(max{d[u], U}, min{d[u] : ∈ L, d[v] : ∈ R} + c

    总复杂度O(n^2)

     Implementation:

    #include <bits/stdc++.h>
    using namespace std;
    const int N(2500+5);
    typedef pair<int,int> P;
    struct edge{
        int u, v, c, flag, nt;
    }E[N<<1];
    int head[N], dp[3][N];
    void dfs1(int u, int f){
        dp[0][u]=dp[1][u]=0;
        for(int i=head[u]; ~i; i=E[i].nt){
            int &v=E[i].v, &c=E[i].c;
            if(v==f||E[i].flag) continue;
            dfs1(v, u);
            if(dp[0][v]+c > dp[0][u])
                dp[1][u]=dp[0][u], dp[0][u]=dp[0][v]+c;
            else dp[1][u]=max(dp[1][u], dp[0][v]+c);
        }
    }
    P dfs2(int u, int f){
        int mi, ma=mi=max(dp[0][u], dp[2][u]);
        for(int i=head[u]; ~i; i=E[i].nt){
            int &v=E[i].v, &c=E[i].c;
            if(v==f||E[i].flag) continue;
            dp[2][v]=c+max(dp[2][u], dp[0][u]==dp[0][v]+c?dp[1][u]:dp[0][u]);
            P res=dfs2(v, u);
            mi=min(mi, res.first), ma=max(ma, res.second);
        }
        return {mi, ma};
    }
    int main(){
        int T; scanf("%d", &T);
        for(int n, cs=0, ans; T--;){
            scanf("%d", &n);
            memset(head, -1, sizeof(head));
            for(int i=1, u, v, c, id=0; i<n; ++i){
                scanf("%d%d%d", &u, &v, &c);
                E[id]={u, v, c, 0, head[u]}, head[u]=id++;
                E[id]={v, u, c, 0, head[v]}, head[v]=id++;
            }
            P p1, p2;
            ans=INT_MAX;
            for(int i=0; i<(n-1)<<1; i+=2){
                E[i].flag=E[i^1].flag=1;
                int &u=E[i].u, &v=E[i].v, &c=E[i].c;
                dfs1(u, u), dp[2][u]=0, p1=dfs2(u, u);
                dfs1(v, v), dp[2][v]=0; p2=dfs2(v, v);
                ans=min(ans, max(max(p1.second, p2.second), p1.first+p2.first+c));
                E[i].flag=E[i^1].flag=0;
            }
            printf("Case %d: %d
    ", ++cs, ans);
        }
    }
  • 相关阅读:
    两次动态输入和while的结合使用
    索引切片步长
    12.⽤户登陆(三次输错机会)且每次输错误时显示剩余错误次数(提示:使⽤字符串格式化)
    输出1-100的所以奇数或偶数
    求1-2+3-4+5 ... 99的所有数的和
    求1-100所有数的和
    三次登录机会
    while输入12345689
    while和格式化输出的复合使用
    44
  • 原文地址:https://www.cnblogs.com/Patt/p/4873579.html
Copyright © 2011-2022 走看看