码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5441 离线处理 + 并查集

时间:2015-09-14 23:59:20      阅读:411      评论:0      收藏:0      [点我收藏+]

标签:

题意:给n个节点m条带权值边的无向图。然后q个问题,每次询问点对的数目,点对需要满足的条件是:1)连通;2)其路径的最大权值不能超过询问值。

分析:如果没次询问一次,dfs一次,很可能超时,因此可以用并查集。离线处理,把边按权值排序,把问题按大小排序。然后离线的过程就是不断向图中加边的过程。

比如样例如下:

技术分享

然后离线处理,排完序后将会是一条一条的加边:问题也排了序,因此是个累加过程。。。

技术分享

技术分享

技术分享

技术分享
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <sstream>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <string>
 8 #include <vector>
 9 #include <map>
10 #include <set>
11 #include <queue>
12 #include <stack>
13 #include <algorithm>
14 #define ll long long
15 #define mem(m, a) memset(m, a, sizeof(m))
16 #define repu(i, a, b) for(int i = a; i < b; i++)
17 #define maxn 100005
18 const double PI=-acos(-1.0);
19 using namespace std;
20 struct node
21 {
22     int x,y,z;
23     bool operator < (const node &a) const
24     {
25         return z < a.z;
26     }
27 } e[maxn];
28 struct Q
29 {
30     int w,id;
31     bool operator < (const Q &a) const
32     {
33         return w < a.w;
34     }
35 } q[maxn];
36 int ans[maxn];
37 int fa[maxn],num[maxn];
38 int find_set(int x)
39 {
40     if(x==fa[x])
41         return fa[x];
42     else
43         return fa[x]=find_set(fa[x]);
44 }
45 int main()
46 {
47     int n,m,k,t;
48     scanf("%d",&t);
49     while(t--)
50     {
51         scanf("%d%d%d",&n,&m,&k);
52         repu(i,0,m)
53         scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
54         repu(i,0,k)
55         scanf("%d",&q[i].w),q[i].id=i;
56         sort(e,e+m);
57         sort(q,q+k);
58         repu(i,1,1+n)
59         fa[i]=i,num[i]=1;
60         int cnt=0,j=0;
61         repu(i,0,k)
62         {
63             while(j<m&&e[j].z<=q[i].w)
64             {
65                 int x=find_set(e[j].x);
66                 int y=find_set(e[j].y);///找各自的所属的集合编号
67                 if(x != y)
68                 {
69                     cnt += num[x]*num[y];///各自集合的数目相乘
70                     fa[x] = y;///因为已经统一集合了
71                     num[y] += num[x];///y集合的数目就可以直接加上x的数目
72                 }
73                 j++;
74             }
75             ans[q[i].id] = 2*cnt;
76         }
77         repu(i,0,k)
78         printf("%d\n",ans[i]);
79     }
80     return 0;
81 }
View Code

 

HDU 5441 离线处理 + 并查集

标签:

原文地址:http://www.cnblogs.com/ACMERY/p/4808889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!