poj2421(kruskal)(水题)

来源:互联网 发布:数据采集网络兼职 编辑:程序博客网 时间:2024/04/19 07:06

题目链接:http://poj.org/problem?id=2421

题目大意;有n个村庄  接下来是一个n*n的矩阵  代表i行第j个  代表村庄i到j的距离

现已经有m条路 问还需要最少多长的距离将所有村庄连通

思路:模板题  直接上代码

kruskal:

#include <iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<string.h>using namespace std;#define maxn 200int u[maxn*maxn],v[maxn*maxn],w[maxn*maxn];int r[maxn*maxn],pre[maxn*maxn];int n,m,t;int find(int x){int r=x;while(pre[r]!=r){r=pre[r];}int i=x,j;while(i!=r){j=pre[i];pre[i]=r;i=j;}return r;}bool cmp(int x,int y){return w[x]<w[y];}void join(int x,int y){int fx=find(x),fy=find(y);if(fx!=fy){pre[fx]=fy;}}bool check(){int ans=find(1);for(int i=2;i<=n;i++)if(find(i)!=ans)return false;return true;}void init(){int a,b;scanf("%d",&m);for(int i=0;i<m;i++){scanf("%d%d",&a,&b);join(a,b);}}void kruskal(){for(int i=1;i<=n;i++){pre[i]=i;}for(int i=0;i<t;i++)r[i]=i;sort(r,r+t,cmp);init();int sum=0;for(int i=0;i<t;i++){int e=r[i],x=find(u[e]),y=find(v[e]);if(x!=y)//如果不在一个集合之中  在将其将入并入一个集合  同时输出这条边{pre[x]=y;sum+=w[e];}if(check())//检验是否已经都在一个集合之中break;}printf("%d\n",sum);}int main(){scanf("%d",&n);t=0;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){scanf("%d",&w[t]);u[t]=i,v[t++]=j;}}kruskal();return 0;}