Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 39499 | Accepted: 16017 |
Description
Input
Output
Sample Input
4 0 4 9 21 4 0 8 17 9 8 0 16 21 17 16 0
Sample Output
28
Source
#include <cstdio> #include <cstring> const int Max=0x3f3f3f3f; const int maxn=100+10; int map[maxn][maxn],low[maxn],visit[maxn]; int n; int prim() { int pos,i,j,min,sum=0; memset(visit,0,sizeof(visit));//初始化visit数组 visit[1]=1;//从第一个点开始 pos=1;//标记和记录这个点 for(i=1;i<=n;i++) low[i]=map[pos][i];//用low数组记录权值 for(i=1;i<n;i++) //第一个点已经进行了,还需要进行n-1次; { min=Max;//把min赋初值 for(j=1;j<=n;j++) { if(visit[j]==0&&low[j]!=0&&low[j]<min)//比较权值的大小 { min=low[j]; pos=j;//记录权值最小的点,下一次从这个点开始 } } sum+=min;//记录权值的和 visit[pos]=1;//标记访问 for(j=1;j<=n;j++)//访问下一个点 { if(visit[j]==0&&low[j]>map[pos][j]) low[j]=map[pos][j]; } } return sum; } int main() { int sum,i,j; while(scanf("%d",&n)!=EOF) { sum=0; memset(map,Max,sizeof(map)); for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&map[i][j]); sum=prim(); printf("%d\n",sum); } return 0; }
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct node { int u,v,cost; }; node map[100002]; int father[102]; int n,k; bool cmp(node a,node b) { return a.cost<b.cost;//按照升序排序 } void Init()//对并查集初始化 { for(int i=1;i<=n;i++) father[i]=i; } int find_set(int x)//带状态压缩的查找 { if(father[x]==x) return x; else return father[x]=find_set(father[x]); } bool union_set(int x,int y)//两个集合之间的合并 { x=find_set(x); y=find_set(y); if(x!=y) { father[y]=x; return true; } else { return false; } } int kruskal() { int i,mst_edge=0,sum=0; Init();//初始化 sort(map,map+k,cmp);//排序 for(i=1;i<=k;i++) { if(union_set(map[i].u,map[i].v))//判断是否形成回路 { sum+=map[i].cost; mst_edge++; } } if(mst_edge==n-1)//根据生成树的概念,最小生成树的边数应等于顶点数减一 return sum; return mst_edge; } int main() { int i,j,w; while(scanf("%d",&n)!=EOF) { k=0; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { scanf("%d",&w); if(i!=j) { map[k].u=i; map[k].v=j; map[k++].cost=w; } } printf("%d\n",kruskal()); } return 0; }