链接 : http://acm.hdu.edu.cn/showproblem.php?pid=1102
最小生成树,Prim和Kruskal,与1233相比变一个输入方式
正因如此,Kruskal算法想了半天也没想出来什么好的记录边的方法,最后直接先用数组保存,再把数组的数据转换成边的形式
不是什么聪明的办法,最后也算AC了
Prim:
#include <cstdio> #include <climits> #include <cstring> using namespace std; int map[110][110]; bool used[110]; int Prim(int n) { int sum=0,T=n-1; while(T--) { int mini=INT_MAX,t; for(int i=2; i<=n; i++) if(!used[i] && mini>map[1][i]) { mini=map[1][i]; t=i; } sum+=mini; used[t]=1; for(int i=2; i<=n; i++) if(!used[i] && map[t][i]<map[1][i]) map[1][i]=map[t][i]; } return sum; } int main() { int n,q; while(~scanf("%d",&n)) { for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%d",&map[i][j]); scanf("%d",&q); while(q--) { int x,y; scanf("%d %d",&x,&y); map[x][y]=map[y][x]=0; } memset(used,0,sizeof(used)); printf("%d\n",Prim(n)); } return 0; }
#include <cstdio> #include <algorithm> using namespace std; struct node { int b,e,dis; }s[5001]; int father[101],map[101][101]; bool cmp(node a,node b) { return a.dis<b.dis; } int find(int n) { return n==father[n] ? n : father[n]=find(father[n]); } int Kruskal(int n) { for(int i=0;i<101;i++) father[i]=i; sort(s,s+n,cmp); int sum=0; for(int i=0;i<n;i++) { int x=find(s[i].b); int y=find(s[i].e); if(x!=y) { father[y]=x; sum+=s[i].dis; } } return sum; } int main() { int n,q,x,y,k; while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&map[i][j]); scanf("%d",&q); while(q--) { scanf("%d %d",&x,&y); map[x][y]=map[y][x]=0; } k=0; for(int i=1;i<=n;i++) //转换成边 for(int j=i+1;j<=n;j++) { s[k].b=i; s[k].e=j; s[k++].dis=map[i][j]; } printf("%d\n",Kruskal(k)); } return 0; }