http://acm.hdu.edu.cn/showproblem.php?pid=5441

题目大意是给一个n个城市(点)m条路线(边)的双向的路线图,每条路线有时间值(带权图),然后q个询问,每个询问一个时间值

求不大于这个时间的可以连通的城市有多少种连法

比如样例中第一个询问6000,不大于6000时间值的连通城市有3,5.所以有3-->5,5-->3两种

第二个询问10000,符合条件的连通的城市有2,3,5,所以有2-->3,3-->2,2-->5,5-->2,3-->5,5-->3六种

利用结构体储存点与权值然后把权值排序,找出符合条件的城市点,利用并查集记录相连的点然后合并,整合路线

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int father[20001],num[20001];
 6 int a[20001];
 7 void lsy(int n)
 8 {
 9     for (int i=1;i<=n;i++)
10     {
11         father[i]=i;
12         num[i]=1;
13     }
14 }
15 struct point {
16     int x,y,z;
17     bool operator <(const point& q)const
18     {
19         return z<q.z;
20     }
21 };
22 point yj[100001];
23 struct node {
24     int w,id;
25     bool operator <(const node &q)const
26     {
27         return w<q.w;
28     }
29 };
30 node yjj[20001];
31 int _find(int x)
32 {
33     if (father[x]==x)return x;
34     father[x]=_find(father[x]);
35     return father[x];
36 }
37 int main()
38 {
39     int t,n,m,q,i;
40     while (~scanf("%d",&t))
41     {
42         while (t--)
43         {
44             scanf("%d %d %d",&n,&m,&q);
45             memset(a,0,sizeof(a));
46             for (i=1;i<=m;i++)
47                scanf("%d %d %d",&yj[i].x,&yj[i].y,&yj[i].z);
48             sort(yj+1,yj+m+1);
49             lsy(n);
50             for (i=1;i<=q;i++)
51             {
52                 scanf("%d",&yjj[i].w);
53                 yjj[i].id=i;
54             }
55             sort(yjj+1,yjj+q+1);
56             int ans=0,j=1;
57             for (i =1;i<=q;i++)
58             {
59                 while (j<=m&&yj[j].z<=yjj[i].w )
60                 {
61                     int sx=_find(yj[j].x);
62                     int sy=_find(yj[j].y);
63                     j++;
64                     if (sx==sy) continue;
65                     ans+=(num[sx]+num[sy])*(num[sx]+num[sy]-1)-num[sx]*(num[sx]-1) - num[sy]*(num[sy]-1);//合并之后的关系
66                     father[sx]=sy;
67                     num[sy]+=num[sx];
68                 }
69                 a[yjj[i].id]=ans;
70             }
71             for (i=1;i<=q;i++)
72                 printf("%d\n",a[i]);
73         }
74     }
75     return 0;
76 }

 

posted on 2015-09-14 20:01  蜘蛛侦探  阅读(121)  评论(0编辑  收藏  举报