• hdu 5176 The Experience of Love


    The Experience of Love

     
     Accepts: 11
     
     Submissions: 108
     Time Limit: 4000/2000 MS (Java/Others)
     
     Memory Limit: 65536/65536 K (Java/Others)
    问题描述
    一个叫Gorwin的女孩和一个叫Vivin的男孩是一对情侣。他们来到一个叫爱情的国家,这个国家由NN个城市组成而且只有N-1N1条小道(像一棵树),每条小道有一个值表示两个城市间的距离。他们选择两个城市住下,Gorwin在一个城市Vivin在另外一个,第一次约会,Gorwin去找Vivin,她会写下路径上最长的一条小道(maxValue),第二次约会,Vivin去找Gorwin,他会写下路径上最短的一条小道(minValue),然后计算maxValue减去minValue的结果作为爱情经验值,再然后重新选择两个城市居住而且计算新的爱情经验值,重复一次又一次。
    
    当他们选择过所有的情况后,请帮助他们计算一下爱情经验值的总和。
    输入描述
    大约有55组数据在输入文件。
    对于每一组测试数据,第一行一个数NN,然后N-1N1行,每行三个数aa, bb和cc,表示一条小道连接城市aa和城市bb,距离为cc.
    
    [参数说明]
    1 < N <= 150000,1 <= a, b <= n,1 <= c <= {10}^{9}1<N<=150000,1<=a,b<=n,1<=c<=109​​
    输出描述
    每组测试数据输出一行,输出格式为 Case #x: answer, x表示数据编号,answer表示爱情经验值的总和。
    输入样例
    3
    1 2 1
    2 3 2
    5
    1 2 2
    2 3 5
    2 4 7
    3 5 4
    输出样例
    Case #1: 1
    Case #2: 17
    Hint
    请注意输入文件较大。
    
    对于第一个样例:
    最大值是1最小值是1,当他们选择城市1和2,爱情经验值是0.
    最大值是2最小值是2,当他们选择城市2和3,爱情经验值是0.
    最大值是2最小值是1,当他们选择城市1和3,爱情经验值是1.
    所以爱情经验值的总和就是1。

    对于边i,与u相连的点有m个,与v相连的边有n个,如果按权值从小到大排,那么每次都能求得从m个中的一个节点到n个中的一个节点路径的最大值,就是wi,因为之前所处理的所有边权值
    都小于wi。反之求最小值也一样。
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #define LL unsigned long long
    using namespace std;
    const int Max=150000+10;
    int f[Max],num[Max];
    struct edge
    {
        int u,v,w;
    }e[Max];
    bool cmp1(edge a,edge b)
    {
        return a.w<b.w;
    }
    bool cmp2(edge a,edge b)
    {
        return a.w>b.w;
    }
    int find(int x)
    {
        return f[x]==-1?x:f[x]=find(f[x]);
    }
    int main()
    {
        int n,ca=1;
        while(~scanf("%d",&n))
        {
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
            }
            for(int i=0;i<=n;i++) f[i]=-1,num[i]=1;
            sort(e+1,e+n,cmp1);
            LL maxsum=0,t=1;
            for(int i=1;i<n;i++)
            {
                int pa=find(e[i].u);
                int pb=find(e[i].v);
                if(pa!=pb)
                {
                    f[pa]=pb;             //设pb为pa的父节点
                    maxsum+=t*num[pa]*num[pb]*e[i].w;
                    num[pb]+=num[pa];     //那么pa对到pb的节点个数和有所增益
                }
            }
            sort(e+1,e+n,cmp2);
            LL minsum=0;
            for(int i=0;i<=n;i++) f[i]=-1,num[i]=1;
            for(int i=1;i<n;i++)
            {
                int pa=find(e[i].u);
                int pb=find(e[i].v);
                if(pa!=pb)
                {
                    f[pa]=pb;
                    minsum+=t*num[pa]*num[pb]*e[i].w;
                    num[pb]+=num[pa];
                }
            }
            printf("Case #%d: %I64u
    ",ca++,maxsum-minsum);
        }
        return 0;
    }
  • 相关阅读:
    Linux c 开发-17 pugixml xml_node Collection和一个数组的值比较示例
    Linux c 开发-16 不需要头文件也可以编译???
    SourceInsight快捷键
    Linux c 开发-16 VsCode下使用CMakeFile编译项目
    java 字符串转Base64
    Linux c 开发-15 Ubuntu子系统中使用串口
    Linux c 开发-14 一例不能直接调试gdb程序的解决办法
    Ubuntu子系统与Windows互相访文件系统
    Linux c 开发-13 Makefile与VisualStudio Linux C环境对应关系
    Linux c 开发-12 创建子进程
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/5384132.html
Copyright © 2020-2023  润新知