• 最大权森林 poj 3723


    Description

    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
    

    Source

     
    题意就是部队要征召n个男兵和m个女兵,这些人之间按编号存在r种关系,关系值越大,那么招募过来需要的钱就越少10000-亲密度就是所需要的钱,要你按照一定的顺序招募,花的钱越少。(这个题目就很奇怪,你让别人帮你拉皮条,你反而可以少给人家钱???)总之这个题目就是求一个最大权的森林,那么就是个裸的最小生成树。只不过要么改一下生成树的顺序,变成降序,要么就把权值取反,最后加上路径和ans,这个题目有个巨坑,就是男女的编号是分开的...男女分别从0开始到n,所以要处理一下输入数据,比方说女的第一个人就是0+n,(这个坑了我半个多小时debug),还有一个坑就是输入输出,cincout会tle,我关了同步也tle,不知道为什么.... 只能scanf printf....都说关了同步还比scanf快一点嘛...
    //#include <bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    #define maxn 100005
    #define INF 9999999
    
    int p[maxn],r[maxn],s,n,m,k,ans,cnt;
    struct edge
    {
        int x,y,z;
    } mp[maxn];
    
    void init(int n)
    {
        for(int i=0; i<=n; i++)
        {
            p[i]=i;
            r[i]=0;
        }
    }
    
    int Find(int x)
    {
        return p[x]==x ? x : p[x]=Find(p[x]);
    }
    
    bool cmp(const edge &a,const edge &b)
    {
        return a.z<b.z;
    }
    
    void unite(int x,int y)
    {
        x=Find(x);
        y=Find(y);
        if(x==y) return;
        if(r[x]<r[y])
            p[x]=y;
        else
        {
            p[y]=x;
            if(r[x]==r[y]) r[x]++;
        }
    }
    
    void kruskal()
    {
        sort(mp,mp+k,cmp);
        init(s);
        ans=0;
        for(int i=0; i<k; i++)
        {
            int x=Find(mp[i].x),y=Find(mp[i].y);
            if(x==y) continue;
            ans+=mp[i].z;
            unite(x,y);
            //cnt++;
            //if(cnt==s-1) return;
        }
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d %d %d",&n,&m,&k);
            s=n+m;
            memset(mp,0,sizeof(mp));
            for(int i=0;i<k;i++)
            {
                int a,b,c;
                scanf("%d %d %d",&a,&b,&c);
                mp[i].x=a;
                mp[i].y=b+n;      //注意看题男女都是从0开始编号的,要重新编号!
                mp[i].z=-c;
            }
            kruskal();
            int sum=10000*s+ans;
            printf("%d
    ",sum);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【codeforces 510D】Fox And Jumping
    【codeforces 755E】PolandBall and White-Red graph
    实用SQL语句大全
    经典SQL语句大全
    mysql安装及使用语句
    ubuntu安装mysql数据库
    android数据库sqlite增加删改查
    ubuntu 15.04怎么安装QQ
    Tagging Physical Resources in a Cloud Computing Environment
    程序员的10大编程技巧
  • 原文地址:https://www.cnblogs.com/youchandaisuki/p/8660333.html
Copyright © 2020-2023  润新知