HDU 5176 The Experience of Love(带权并查集)

The Experience of Love

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 309    Accepted Submission(s): 119


Problem Description
A girl named Gorwin and a boy named Vivin is a couple. They arrived at a country named LOVE. The country consisting of  N  cities and only  N1  edges (just like a tree), every edge has a value means the distance of two cities. They select two cities to live,Gorwin living in a city and Vivin living in another. First date, Gorwin go to visit Vivin, she would write down the longest edge on this path(maxValue).Second date, Vivin go to Gorwin, he would write down the shortest edge on this path(minValue),then calculate the result of maxValue subtracts minValue as the experience of love, and then reselect two cities to live and calculate new experience of love, repeat again and again.

Please help them to calculate the sum of all experience of love after they have selected all cases.
 

Input
There will be about  5  cases in the input file.
For each test case the first line is a integer  N , Then follows  n1  lines, each line contains three integers  a b , and  c , indicating there is a edge connects city  a  and city  b  with distance  c .

[Technical Specification]
1<N<=150000,1<=a,b<=n,1<=c<=109
 

Output
For each case,the output should occupies exactly one line. The output format is Case #x: answer, here x is the data number, answer is the sum of experience of love.
 

Sample Input
  
  
3 1 2 1 2 3 2 5 1 2 2 2 3 5 2 4 7 3 5 4
 

Sample Output
  
  
Case #1: 1 Case #2: 17
Hint
huge input,fast IO method is recommended. In the first sample: The maxValue is 1 and minValue is 1 when they select city 1 and city 2, the experience of love is 0. The maxValue is 2 and minValue is 2 when they select city 2 and city 3, the experience of love is 0. The maxValue is 2 and minValue is 1 when they select city 1 and city 3, the experience of love is 1. so the sum of all experience is 1;
 

Source
 
题意:给一棵树,求任意{两点路径上的最大边权值-最小边权值}的总和。
解法:
sigma(maxVal[i]-minVal[i]) = sigma(maxVal)-sigma(minVal); 
所以我们分别求所有两点路径上的最大值的和,还有最小值的和。再相减就可以了。求最大值的和的方法用带权并查集,把边按权值从小到大排序,一条边一条边的算,当我们算第
     
     
      
      i
     
     条边的时候权值为
     
     
      
      wi
     
     ,两点是
     
     
      
      ui,vi
     
     ,前面加入的边权值一定是小于等于当前
     
     
      
      wi
     
     的,假设与
     
     
      
      ui
     
     连通的点有
     
     
      
      a
     
     个,与
     
     
      
      vi
     
     连通的点有
     
     
      
      b
     
     个,那么在
     
     
      
      a
     
     个中选一个,在
     
     
      
      b
     
     个中选一个,这两个点的路径上最大值一定是
     
     
      
      wi
     
     ,一共有
     
     
      
      ab
     
     个选法,爱情经验值为
     
     
      
      abwi
     
     。求最小值的和的方法类似。
program:
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef unsigned long long ULL;
#define N 200000
int p[N];
ULL r[N];
struct Edge
{
    int u, v;
    ULL w;
}e[N];
bool cmp(Edge c, Edge d) {return c.w < d.w;}

int find(int x) {return p[x] == x ? x : p[x]=find(p[x]);}

int main()
{
    int n, t = 1;

    while(~scanf("%d", &n))
    {
        int m = n-1;
        for(int i=1; i<=m; i++)
            scanf("%d%d%llu", &e[i].u,&e[i].v,&e[i].w);
        sort(e+1,e+m+1,cmp);
        for(int i=1; i<=n; i++) p[i] = i, r[i] = 1;
        ULL res = 0;
        for(int i=1; i<=m; i++)
        {
            int x = find(e[i].u);
            int y = find(e[i].v);
            res += r[x]*r[y]*e[i].w;
            p[y] = x; //x是始祖
            r[x] += r[y];
        }
        for(int i=1; i<=n; i++) p[i] = i, r[i] = 1;
        for(int i=m; i>=1; i--)
        {
            int x = find(e[i].u);
            int y = find(e[i].v);
            res -= r[x]*r[y]*e[i].w;
            p[y] = x;
            r[x] += r[y];
        }
        printf("Case #%d: %llu\n", t++,res);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值