zoukankan      html  css  js  c++  java
  • POJ3723(最小生成树,负权)

    题目描述

    温迪有一个国家,他想建立一支军队来保护他的国家。他收留了N个女孩和M个男孩,想把她们收留成他的士兵。征兵无特权,必须交纳一万元。女孩和男孩之间有一些关系,温迪可以利用这些关系来降低他的成本。如果X女孩和Y男孩有D关系,并且其中一个已经被收集,Windy可以用10000-D人民币收集另一个。现在考虑到男孩和女孩之间的所有关系,你的任务是找到风必须支付的最少的钱。注意,收集一个士兵时只能使用一个关系。Input

    输入的第一行是测试用例的数量。 每个测试用例的第一行包含三个整数,n、m和r。 然后R行,每个包含三个整数Xi,Yi和DI。 每个测试用例前都有一个空白行。

    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<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ull unsigned long long
    #define ll long long
    const int maxn=5e4+10;
    int par[maxn];
    int rank1[maxn],n,m,r;
    
    void init(int n) //初始化 
    {
        for(int i=0;i<n;i++)
        {
            par[i]=i;
            rank1[i]=0;
         } 
    }
    int find(int x)
    {
        if(par[x]==x)
        {
            return x;
        }
        else
        {
            return par[x]=find(par[x]);
        }
    }
    void unite(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x==y)
        return ;
        if(rank1[x]<rank1[y])
        {
            par[x]=y;
        }
        else
        {
            par[y]=x;
        }
        if(rank1[x]==rank1[y])
        rank1[x]++;
    }
    struct edge{
        int x,y,cost;
    }e[50005];
    bool cmp(const edge e1,const edge e2)
    {
        return e1.cost<e2.cost;
    }
    ll kruskal()
    {
        ll res=0;
        sort(e+1,e+r+1,cmp);
        for(int i=1;i<=r;i++)
        {
            edge e1=e[i];
            if(find(e1.x)!=find(e1.y))
            {
                unite(e1.x,e1.y);        
                res=res+e1.cost;
            }
        }
        return res;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {  
            scanf("%d%d%d",&n,&m,&r);
            init(n+m);
            for(int i=1;i<=r;i++)
            {
                scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].cost);
                e[i].cost=-e[i].cost;
                e[i].y=e[i].y+n; 
            }
            printf("%lld
    ",10000LL*(n+m)+kruskal());
        }
        return 0;
    }
  • 相关阅读:
    浩秦的竞聘报告
    烽火2640路由器命令行手册-14-桥接配置命令
    烽火2640路由器命令行手册-13-VPDN(L2TP,PPTP,PPPOE)配置命令
    烽火2640路由器命令行手册-12-IBM网络配置命令
    烽火2640路由器命令行手册-11-IP语音配置命令
    烽火2640路由器命令行手册-10-可靠性配置命令
    烽火2640路由器命令行手册-09-拨号配置命令
    烽火2640路由器命令行手册-08-服务质量配置命令
    烽火2640路由器命令行手册-07-安全配置命令
    烽火2640路由器命令行手册-06-组播协议配置命令
  • 原文地址:https://www.cnblogs.com/hh13579/p/11364607.html
Copyright © 2011-2022 走看看