POJ 3723 最小生成树

来源:互联网 发布:云计算是什么 编辑:程序博客网 时间:2024/05/17 23:10

构图思路:建立一个节点 ,该节点与其他每一个节点(男孩女孩)相连,权重为10000。 然后女孩xi和男孩yi有关系di,对应边权重设为10000-di。求最小生成树就结束啦~~~


#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<cstdlib>#include<queue>#include<functional>#include<vector>using namespace std;const int maxn = 1e5 + 5;const int maxm = 1e5 + 5;const int inf = 0x3f3f3f3f;int n,m,r;struct edge{    int u,v,cost;    bool operator < (const edge& z) const {        return cost < z.cost;    }}ed[maxm];int par[maxn],rnk[maxn];void init_union(){    memset(par,-1,sizeof(par));    memset(rnk,0,sizeof(rnk));}int find(int x){    while(par[x] >= 0) x = par[x];    return x;}void unite(int x,int y){    x = find(x);y = find(y);    if(x == y) return;    if(rnk[x] < rnk[y]){        par[x] = y;    }else{        par[y] = x;        if(rnk[x] == rnk[y]) rnk[x]++;    }}bool same(int x,int y){    return find(x) == find(y);}void solve(){    sort(ed,ed+n+m+r);    int ans = 0,cnt = 0;    init_union();    for(int i=0;i < n+m+r;i++){        if(!same(ed[i].u,ed[i].v)){            ans += ed[i].cost;            unite(ed[i].u,ed[i].v);            cnt++;            if(cnt == n + m) break;        }    }    printf("%d\n",ans);}int main(){    int cas;    scanf("%d",&cas);    while(cas--){        init_union();        scanf("%d%d%d",&n,&m,&r);        for(int i=0;i<n+m;i++){            ed[i].u = n+m;            ed[i].v = i;            ed[i].cost = 10000;        }        int a,b,c;        for(int i=n+m;i < n+m+r;i++){            scanf("%d%d%d",&a,&b,&c);            ed[i].u = a;            ed[i].v = n+b;            ed[i].cost = 10000 - c;        }        solve();    }    return 0;}


0 0
原创粉丝点击