poj1182 并查集经典题 Weighted Union-Find Sets
来源:互联网 发布:东京 泡泡 上门 知乎 编辑:程序博客网 时间:2024/06/05 11:56
没注意只有一个case 不知道怎么就错了 - -
带权并查集的"权"表示该节点与爸爸的关系
这题的关系有
0.儿子与爸爸是同类
1.儿子被爸爸是吃 - -
2.儿子吃爸爸 = =
为什么权要这样设?待会解释
所以每个节点多一个变量记录权
那两个不是父子关系的点之间的关系怎么表示呢?
为了解决这个问题 我们把每条指向父亲的边都看作向量!
eg:假如现在UFS是这样的
(节点,权) (1,0)->(2,1)->(3,2)->(4,0)
那么可知:
1与2的关系是同类;
2被3吃;
3吃4;
4与4(自己)是同类
2与1是什么关系呢? 因为1->2的长度(权)是0 那么2->1的长度不也是0吗? 就是说2与1也是同类
3与2是什么关系? 同理 |3->2|=-1 怎么办? 权只有 0,1,2 啊 ! 所以-1+3=2 即权为2 就是3吃吃2了
如果 a吃b b吃c c吃d 呢? 是多少怎么处理?
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 50010;struct node{ int f,r;}ani[maxn];inline int mod(int a){ a%=3; return a<0?a+3:a;}int ff(int x){ int &f=ani[x].f,t=f; f=(f==x?x:ff(f)); ani[x].r=mod(ani[x].r+ani[t].r); ///BE CAREFUL! Father is change!! return f;}int main(){ //freopen("a.in","r",stdin); int m,n; scanf("%d%d",&m,&n); int ans=0; for(int i=1;i<=m;i++) { ani[i].f=i; ani[i].r=0; } for(int i=0;i<n;i++) { int o,a,b; scanf("%d%d%d",&o,&a,&b); o--; int ra=ff(a),rb=ff(b); ///a to be father of b if(a>m||b>m) ans++; else if(o&&a==b) ans++; else { if(ra!=rb) { ani[rb].f=ra; ani[rb].r=mod(o+ani[a].r-ani[b].r); } else if(mod(ani[b].r-ani[a].r)!=o) ans++; } } printf("%d\n",ans); return 0;}
0 0
- poj1182 并查集经典题 Weighted Union-Find Sets
- 经典算法系-并查集(Union-Find Sets)
- 并查集 (Union-Find Sets)
- 并查集 (Union-Find Sets)
- 并查集 (Union-Find Sets)
- 并查集Union-Find Sets
- 并查集-(union-find sets)
- 并查集 (Union-Find Sets)
- 并查集 (Union-Find Sets)
- 并查集Union-Find Sets
- 并查集(Union-find Sets)
- 并查集(union-find sets)
- 常用类之四---并查集(Union-Find Sets)
- 并查集 (Union-Find Sets)及其应用
- 并查集 (Union-Find Sets)及其应用
- 并查集 (Union-Find Sets)及其应用
- 并查集 (Union-Find Sets)及其应用
- 并查集 (Union-Find Sets)及其应用
- 【索引】Backtracking - Hard
- VC double CString 相互转换 摘录
- 关于js中的传递方式
- Java语言与应用框架——Struts官方文档
- Python(2.7.x)多线程的简单示例
- poj1182 并查集经典题 Weighted Union-Find Sets
- jquery中的冒泡事件
- AbstractAccountAuthenticator简介
- hdu 1880 二分+快排 水题
- hdu4856(bfs + 状态压缩)
- 1-100的素数
- ACM中的java使用
- UVa10129 Play on Words
- FTP文件传输协议