Algorithm --> 并查集
2015-08-02 21:43
429 查看
[b]并查集[/b]
主要解决图的连通性问题,比如:
1、随意给你两个点,让你判断它们是否连通;
2、问你整幅图一共有几个连通分支;
初始化:
代码(非递归):
递归法:
求连接非连通图,需要几条边:
输入:
主要解决图的连通性问题,比如:
1、随意给你两个点,让你判断它们是否连通;
2、问你整幅图一共有几个连通分支;
初始化:
void init(int size) { for(int i = 0; i < size; i++) pre[i] = i; }
代码(非递归):
int find(int x) //查找根节点 { int r = x; while(pre[r] != r) r = pre[r]; //返回根节点 r int i = x , j ; while(i != r) //路径压缩 { j = pre[i]; // 在改变上级之前用临时变量 j 记录下他的值 pre[i] = r ; //把上级改为根节点 i = j; } return r ; } void join(int x,int y) //判断x y是否连通 { int fx = find(x); int fy = find(y); if(fx != fy) //如果已经连通,就不用管了; 如果不连通,就把它们所在的连通分支合并起 pre[fx]=fy; }
递归法:
int find(int x) { if (x != pre[x]) pre[x] = find(pre[x]); return pre[x]; }
求连接非连通图,需要几条边:
#include <iostream> using namespace std; int N, E, Answer; int pre[1000]; int find(int x) { int r = x; while(pre[r] != r) //找父亲 r = pre[r]; int i = x, j; while(i != r) //路径压缩 { j = pre[i]; pre[i] = r; i = j; } return r; } int find2(int x) //递归 { if (x != pre[x]) pre[x] = find(pre[x]); return pre[x]; } int main() { int x, y, p1, p2; while(cin >> N, N) //顶点数 { Answer = N-1; //N个顶点需要N-1条边 for(int i = 1; i <= N; i++) pre[i] = i; //每个顶点的父亲都是自己 cin >> E; //边数 while(E--) { cin >> p1 >> p2; x = find(p1); y = find(p2); if(x != y) //如果是不连通的,把这两个分支连起来, 分支的总数就减少了1,还需建的路也就减了1 { pre[y]=x; Answer--; } //如果两点已经连通了,那么这条路只是在图上增加了一个环 //对连通性没有任何影响,无视掉 } cout << Answer << endl; //最后输出还要修的路条数 } }
输入:
4 2 1 2 3 4 7 5 1 2 2 3 3 4 1 5 6 7
相关文章推荐
- Category,protocol,Block总结对比
- 利用PPT绘制京东阅读Logo
- How to write a good tech blog
- Farey Polygon
- Django学习(一)
- Algorithm --> KMP算法
- Dragon Balls HDU杭电3635 【并查集,递归的方法找根节点】
- django notes 三:Template 的查找
- Good Luck in CET-4 Everybody! HDOJ(巴什博弈)
- hdoj 3635 Dragon Balls【并查集】
- codeforces 559A A. Gerald's Hexagon(几何题)
- Google黑客常用的入侵语法
- HDU 3635 Dragon Balls 带权并查集
- django notes 二:URL dispatcher
- django notes 一:开篇
- Google Play Store启用AdWords搜索广告
- poj 2762 Going from u to v or from v to u? 【判断图是否为弱连通】 【tarjan求SCC + 缩点 + 拓扑排序】
- HackerRank - "Lego Blocks"
- Django新手需要注意的10个要点
- django环境搭建