HDU 3047 带权并查集
2015-06-04 16:26
281 查看
冲突的条件是:用一个dist数组来保存节点到根的距离,这个距离在路径压缩的时候更新一下,dist[x]+=dist[parent[x]],然后 在合并时,令r1=Find(u),r2=Find(v),于是合并时就有parent[r2]=r1,dist[r2]=dist[u]+w-dist[v]。
#include<cstdio> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<cstdlib> #include<cstring> #include<map> #include<string> using namespace std; typedef long long ll; const int maxn = 50005; int n,m; int par[maxn]; int dis[maxn]; void init(){ memset(par,-1,sizeof(par)); memset(dis,0,sizeof(dis)); } int find(int x){ int t = x; int tmp = 0; bool isRoot = true; while(par[t] >= 0){ isRoot = false; tmp += dis[t]; t = par[t]; } if(isRoot) return x; else{ dis[x] = tmp; return par[x] = t; } } bool unite(int x,int y,int k){ int fax = find(x); //cout<<x<<" "<<fax<<endl; int fay = find(y); //cout<<y<<" "<<fay<<endl; if(fax == fay && dis[y] != dis[x] + k) return true; if(fax == fay) return false; par[fay] = fax; dis[fay] = dis[x] + k - dis[y]; return false; } bool same(int x,int y){ return find(x) == find(y); } int main(){ while(~scanf("%d%d",&n,&m)){ init(); int a,b,c,ans = 0; while(m--){ scanf("%d%d%d",&a,&b,&c); //printf("!!!!!!\n"); if(unite(a,b,c)){ ans++; //cout<<a<<" "<<b<<" "<<c<<endl; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ2155二维线段树
- iOS block内部更新主界面
- 自定义组合控件关于LayoutInflater.from(context).inflate(R.layout.view_title, this,true)的问题
- java中substring的使用方法
- JS实现验证码倒计时效果
- ZJ 虚拟机扩磁盘
- Spring MVC
- 多事的键盘
- 物联网技术上面临的基本问题和操作系统设计
- ASP.NET MVC4中调用WEB API的四个方法
- 江湖夜雨十年灯(要坚持,要能承受惨败的结果)
- kvc & kvo
- 推送 延迟的 原因,,,
- IDEA14.1 console log4j utf-8乱码
- Oracle传输表空间学习
- python模块ConfigParser操作配置文件
- rmmod:chdir(lib/modules):No such file or director 4000 y
- android引入JAR包,打包成JAR包,打包成Library项目,导入Library项目
- 第十二周 课后实践:项目二——摩托车继承自行车和机动车
- 全面理解面向对象的 JavaScript