51nod 1212 模板

来源:互联网 发布:淘宝劳模代购 编辑:程序博客网 时间:2024/05/18 21:47

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
输出最小生成树的所有边的权值之和。
Sample 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
Sample Output
37

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int maxn=1000+10;//最大点数const int maxm=50000+10;//最大边数int F[maxn];//并查集 int n,m; struct Edge{    int u,v,w;}edge[maxm];//存储边的信息,包括起点。终点。权值 int tol;//边数,加边前赋值为0 void addedge(int u,int v,int w) {    edge[tol].u=u;    edge[tol].v=v;    edge[tol++].w=w;}//边权从小到大 bool cmp(Edge a,Edge b) {    return a.w<b.w;}int find(int x) {    if(F[x]==-1) return x;    else return F[x]=find(F[x]);}//传入点数,返回最小生成树的权值,如果不连通返回-1 int Kruskal(int n) {    memset(F,-1,sizeof(F));    sort(edge,edge+tol,cmp);    int cnt=0;//计算加入的边数     int ans=0;    for(int i=0;i<tol;i++) {        int u=edge[i].u;        int v=edge[i].v;        int w=edge[i].w;        int t1=find(u);        int t2=find(v);        if(t1!=t2) {            ans+=w;            F[t1]=t2;            cnt++;        }        if(cnt==n-1) break;    }    if(cnt<n-1) return -1;//不连通     else return ans;}int main() {//  freopen("input.txt","r",stdin);    while(scanf("%d%d",&n,&m)!=EOF) {        tol=0;        int a,b,c;        for(int i=0;i<m;i++) {            scanf("%d%d%d",&a,&b,&c);            addedge(a,b,c);        }        printf("%d\n",Kruskal(n));    }    return 0;}