POJ 3723 Conscription

看了半天发现原来是最小生成树啊......

先操作一次最小生成树,再看有几个集合,答案还需要加上集合数量*10000

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

const int maxn=50000;
int T;
int n,m,r;
int f[maxn];
int num;
int ans;
struct Edge
{
    int u,v;
    int cost;
}e[maxn];

bool cmp(const Edge&a,const Edge&b)
{
    return a.cost<b.cost;
}

int Find(int x)
{
    if(x!=f[x]) f[x]=Find(f[x]);
    return f[x];
}

void read()
{
    scanf("%d%d%d",&n,&m,&r);
    for(int i=1;i<=r;i++)
    {
        int a,b,c; scanf("%d%d%d",&a,&b,&c);
        a++;b++;c=10000-c;
        e[i].u=a; e[i].v=b+n; e[i].cost=c;
    }
}

void init()
{
    for(int i=1;i<=n+m;i++) f[i]=i;
    num=n+m;
    ans=0;
}

void work()
{
    sort(e+1,e+1+r,cmp);
    for(int i=1;i<=r;i++)
    {
        int fu=Find(e[i].u),fv=Find(e[i].v);
        if(fu!=fv) f[fu]=fv,num--,ans=ans+e[i].cost;
    }
    ans=ans+10000*num;
    printf("%d\n",ans);
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        read();
        init();
        work();
    }
    return 0;
}

 

posted @ 2016-03-14 19:36  Fighting_Heart  阅读(184)  评论(0编辑  收藏  举报