并查集和prime和kruskal
来源:互联网 发布:软件公寓如何申请 编辑:程序博客网 时间:2024/05/04 16:54
现在有10个强盗,下面9行两个人是一个团伙
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4
求有几个团伙
//并查集#include<stdio.h>int f[1000]={0},n,m,k,sum=0;//第一步,这里是初始,非常的重要,数组里面存自己的下标就好了(自己是自己的老大)void init(){ int i; for(i=1;i<=n;i++) f[i]=i; return ;}//这是找爹的递规函数,不停的去找爹,直到找到祖宗为止,其实就是去犯罪团伙的最高领导,“擒贼先擒王”原则int getf(int v){ if(f[v]==v) return v; else { f[v]=getf(f[v]);//找爹循环,哈哈哈 return f[v];//返回找到的值 }}//这里是合并两子集合的函数void merge(int v,int u){ int t1,t2; t1=getf(v);//注意这里是getf(v),不是getf(f[v]),要不然就隔过了一层找爹循环 t2=getf(u); if(t1!=t2)//判断两节点是否同一祖先 { //靠左原则 f[t2]=t1; } return ;}int main(){ int i,x,y; scanf("%d%d",&n,&m); //初始化为第一步 init(); //第二步合并团伙,题型可能有改动,但是万变不离其宗 for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); merge(x,y); } //第三步扫描有多少团伙 for(i=1;i<=n;i++) { if(f[i]==i) sum++; } printf("%d\n",sum); getchar();getchar(); return 0;}//答案为3
有好几个孤岛,要把它们连起来,且花费最少
数据
6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
找到n-1条边,使得n个岛连通且路程最短
//最小生成树kruskal算法//核心:排序,选用n-1条边#include <stdio.h>#include<iostream>#include<algorithm>using namespace std;struct edge{ int u,v,w;}e[10];int cmp(edge x,edge y){ return x.w<y.w;}int n,m;int f[7]={0},sum=0,cou=0;int geft(int v){ if(f[v]==v) return v; else { f[v]=geft(f[v]); return f[v]; }}int merge(int v,int u){ int t1,t2; t1=geft(v); t2=geft(u); if(t1!=t2) { f[t2]=t1; return 1; } return 0;}int main(){ int i; scanf("%d%d",&n,&m); //第一步,找到一个结构体储存边的位置 for(i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); //第二步,按边的大小排序 sort(e+1,e+m+1,cmp); //第三步,初始化 for(i=1;i<=n;i++) f[i]=i; //第四步,kruskal算法的核心 for(i=1;i<=m;i++) { //先判断两点是否连通 if(merge(e[i].u,e[i].v))//如果不连通,这条边 { cou++; sum=sum+e[i].w; } if(cou==n-1)//直到n-1条边后退出循环 break; } printf("%d",sum);//打印结果 getchar();getchar(); return 0;}
这个算法也采用上面那个例子;
这个算法的思想是:
//prime算法#include<stdio.h>int main(){ int n,m,i,j,k,minn,t1,t2,t3; int e[7][7],dis[7],book[7]= {0};//这里对book数组进行初始化 int inf=999999999;//用inf(infinity的缩写)储存一我们认为的正无穷值 int cou=0,sum=0;//cou用来生成树中定点的,sum用来路径之和; //读入n和m,n表示定点个数,m表示边的条数 scanf("%d%d",&n,&m); //第一步,初始化 for(i=1; i<=n; i++) for(j=1; j<=n; j++) if(i==j) e[i][j]=0; else e[i][j]=inf; //第二步,读入边 for(i=1; i<=m; i++) { scanf("%d%d%d",&t1,&t2,&t3); e[t1][t2]=t3; e[t2][t1]=t3; } //第三步,初始化dis数组, for(i=1; i<=n; i++) dis[i]=e[1][i]; //第四步,将一号点加入树 book[1]=1; //第五步,加边 cou++; //第六步,prime算法核心 while(cou<n)//找到n-1条边 { minn=inf; for(i=1; i<=n; i++) { if(book[i]==0&&dis[i]<minn)//找下一个能走的点 { minn=dis[i]; j=i; } } book[j]=1; cou++; sum=sum+dis[j]; for(k=1; k<=n; k++) { if(book[k]==0&&dis[k]>e[j][k])//找到通向这个点的最短路 dis[k]=e[j][k]; } //扫描当前定点j所有边,在以j为中间点,更新生成树到每一个非数定点的距离 for(k=1;k<=n;k++) { printf("%d ",dis[k]); } printf("\n"); } printf("%d",sum);//打印结果 getchar(); getchar(); return 0;}
1 0
- 并查集和prime和kruskal
- HDU1863并查集和kruskal算法
- Kruskal算法并查集和最小堆实现
- kruskal+ 并查集
- Kruskal+并查集
- Kruskal + 并查集
- Prime算法和Kruskal算法
- HDU--1233 -- 还是畅通工程 [kruskal算法] [prime算法] [并查集]
- Kruskal算法 (并查集)
- poj3522 并查集+kruskal
- hdu1233 并查集+Kruskal
- hdu3367并查集+Kruskal
- kruskal+并查集学习
- hdu1301 kruskal+并查集
- Dijkstra 并查集 Kruskal
- 使用并查集UnionFind和优先队列PriorityQueue实现Kruskal算法
- 最小生成树总结(prim、并查集和kruskal) C++实现
- 并查集——最小连接路径和Kruskal(hdu1301)
- 修改War包文件
- 六大排序算法之 PHP和C++实现
- centos6.5 redis sentinel主从模式配置
- 二叉树
- UGUI播放UI特效以及解决特效与UI的层级问题
- 并查集和prime和kruskal
- ASP .Net MVC使用Knockout.js
- Json数据处理:使用GSON处理数据的方法
- Codeforces Round #204 (Div. 2) B
- Java集合类之Collection接口
- Unity3D Asset文件导出3DMax 可编辑格式
- 在ssh中避免老掉线以及私钥公钥的问题
- 八皇后c++版本
- 使用ArrayAdapter结合LisiView自定义一个列表