最小生成树的总结
2010-10-23 17:00
330 查看
最小生成树有两种算法:kruskal算法与prim算法
http://acm.hdu.edu.cn/showproblem.php?pid=1102
kruskal算法如下:
prim算法如下:
两种算法在OJ上的比较:
http://acm.hdu.edu.cn/showproblem.php?pid=1102
kruskal算法如下:
//就是求最小生成树,对于已有的道路只要赋予0即可 //使用kruskal算法,对于每次都去找权值最小的边,如果不会形成环,则加入最小生成树的边 //对于判断是否形成环,则我们可以使用并查集的思想 #include<iostream> #include<algorithm> using namespace std; #define M 101 #define inf 1<<20 struct node { int s, e, w; }edge[M*M]; int mat[M][M]; int father[M], rank[M];//father[i]表示节点i的祖先编号,rank[i]表示i这个集合的个数 int n;// void make_set()//初始化father[],rank[] { int i; for(i=1; i<=n; i++) { father[i] = i; rank[i] = 1; } } int find_set(int x)//寻找x的祖先节点 { if(x != father[x]) return father[x] = find_set(father[x]); else return x; } bool union_set(int x, int y)//合并x和y的集合 { x = find_set(x); y = find_set(y); if(x == y) return false; if(rank[x] < rank[y]) { father[x] = y; rank[y] += rank[x]; } else { father[y] = x; rank[x] += rank[y]; } return true; } bool cmp(const node &a, const node &b)//按权值进行排序 { return a.w < b.w; } int main() { // freopen("in.txt","r",stdin); int i, q, a, b, j; int ans; while(scanf("%d",&n) != EOF) { make_set(); int m = 0; for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { scanf("%d", &mat[i][j]); } } scanf("%d",&q); for(i=0; i<q; i++) { scanf("%d %d", &a, &b); mat[a][b] = 0; } for(i=1; i<=n; i++) { for(j=i+1; j<=n; j++) { // if(i == j) // continue; edge[m].s = i; edge[m].e = j; edge[m++].w = mat[i][j]; // printf("%d %d %d/n", i, j, mat[i][j]); } } ans = 0; sort(edge, edge+m, cmp); for(i=0; i<m; i++) { if(union_set(edge[i].s, edge[i].e))//判断是否有环 ans += edge[i].w; } printf("%d/n",ans); } return 0; }
prim算法如下:
//prim算法 // #include<stdio.h> #include<string.h> #define M 101 #define inf 1<<20 int mat[M][M], lowcost[M]; bool v[M]; int n; void prim() { int i, j, k, min; int ans = 0; for(i=1; i<=n; i++) { lowcost[i] = mat[1][i]; // printf("%d/n", lowcost[i]); v[i] = false; } v[1] = true; for(i=2; i<=n; i++) { min = inf; for(j=1; j<=n; j++)//寻找最小边 { if(!v[j] && min > lowcost[j]) { min = lowcost[j]; k = j; } } v[k] = true; // printf("%d %d/n", min, k); ans += min; for(j=1; j<=n; j++)//更新最小边 { if((mat[k][j] < lowcost[j]) && (!v[j])) lowcost[j] = mat[k][j]; } } printf("%d/n", ans); } int main() { // freopen("in.txt","r",stdin); int i, j, q, a, b; while(scanf("%d",&n) != EOF) { for(i=1; i<=n; i++) for(j=1; j<=n; j++) scanf("%d",&mat[i][j]); scanf("%d",&q); for(i=0; i<q; i++) { scanf("%d %d", &a, &b); mat[a][b] = mat[b][a] = 0; } prim(); } return 0; }
两种算法在OJ上的比较:
相关文章推荐
- 最小生成树算法总结
- 最小生成树的两种算法总结(克鲁斯塔尔,prim)
- 最小生成树总结
- kuangbin专题六最小生成树总结
- 图的最小生成树prim算法总结
- 最小生成树、次生成树、最短路劲、0-背包总结
- 最小生成树基础总结(Prim Kruskal)
- 最小生成树总结
- 曼哈顿距离最小生成树与莫队算法(总结)
- Qrcode生成二维码的参数总结 及最小尺寸的测试
- Prim 最小生成树总结
- 关于最小生成树中的kruskal算法中判断两个点是否在同一个连通分量的方法总结
- 最小生成树问题学习总结
- 求最小生成树和最短路径的总结
- Qrcode生成二维码的参数总结 及最小尺寸的测试
- 最小生成树总结
- Kruskal 最小生成树的总结
- 2017.9.1 最小生成树 失败总结
- 最小生成树——prim算法(个人总结)
- 最小生成树总结