zoukankan      html  css  js  c++  java
  • POJ3723-Conscription-(最小生成树-Kruskal模板)

    Windy has a country, and he wants to build an army to protect his country. He has picked up N girls and M boys and wants to collect them to be his soldiers. To collect a soldier without any privilege, he must pay 10000 RMB. There are some relationships between girls and boys and Windy can use these relationships to reduce his cost. If girl x and boy y have a relationship d and one of them has been collected, Windy can collect the other one with 10000-d RMB. Now given all the relationships between girls and boys, your assignment is to find the least amount of money Windy has to pay. Notice that only one relationship can be used when collecting one soldier.

    Input

    The first line of input is the number of test case.
    The first line of each test case contains three integers, NM and R.
    Then R lines followed, each contains three integers xiyi and di.
    There is a blank line before each test case.

    1 ≤ NM ≤ 10000
    0 ≤ R ≤ 50,000
    0 ≤ xi < N
    0 ≤ yi < M
    0 < di < 10000

    Output

    For each test case output the answer in a single line.

    Sample Input

    2
    
    5 5 8
    4 3 6831
    1 3 4583
    0 0 6592
    0 1 3063
    3 3 4975
    1 3 2049
    4 2 2104
    2 2 781
    
    5 5 10
    2 4 9820
    3 2 6236
    3 1 8864
    2 4 8326
    2 0 5156
    2 0 1463
    4 1 2439
    0 4 4373
    3 4 8889
    2 4 3133
    

    Sample Output

    71071
    54223
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<vector>
    #include<queue>
    #include<map>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,m,r;
    int par[20005];
    
    struct edge
    {
        int u;
        int v;
        int cost;
    };
    edge es[50005];
    
    void init(int n)
    {
        memset(par,0,sizeof(par));
        for(int i=0;i<n;i++)
            par[i]=i;
    }
    
    int seek(int x)
    {
        if(x==par[x])
            return x;
        else
            return par[x]=seek(par[x]);
    }
    
    void unite(int x,int y)
    {
        int xx=seek(x);
        int yy=seek(y);
        if(xx!=yy)
            par[xx]=yy;
    }
    
    bool same(int x,int y)
    {
        int xx=seek(x);
        int yy=seek(y);
        return (xx==yy);
    }
    
    int boss(int n)//找有多少个集合,即有多少连通图
    {
        int res=0;
        for(int i=0;i<n;i++)
        {
            if( seek(i)==i )
                res++;
        }
        return res;
    }
    
    bool cmp(edge e1,edge e2)
    {
        return e1.cost<e2.cost;
    }
    
    int Kruskal()
    {
        sort(es,es+r,cmp);
        int res=0;
        for(int i=0;i<r;i++)
        {
            edge e=es[i];
            if(!same(e.u,e.v))
            {
                unite(e.u,e.v);
                res+=e.cost;
            }
        }
        return res;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&r);//女,男,关系数,人当做点,从0开始
            int x,y,d;
            init(n+m);
            for(int i=0;i<r;i++)
            {
                scanf("%d%d%d",&x,&y,&d);
                es[i].u=x;
                es[i].v=(n+y);//把男女都当做一类点
                es[i].cost=10000-d;
            }
            int ans=Kruskal();
            int num=boss(n+m);
            ans+=num*10000;
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    css 基础
    css 基础-1
    html 入门2-表
    CMDB (后台管理) CURD 插件
    序列化
    AES(高级加密)
    API验证
    数据库取时间(分组)
    用户权限 (知识点)
    xss 过滤
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10328054.html
Copyright © 2011-2022 走看看