第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
9 14 1 2 4 2 3 8 3 4 7 4 5 9 5 6 10 6 7 2 7 8 1 8 9 7 2 8 11 3 9 2 7 9 6 3 6 4 4 6 14 1 8 8
37
#include<stdio.h>
#include<string.h>
int a[1005][1005],dis[1005],vis[1005]={0}; //a用来存放:某点-某点的权值。
int indx,ans=0; //dis存放:当前到达的点到所有点的权值。
int n,m; //vis标记走过的点。
void prim()
{
int i,j,temp=9999999,ans=0;
for(i=0;i<=n;i++)
dis[i]=a[1][i];
vis[1]=1;
for(i=2;i<=n;i++)
{
temp=999999; //存储最小权值边。
indx=0;
for(j=0;j<=n;j++)
if(dis[j]<temp && !vis[j]) //找出当前点到其他点 最小且没有走过的边的权值。
{
temp=dis[j];
indx=j; //indx表示走到的点。
}
vis[indx]=1;
ans+=temp; //将最小边逐个相加。
for(j=0;j<=n;j++)
if(!vis[j] && a[indx][j]<dis[j]) //走到下一个点后更新权值。
dis[j]=a[indx][j]; //注意:如果当前点比上一点到同一个点的权值大则不更新
//例如 1-3权值为3 从1走到2后 2-3的权值为5 则不更新。
}
printf("%d\n",ans);
}
int main()
{
int i,j,x,y,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
a[i][j]=999999;
memset(vis,0,sizeof(vis));
for(i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&v);
if(a[x][y]>v)
a[x][y]=a[y][x]=v;
}
prim();
}
return 0;
}