hdu1839(最小生成树)

题意:字面意思;

思路:就是多了一个前提,有些点之间可能有边,有两个处理方法,一个是有边的,这条边权值归零,另一个是,先一次循环用并查集过一遍;

代码:(用的是第一种方法)

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct node
{
    int x;int y;int s;int v;
}edge[10005];
int f[105];
int cmp(node a,node b)
{
    return a.s<b.s;
}
int findf(int x)
{
    if(f[x]==x)
        return f[x];
    else
    {
        f[x]=findf(f[x]);
        return f[x];
    }
}
bool join(int x,int y)
{
    int t1,t2;
    t1=findf(x);
    t2=findf(y);
    if(t1==t2)
        return true;
    else
    {
        f[t2]=t1;
        return false;
    }
}
int main()
{
    int n;
    int sum;
    while(scanf("%d",&n)!=EOF)
    {
        sum=0;
        if(n==0)
            break;
        for(int i=1;i<=n;i++)
            f[i]=i;
        int m=n*(n-1);m=m/2;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&edge[i].x,&edge[i].y,&edge[i].s,&edge[i].v);
            if(edge[i].v==1)
                edge[i].s=0;
        }
        sort(edge+1,edge+1+m,cmp);
        for(int i=1;i<=m;i++)
        {
            if(!join(edge[i].x,edge[i].y))
            sum+=edge[i].s;
        }
        printf("%d
",sum);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/huangdao/p/8336892.html