POJ

来源:互联网 发布:手机淘宝众筹在哪进入 编辑:程序博客网 时间:2024/05/23 18:34
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, N, M and R.Then R lines followed, each contains three integers xi, yi and di.There is a blank line before each test case.1 ≤ N, M ≤ 100000 ≤ R ≤ 50,0000 ≤ xi < N0 ≤ yi < M0 < di < 10000

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

25 5 84 3 68311 3 45830 0 65920 1 30633 3 49751 3 20494 2 21042 2 7815 5 102 4 98203 2 62363 1 88642 4 83262 0 51562 0 14634 1 24390 4 43733 4 88892 4 3133

Sample Output

7107154223

求一棵最大生成树,就是这样,只不过,男女的编号上稍微处理一下,把他们的编号区别开。

#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3fusing namespace std;/*现在我明白错在哪了,初始化写错了,不应该写成2*n+10,因为m的值可能远远大于n,所以导致初始化,不足*/int n,m,r;int pre[20020];struct edge{    int u,v;    int w;}Edge[50010];int cmp(edge a,edge b){    return a.w>b.w;}int find_root(int x){    return pre[x]==x?x:pre[x]=find_root(pre[x]);}int main(){   int t;   scanf("%d",&t);   while(t--)   {       memset(pre,0,sizeof(pre));       memset(Edge,0,sizeof(Edge));       scanf("%d %d %d",&n,&m,&r);       for(int i=0;i<n+m+10;i++)            pre[i]=i;       for(int i=0;i<r;i++)       {           int u,v,w;           scanf("%d %d %d",&u,&v,&w);           Edge[i].u=u,Edge[i].v=v+n+1,Edge[i].w=w;       }       sort(Edge,Edge+r,cmp);       long long sum=0;       int cnt=0;       for(int i=0;i<r;i++)       {           int x,y,rx,ry;           x=Edge[i].u,y=Edge[i].v;           rx=find_root(x),ry=find_root(y);           if(rx!=ry)           {                 pre[ry]=rx;                 sum+=Edge[i].w;                 cnt++;           }       }       if(cnt==n+m-1)       {           long long ans=(n+m)*10000-sum;           printf("%I64d\n",ans);       }       else       {           long long ans=10000*((n+m)-cnt-1)+(cnt+1)*10000-sum;            printf("%I64d\n",ans);       }   }    return 0;}
原创粉丝点击