POJ 1258 最小生成树
http://poj.org/problem?id=1258
把N个村庄连在一起,求最小花费,纯最短路 借这个题整理一下最短路的两种方法 prim kruscal
prim代码(16MS):
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define inf 100002 using namespace std; int map[102][102],dis[102]; bool vs[102]; int N,SUM; void prim(int x) { int i,k,mark,MIN; memset(vs,0,sizeof(vs)); for(i=1;i<=N;i++) dis[i]=map[x][i]; SUM=0; vs[1]=1; for(k=1;k<N;k++) { MIN=inf; for(i=1;i<=N;i++) if(!vs[i]&&MIN>dis[i]) { MIN=dis[i]; mark=i; } SUM+=dis[mark]; vs[mark]=1; for(i=1;i<=N;i++) if(!vs[i]&&dis[i]>map[mark][i]) dis[i]=map[mark][i]; } return ; } int main() { while(~scanf("%d",&N)) { int i,j; for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&map[i][j]); prim(1); printf("%d\n",SUM); } return 0; }
kruscal代码(32MS):
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #define inf 100002 using namespace std; int root[10005],height[10005]; int N,SUM,s_edge; struct Edge { int u,v,w; }edge[10005]; int cmp(const void *a,const void *b) { return (*(Edge*)a).w>(*(Edge*)b).w?1:-1; } void addedge(int uu,int vv,int ww) { edge[s_edge].u=uu; edge[s_edge].v=vv; edge[s_edge].w=ww; s_edge++; } int find(int x) { if(x!=root[x]) root[x]=find(root[x]); return root[x]; } void kruscal() { SUM=0; int i,a,b,Sum=0; for(i=0;i<N;i++) { root[i]=i; height[i]=0; } for(Sum=0;Sum<s_edge;Sum++) { a=find(edge[Sum].u); b=find(edge[Sum].v); if(a!=b) { SUM+=edge[Sum].w; root[a]=b; } } return ; } int main() { int i,j,len; while(~scanf("%d",&N)) { s_edge=0; for(i=0;i<N;i++) for(j=0;j<N;j++) { scanf("%d",&len); if(j>i) addedge(i,j,len); } qsort(edge,s_edge,sizeof(edge[0]),cmp); kruscal(); printf("%d\n",SUM); } return 0; }