hdu 3938(离线的并查集)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3938

思路:对于边进行从小到大进行排序,题目要求a、b两点之间所有的路径中的最大边的最小值,在满足边的大小<=len的条件下,令r1=Find(a),r2=Find(b),若r1==r2,此时就是简单的合并,并且更新一下集合的个数(abs(parent[i])即为以i为根结点的集合的大小),若r1!=r2,此时a,b两点之间的路径的条数即为parent[r1]*parent[r2]。显然对于那些边>=len的,都要加上原先的路径数目。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define MAXN 10000+100
 7 #define MAXM 50000+555
 8 typedef long long LL;
 9 int parent[MAXN];
10 int n,m,q;
11 LL path[MAXN];
12 struct Edge{
13     int u,v,w;
14 }edge[MAXM];
15 
16 struct Node{
17     int id,len;
18 }p[MAXN];
19 
20 int Find(int x)
21 {
22     int s;
23     for(s=x;parent[s]>=0;s=parent[s])
24     ;
25     while(x!=s){
26         int tmp=parent[x];
27         parent[x]=s;
28         x=tmp;
29     }
30     return s;
31 }
32 
33 int  Union(int u,int v)
34 {
35     int r1=Find(u),r2=Find(v);
36     if(r1==r2)return 0;
37     int tmp=parent[r1]*parent[r2];
38     if(parent[r1]<parent[r2]){
39         parent[r1]+=parent[r2];
40         parent[r2]=r1;
41     }else {
42         parent[r2]+=parent[r1];
43         parent[r1]=r2;
44     }
45     return tmp;
46 }
47 
48 int cmp1(const Edge &a,const Edge &b)
49 {
50     return a.w<b.w;
51 }
52 
53 int cmp2(const Node &a,const Node &b)
54 {
55     return a.len<b.len;
56 }
57 
58 
59 int main()
60 {
61     while(~scanf("%d%d%d",&n,&m,&q)){
62         memset(parent,-1,sizeof(int)*(n+2));
63         for(int i=0;i<m;i++){
64             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
65         }
66         sort(edge,edge+m,cmp1);
67         for(int i=0;i<q;i++){
68             scanf("%d",&p[i].len);
69             p[i].id=i;
70         }
71         sort(p,p+q,cmp2);
72         LL ans=0;
73         int pos=0;
74         for(int i=0;i<q;i++)
75         {
76             while(pos<m&&edge[pos].w<=p[i].len){
77                 ans+=Union(edge[pos].u,edge[pos].v);
78                 pos++;
79             }
80             path[p[i].id]=ans;
81         }
82         for(int i=0;i<q;i++)
83             printf("%I64d\n",path[i]);
84     }
85     return 0;
86 }
View Code

 

posted @ 2013-06-08 21:05  ihge2k  阅读(372)  评论(0编辑  收藏  举报