HDU 5441 Travel (并查集)
2015-09-16 19:45
344 查看
题目大意
n个点m条边的无向图,给出每条边的权值,给出q次询问,每次给出一个值,求用到所有边权不大于这个值的边的情况下,能够互相到达的点对的个数。分析
给m条边的权值和查询的值都从小到大排序然后对于每个查询,把不大于这个值的边加入到并查集中去,并记录第一个比查询值大的边的标号,下次查询从此标号开始即可。因此,每条边只需遍历一次。
sum[i]表示以节点i为根的子树拥有根节点的个数,因此对于每个查询的答案为
ans += (sum[x] + sum[y] ) * (sum[x] + sum[y] - 1) - sum[x] * (sum[x] - 1) + sum[y] * (sum[y] - 1);
代码
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; const int maxn = 20010; struct Edge { int from , to , v; }edge[maxn * 5]; struct Node { int id , v; }Que[maxn]; //给edge的v从小到大排序 bool cmp1(Edge const &A , Edge const &B) { return A.v < B.v; } //给Que的v从小到大排序 bool cmp2(Node const &A , Node const &B) { return A.v < B.v; } int pa[maxn] , sum[maxn]; //pa[i]表示节点i的父亲 , sum[i]表示以i为根节点的的节点数 int findset(int x) {return pa[x] != x ? pa[x] = findset(pa[x]) : x;} int ret[maxn]; int main() { int t , m , n , q; scanf("%d" , &t); while(t--) { scanf("%d%d%d" , &n , &m , &q); for(int i = 0; i < m; i++) scanf("%d%d%d" , &edge[i].from , &edge[i].to , &edge[i].v); for(int i = 0; i < q; i++) {scanf("%d" , &Que[i].v); Que[i].id = i;} sort(edge , edge + m , cmp1); sort(Que , Que + q , cmp2); //初始化并查集 for(int i = 1; i <= n; i++) {sum[i] = 1; pa[i] = i;} //一共只循环了m次 int cur = 0 , ans = 0; for(int i = 0; i < q; i++) { for(int j = cur; j < m; j++) { if(edge[j].v <= Que[i].v) { int x = findset(edge[j].from) , y = findset(edge[j].to); if(x != y) { ans -= sum[x] * (sum[x] - 1) + sum[y] * (sum[y] - 1); sum[y] += sum[x]; pa[x] = y; ans += sum[y] * (sum[y] - 1); } } else {cur = j; break;} } ret[Que[i].id] = ans; } for(int i = 0; i < q; i++) printf("%d\n" , ret[i]); } return 0; }
相关文章推荐
- HDU-1213-How Many Tables
- Longest Consecutive Sequence,Distinct Subsequences,Interleaving String,Scramble String
- SARS病毒传染 并查集
- HDU 1213
- CSU1307 并查集+SPFA
- BestWiring——Kruskal算法&并查集
- HDU-1233 还是畅通工程(最小生成树&并查集)
- Simon-【深入理解数据结构】有根树的不同实现① —— 并查集
- 家族
- poj 1417 True Liars 解题报告 并查集 DP
- poj 1161
- 并查集——HDOJ 1213How Many Tables解题报告
- 最小生成树——HDOJ 2988 Dark roads解题报告
- HDU 1198 Farm Irrigation(并查集)
- hdu 1213 How Many Tables(并查集,简单题)
- hud 1233 还是畅通工程( kruskal和prim两种方法)
- hdu 1863 畅通工程 (最小生成树kruskal 算法)
- hdu 1213并查集
- hdu 1272并查集
- hdu 1198并查集