hdu5443The Water Problem 并查集
2015-09-15 21:37
281 查看
//给一个无向图 //每条边有对应的权值,问对于权值不能大于x的所有 //有多少对互相能到达的点 //直接记录下所有边,按权值大小排序 //然后将所有询问离线,排序 //对于小于x的所有边,用并查集将它们连接在一起 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> #include<vector> using namespace std ; const int maxm = 1e5+10 ; const int maxn = 2e4+10 ; int vis[maxn] ; int F[maxn]; int sum[maxn] ; int ans = 0 ; int find(int x) { if(F[x] == -1) return x ; return F[x] = find(F[x]) ; } void join(int x , int y) { int fx = find(x) ; int fy = find(y) ; if(fx == fy) return ; F[fx] = fy ; ans += sum[fx]*sum[fy]*2 ; sum[fy] += sum[fx] ; sum[fx] = 0 ; } pair<int, int>q[maxn] ; struct node { int u , v , w ; bool operator < (struct node tmp)const { return w < tmp.w ; } }edge[maxm<<1] ; int a[maxn] ; int main() { int t ; scanf("%d" , &t) ; while(t--) { int n , m , Q ; scanf("%d%d%d" ,&n , &m , &Q) ; memset(F , -1, sizeof(F)) ; for(int i = 1;i <= n;i++) sum[i] = 1 ; for(int i = 1;i <= m;i++) scanf("%d%d%d" , &edge[i].u , &edge[i].v , &edge[i].w) ; sort(edge+1 , edge+1+m) ; for(int i = 1;i <= Q;i++) { int tmp ; scanf("%d" ,&tmp) ; q[i] = make_pair(tmp , i) ; } sort(q+1 , q+1+Q) ; ans = 0 ; int j = 1 ; for(int i = 1;i <= Q;i++) { while(edge[j].w <= q[i].first && j <= m) join(edge[j].u , edge[j].v) ,j++; a[q[i].second] = ans ; } for(int i = 1;i <= Q;i++) cout<<a[i]<<endl; } return 0 ; }
相关文章推荐
- 音乐(多媒体)SoundPool,MediaRecorder和Mediaplayer
- 软件测试理论知识总结
- Qt 学习之路:模型-视图高级技术
- 9-15考试题目程序作业
- cocos2dx
- JQuery直接调用asp.net后台WebMethod方法
- 面试题_抽象类和接口的区别
- java 多参数与this
- 【Android开源项目解析】仿支付宝付款成功及"天女散花"效果实现——看PathMeasure大展身手
- 海浪
- 啥?
- [LeetCode]:144:Binary Tree Preorder Traversal
- tar解压
- 0915Android基础MediaRecorder
- Ubuntu编译安装llvm-clang
- [LeetCode]:94:Binary Tree Inorder Traversal
- java关键字transient与volatile小结
- N次剩余
- WebMethod属性详解
- MFC 截图操作详解。