51nod 1212 无向图最小生成树
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000) 第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
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
Output示例
37
最小生成树的解法一般是有Prime生成树和Kruskal生成树来实现:
比较简单的最小生成树可以直接套用模板
#include<stdio.h>
#include<string.h>
#define inf 0x3f3f3f3f
int G[1001][1001];
int vis[1001],lowc[1001];
void init(int x,int y,int v)
{
G[x][y]=v;
G[y][x]=v;
return;
}
int prim(int G[][1001],int n){
int i,j,p,minc,res=0;
memset(vis,0,sizeof(vis));//全部初值为0表示没有访问过;
vis[1]=1;
for(i=2;i<=n;i++)
lowc[i]=G[1][i];
for(i=2;i<=n;i++){
minc=inf;
p=-1;
for(j=1;j<=n;j++){
if(vis[j]==0&&lowc[j]<minc)
{minc=lowc[j];p=j;}
}
if(inf==minc) return -1;//原图不连通
res+=minc;
vis[p]=1;
for(j=1;j<=n;j++){//更新lowc[]
if(vis[j]==0&&lowc[j]>G[p][j])
lowc[j]=G[p][j];
}
}
return res;
}
int main(){
int n,m;
int x,y,w;
while(~scanf("%d %d",&n,&m)){
memset(G,inf,sizeof(G));
while(m--){
scanf("%d%d%d",&x,&y,&w);
init(x,y,w);
}
printf("%d\n",prim(G,n));
}
}