POJ1861-Kruskal算法
来源:互联网 发布:化妆品成分分析软件 编辑:程序博客网 时间:2024/05/16 17:57
之前也写过Kruskal算法,到今天才发现 原来以前的写错了。(也不能说完全错,只是效率好低)。
以前忽视的地方主要有两点,一是Kruskal算法,一般先对边从小到大排好序,然后从小到大区边。
这样的话,排完序以后就只要一个循环就可以走完。
二是 并查集的路径压缩,我以前对并查集合并是遍历所有的结点对两个集合合并,
而正确的做法应该是这样
- int flindfather(int a)
- {
- if(a==father[a])
- return a;
- else
- return findfather(father[a]);
- }
而其实我们还可以进行路径压缩,这才是并查集的核心所在
只要将上面的代码改写一行,就能起到很好的效果
- int flindfather(int a)
- {
- if(a==father[a])
- return a;
- else
- return father[a]=findfather(father[a]);
- }
下面是1861的代码
- #include<iostream>
- #include <algorithm>
- using namespace std;
- #define MAXSIZE 30010
- #define INF 9000100
- int n,m;
- int father[MAXSIZE];//并查集
- int head[MAXSIZE];
- int next[MAXSIZE];
- int e;
- struct node{
- int u;
- int v;
- int w;
- };
- node edge[MAXSIZE];
- node medge[MAXSIZE];
- int num;
- int ansmax,anstot;
- //判断两点是否属于同一集合
- int judge(int a,int b)
- {
- if(father[a]==father[b])//同一集合
- return 1;
- return 0;
- }
- bool cmp(node &a,node &b)
- {
- return a.w<b.w;
- }
- int findset(int a)
- {
- if(a==father[a])
- return a;
- else
- return father[a]=findset(father[a]);
- }
- void kruskal()
- {
- sort(edge,edge+e,cmp);
- int i,j;
- num=0;
- ansmax=anstot=0;
- for(i=0;i<2*m;i++)
- father[i]=i; //初始时 每个元素属于不同的集合
- for(i=0;i<2*m;i++)
- {
- if(findset(edge[i].u)!=findset(edge[i].v))//如果不属于同一集合
- {
- ansmax=ansmax>edge[i].w?ansmax:edge[i].w;
- medge[num++]=edge[i];
- int tu=edge[i].u;//将所有与v一个集合的全部并入u的集合
- int tv=edge[i].v;
- father[findset(tv)]=findset(tu);
- }
- }
- }
- void addnode(int u,int v,int w)
- {
- edge[e].u=u;
- edge[e].v=v;
- edge[e].w=w;
- next[e]=head[u];
- head[u]=e++;
- }
- int main()
- {
- //freopen("in.txt","r",stdin);
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- e=0;
- int t1=m;
- while(t1--)
- {
- int a,b,c;
- scanf("%d%d%d",&a,&b,&c);
- addnode(a,b,c);
- addnode(b,a,c);
- }
- kruskal();
- printf("%d\n",ansmax);
- printf("%d\n",num);
- for(int i=0;i<num;i++)
- printf("%d %d\n",medge[i].u,medge[i].v);
- }
- }
0 0
- POJ1861-Kruskal算法
- network(poj1861)标准kruskal算法
- poj1861 kruskal
- POJ1861 kruskal.
- poj1861最小生成树(并查集)-kruskal算法
- Kruskal POJ1287 POJ1861 POJ2349
- POJ1861-Network(Kruskal)
- POJ1861 Network [kruskal + 并查集]
- poj1861 最小生成树 prim & kruskal
- poj1861 Network(kruskal求最小生成树)
- poj1861
- poj1861
- poj1861
- poj1861
- poj1861
- POJ1861
- POJ1861
- Kruskal算法
- hdu1408盐水的故事
- UITableView使用
- 2-路归并排序(C代码)及其时间复杂度的具体分析
- cocos2dx 动画常见的22种特效
- 今天开始,有的还是做个记录,记性越来越不好了
- POJ1861-Kruskal算法
- 【Android】Apk安装方式
- cocos2dx 常见的49中动作详解
- hdu 12881 Jumble Match
- hadoop 框架中知识的一点总结
- 【最大流】HDU 4292 Food
- Codeforces Round #260 (Div. 2) A. Laptops
- fzu-1753 Another Easy Problem-快速求N!中有多少个p
- Win32汇编之创建窗口