hdu 5441 (2015长春网络赛E题 带权并查集 )

n个结点,m条边,权值是 从u到v所花的时间 ,每次询问会给一个时间,权值比 询问值小的边就可以走 从u到v 和从v到u算不同的两次 输出有多少种不同的走法(大概是这个意思吧)
先把边的权值 从小到大排序 询问值也按从小到大排序
num记录集合里元素的个数
每合并两个集合 ans增加 2*num[u]*num[v]

Sample Input
1
5 5 3 //n w q
2 3 6334
1 5 15724
3 5 5705
4 3 12382
1 3 21726
6000
10000
13000

Sample Output
2
6
12

 

  1 # include <iostream>
  2 # include <cstdio>
  3 # include <cstring>
  4 # include <algorithm>
  5 # include <cmath>
  6 # include <queue>
  7 # define LL long long
  8 using namespace std ;
  9 
 10 const int MAXN = 20010;
 11 
 12 int F[MAXN];
 13 int num[MAXN] ;
 14 int save[MAXN] ;
 15 int n , m , q;
 16 
 17 struct Edge
 18 {
 19     int u ;
 20     int v ;
 21     int w ;
 22 }e[MAXN * 5];
 23 
 24 bool cmp1(Edge x , Edge y)
 25 {
 26     return x.w < y.w ;
 27 }
 28 
 29 struct Que
 30 {
 31     int id ;
 32     int x ;
 33 }a[MAXN];
 34 
 35 bool cmp2(Que a , Que b)
 36 {
 37     return a.x < b.x ;
 38 }
 39 
 40 int find(int x)
 41 {
 42     if(F[x]==x) return x;
 43     return F[x]=find(F[x]);
 44 }
 45 void bing(int u,int v) 
 46 {
 47     int x = find(u);
 48     int y = find(v);
 49     if ( y < x )
 50         swap ( x , y );
 51     F[y] = x;
 52     num[x] += num[y];
 53 }
 54 
 55 int main ()
 56 {
 57     //freopen("in.txt","r",stdin) ;
 58     int T ;
 59     scanf("%d" , &T) ;
 60     while(T--)
 61     {
 62         int ans = 0 ;
 63         int j = 0 ;
 64         int i ;
 65         scanf("%d%d%d" , &n , &m , &q) ;
 66         for(i = 1 ; i <= n ; i++)
 67         {
 68              F[i] = i ;
 69              num[i] = 1 ;
 70         }
 71         for(i = 0 ; i < m ; i++)
 72             scanf("%d%d%d" , &e[i].u , &e[i].v , &e[i].w) ;
 73         sort(e , e+m , cmp1) ;
 74         for(i = 0 ; i < q ; i++)
 75         {
 76             scanf("%d" , &a[i].x) ;
 77             a[i].id = i ;
 78         }
 79         sort(a,a+q,cmp2) ;
 80         for(i = 0 ; i < q ; i++)
 81         {
 82             while(j < m && e[j].w <= a[i].x)
 83             {
 84                 int u = find(e[j].u);
 85                 int v = find(e[j].v);
 86                 j++ ;
 87                 if (u == v)
 88                     continue ;
 89                 ans += 2*num[u]*num[v] ;
 90                 bing(u,v) ;
 91             }
 92             save[a[i].id] = ans;
 93         }
 94         for(i = 0 ; i < q ; i++)
 95             printf("%d\n" , save[i]) ;
 96 
 97     }
 98 
 99     return 0 ;
100 }
View Code

 

posted @ 2015-09-15 22:18  __Meng  阅读(179)  评论(0编辑  收藏  举报