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));
    }
}



posted @ 2017-11-04 19:46  Bryce1010  阅读(103)  评论(0编辑  收藏  举报