Kruskal 算法模板题

来源:互联网 发布:淘宝企业店铺过户流程 编辑:程序博客网 时间:2024/06/03 11:55

描述

随着小Hi拥有城市数目的增加,在之间所使用的Prim算法已经无法继续使用了——但是幸运的是,经过计算机的分析,小Hi已经筛选出了一些比较适合建造道路的路线,这个数量并没有特别的大。

所以问题变成了——小Hi现在手上拥有N座城市,且已知其中一些城市间建造道路的费用,小Hi希望知道,最少花费多少就可以使得任意两座城市都可以通过所建造的道路互相到达(假设有A、B、C三座城市,只需要在AB之间和BC之间建造道路,那么AC之间也是可以通过这两条道路连通的)。

提示:积累的好处在于可以可以随时从自己的知识库中提取想要的!

输入

每个测试点(输入文件)有且仅有一组测试数据。

在一组测试数据中:

第1行为2个整数N、M,表示小Hi拥有的城市数量和小Hi筛选出路线的条数。

接下来的M行,每行描述一条路线,其中第i行为3个整数N1_i, N2_i, V_i,分别表示这条路线的两个端点和在这条路线上建造道路的费用。

对于100%的数据,满足N<=10^5, M<=10^6,于任意i满足1<=N1_i, N2_i<=N, N1_i≠N2_i, 1<=V_i<=10^3.

对于100%的数据,满足一定存在一种方案,使得任意两座城市都可以互相到达。

输出

对于每组测试数据,输出1个整数Ans,表示为了使任意两座城市都可以通过所建造的道路互相到达至少需要的建造费用。

Sample Input
5 291 2 6742 3 2493 4 6724 5 9331 2 7883 4 1472 4 5043 4 381 3 653 5 61 5 8651 3 5901 4 6822 4 2272 4 6361 4 3121 3 1432 5 1582 3 5163 5 1021 5 6051 4 994 5 2242 4 1983 5 8941 5 8453 4 72 4 141 4 185
Sample Output
92

     题意概括:有n个城市,m条路每条路都有不同的费用,最少需要花费多少才能使所有的城市连接在一起?

解题思路:简单的Kruskal模板。
代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define M 1100000#define N 110000struct edge {int u,v,w;}e[M];int i,j,m,n;int f[N];bool cmp(edge a,edge b){return a.w<b.w;}int getf(int u){if(f[u]==u){return u;}else{f[u]=getf(f[u]);return f[u];}}int merge (int u,int v){int t1=getf(u);int t2=getf(v);if(t1!=t2){f[t2]=t1;return 1;}return 0;}void Kruskal(){int num=0,sum=0;for(i=1;i<=m;i++){f[i]=i;}for(i=0;i<n;i++){if(merge(e[i].u,e[i].v)!=0){num++;sum+=e[i].w;}if(num-1==m)break;}printf("%d\n",sum);}int main(){while(scanf("%d%d",&m,&n)!=EOF){for(i=0;i<n;i++){scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);}sort(e,e+n,cmp);Kruskal();}return 0;}
/*void Uset()  {      for(int i=1;i<=n;i++)      {          p[i]=-1;      }  }  int find(int x)  {      int s;      for(s=x;p[s]>=0;s=p[s]);      while(s!=x)      {          int t=p[x];          p[x]=s;          x=t;      }      return s;  }  void Union(int u ,int v)  {      int t1=find(u);      int t2=find(v);      if(t1==t2)          return ;      int tp=p[t1]+p[t2];      if(p[t1]>p[t2])      {          p[t1]=t2;          p[t2]=tp;      }      else      {          p[t2]=t1;          p[t1]=tp;      }  }   void Kruskal()  {            int sum=0,num=0; Uset();            
        for(i=0;i<n;i++){if(merge(e[i].u,e[i].v)!=0){num++;sum+=e[i].w;}if(num-1==m)break;}printf("%d\n",sum);
} */