初学Kruskal——Prime
来源:互联网 发布:阿里云 dns服务器地址 编辑:程序博客网 时间:2024/05/24 07:38
刚学了最小生成树,,,,做了这个题:NYOJ 布线问题 http://acm.nyist.net/JudgeOnline/problem.php?pid=38
布线问题
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
- 南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
1、把所有的楼都供上电。
2、所用电线花费最少- 输入
- 第一行是一个整数n表示有n组测试数据。(n<5)
每组测试数据的第一行是两个整数v,e.
v表示学校里楼的总个数(v<=500)
随后的e行里,每行有三个整数a,b,c表示a与b之间如果建铺设线路花费为c(c<=100)。(哪两栋楼间如果没有指明花费,则表示这两栋楼直接连通需要费用太大或者不可能连通)
随后的1行里,有v个整数,其中第i个数表示从第i号楼接线到外界供电设施所需要的费用。( 0<e<v*(v-1)/2 )
(楼的编号从1开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。 - 输出
- 每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。
- 样例输入
14 61 2 102 3 103 1 101 4 12 4 13 4 11 3 5 6
- 样例输出
4
找最小生成树有Kruskal和Prime两种算法。
个人觉得Kruskal和并查集的写法很像,,,区别只是并查集在查找过程中需要不断更新,,,而Kruskal需要在查找结束后重新定义父亲节点时加上这个点的权值。。。
确实,在写Kruskal的时候一定要注意题目中边的数目(边数 <= n * (n - 1) / 2),不要把数组开小了。(Kruskal与边数有关)
而Prime与点数有关。。。
Kruskal AC代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#define PI 3.1415926using namespace std;typedef long long LL;int Q[125000];struct Node{ int m,n,d; bool operator < (Node a)const { return d < a.d; }} E[125000];int main(){// freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t --) { int n,m; scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) Q[i] = i; int a,b,w; for(int i = 0; i < m; i++) { scanf("%d%d%d",&a,&b,&w); E[i].m = a; E[i].n = b; E[i].d = w; } sort(E,E + m); int Mx = 10000000; for(int i = 1; i <= n; i++) { int x; scanf("%d",&x); Mx = min(Mx,x); } int num = 0,ans = 0; for(int i = 0; i < m && num < n - 1; i ++) { int j,k; for(j = E[i].m; Q[j] != j; j = Q[j]) Q[j] = Q[Q[j]]; for(k = E[i].n; Q[k] != k; k = Q[k]) Q[k] = Q[Q[k]]; if(j != k) { Q[k] = j; ans += E[i].d; num ++; } } printf("%d\n",ans + Mx); } return 0;}另外一种写法:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#define PI 3.1415926using namespace std;typedef long long LL;int ans ,num;int Q[125000];struct Node{ int m,n,d; bool operator < (Node a)const { return d < a.d; }} E[125000];int Find(int x){ int r = x; while(r != Q[r])r = Q[r]; /***************** 并查集还要加上: int j = x; while(Q[j] != r) { j = Q[j]; Q[j] = r; } ******************/ return r;}void MA(int x,int y,int w){ x = Find(x); y = Find(y); if(x != y) { Q[x] = y; ans += w; // 并查集没 num ++; // 有这些操作 }}int main(){// freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t --) { ans = 0; int n,m; scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) Q[i] = i; int a,b,w; for(int i = 0; i < m; i++) { scanf("%d%d%d",&a,&b,&w); E[i].m = a; E[i].n = b; E[i].d = w; } sort(E,E + m); int Mx = 10000000; for(int i = 1; i <= n; i++) { int x; scanf("%d",&x); Mx = min(Mx,x); } num = 0; for(int i = 0; i < m && num < n - 1; i ++) { MA(E[i].m,E[i].n,E[i].d); } printf("%d\n",ans + Mx); } return 0;}
Prime AC代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#define PI 3.1415926#define INF 0x3f3f3f3fusing namespace std;typedef long long LL;int vis[550],low[550];int Map[550][550];int n,m;int Prim(){ memset(vis,0,sizeof(vis)); vis[1] = 1; int sum = 0; for(int i = 1; i <= n; i++) { low[i] = Map[1][i]; } int k; for(int i = 2; i <= n; i++) { int tem = INF; for(int j = 1; j <= n; j++) { if(!vis[j] && tem > low[j]) { tem = low[j]; k = j; } } if(tem == INF)break; vis[k] = 1; sum += tem; for(int j = 1; j <= n; j++) { if(!vis[j] && low[j] > Map[k][j]) low[j] = Map[k][j]; } } return sum ;}int main(){// freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t --) { scanf("%d%d",&n,&m); int a,b,w; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) Map[j][i] = INF; } for(int i = 1; i <= n; i++) Map[i][i] = 0; for(int i = 0; i < m; i++) { scanf("%d%d%d",&a,&b,&w); if(w < Map[a][b]) // 千万别忘了这个,因为这个还wa了一次 { Map[a][b] = w; Map[b][a] = w; } } int Mx = INF; for(int i = 1; i <= n; i++) { int x; scanf("%d",&x); Mx = min(Mx,x); } int ans = Mx; ans += Prim(); printf("%d\n",ans); } return 0;}
0 0
- 初学Kruskal——Prime
- Prime,Kruskal,Dijkstra算法
- Prime,Kruskal,Dijkstra算法
- HDOJ 2682 Tree 【prime】【kruskal】
- Prime算法和Kruskal算法
- 生成树模板(Prime + Kruskal)
- hdu1863-畅通工程(Prime & Kruskal)
- MST——Kruskal
- Kruskal——模板
- poj 1258Agri-Net(prime,Kruskal )
- poj2485-最小生成树(prime+kruskal)
- Eddy's picture + prime算法 + kruskal算法
- hdu1233 Prime算法和 Kruskal算法
- 最小生成树---Kruskal/Prime算法
- 最小生成树(Prime/kruskal)
- [次小生成树] Prime Kruskal
- 最小生成树算法[Prime/(Kruskal)]
- poj 1287 (最小生成树 Prime + kruskal )
- CSS选择器的阅读方式
- 黑马程序员——OC语言基础---封装的概念及原理
- PagerSlidingTabStrip+ViewPager
- java className失败的原因
- Ubuntu下如何找回 /var/log/messages
- 初学Kruskal——Prime
- iOS 使用MJRefresh刷新
- java基础
- springmvc 集成apache cxf 开发webservice 示例
- Servlet
- 【计蒜客】难题题库 003 判断质数
- 离队后的杂念
- OC语言-NSMutableArray为什么要用strong来修饰
- 212 Word Search II [Leetcode]