NYOJ 38布线问题(并查集)(最小生成树Kruskal)

因为每一幢楼都有线连,选择最小与外界供电设施所需要的费用最小的楼做外连。这个楼也是做为其他楼的根节点。

 
#include<cstdio>
#include<algorithm>
using namespace std;
#define M 125000
int u[M],v[M],w[M],r[M],p[502];
int cmp(const int i,const int j)//间接排序
{ return w[i] < w[j]; }
int find(int x)
{ return p[x] == x ? x : p[x]=find(p[x]); }
int main()
{
    int i,m,k,x,y,ans,t,n,e;
    //freopen("in.txt","r",stdin);
    for(scanf("%d",&t);t--;)
    {
        scanf("%d%d",&n,&e);
        for(i=0;i<e;i++)
            scanf("%d%d%d",&u[i],&v[i],&w[i]);
        scanf("%d",&ans);
        for(i=1;i<n;i++)
        {
            scanf("%d",&m);
            if(m<ans)ans=m;
        }

        for(i=0;i<n;i++)p[i]=i;//初始化并查集
        for(i=0;i<e;i++)r[i]=i;//初始化边序号
        sort(r,r+e,cmp);
        for(i=0;i<e;i++)
        {
            k=r[i];
            x=find(u[k]);
            y=find(v[k]);
            if(x!=y)
            {
                ans+=w[k];
                p[x]=y;
            }
        }

        printf("%d
",ans);
    }
    return 0;
}        
        
View Code
原文地址:https://www.cnblogs.com/qiu520/p/3222222.html