POJ 3723 Conscription(最小生成树)

来源:互联网 发布:战术无线通信与网络 编辑:程序博客网 时间:2024/06/05 17:24

Conscription

题目链接:

http://poj.org/problem?id=3723

解题思路:

把人看做顶点,关系看做边,这个问题就可以转化为求解无向图中最大权森林问题。最大权森林问题可以通过把所有边权取反之后

用最小生成树的算法求解。

AC代码:

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 50005;struct Edge{    int u,v,cost;}es[maxn];int n,m,r;int V;int pa[maxn];bool cmp(Edge a,Edge b){    return a.cost < b.cost;}int findset(int x){    if(x != pa[x])        pa[x] = findset(pa[x]);    return pa[x];}int kruskal(){    sort(es,es+r,cmp);    for(int i = 0; i <= V; i++)        pa[i] = i;    int i,u,v,cnt = V,sum = 0;    for(i = 0; i < r; i++)    {        u = findset(es[i].u);        v = findset(es[i].v);        if(u != v)        {            sum += es[i].cost;            pa[v] = u;            if(--cnt == 1)                break;        }    }    return sum;}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d%d%d",&n,&m,&r);        int x,y,d;        for(int i = 0; i < r; i++){            scanf("%d%d%d",&x,&y,&d);            es[i] = (Edge){x,n+y,-d};        }        V = n+m;        printf("%d\n",10000*(V)+kruskal());    }    return 0;}


0 0
原创粉丝点击