poj3723,最 大 生成树

Conscription

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8243   Accepted: 2859

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

POJ Monthly Contest – 2009.04.05, windy7926778

这道题我从上午10点多开始做,到现在下午快三点了才AC。

好把,这回要认真写解题报告了!!!

大意:韦小宝为了反清复明打算征兵,但是他没有权势,所以只能花钱,征一个兵给人家10000RMB(先不讨论为什么是RMB吧)。韦爵爷多聪明的人啊,心里盘算着能不能省点,正好被他发现了一个省钱的方法。爵爷发现,只要把男丁喜欢的人招进来,那么想招这个男丁就只需要花10000-d,其中d是物质化了的此男对女的爱慕程度,同样,这个规律也适应于女丁。好,here is the question:爵爷该咋的才能花最少的钱招这写人呢???

有N男M女,既然是花最少的钱,何不利用最小生成树,将权值设为10000-d,直接kruskal一下。

嗯,这个想法是正确的,但是有漏洞。因为kruscal算法默认的是所有节点连通,但是这里的男女关系很可能是森林,,,你想想,假如这里的男女关系是连通的,可以构成一颗最小生成树,那,哇,这个村庄里的男女关系好复杂啊,哈哈。

那正确的解题思路是:求出所有的最大连通子图的权值和sum,然后用10000*(N+M)-sum。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 10000
#define maxr 50005
#define maxnr maxn+maxr+10
int n, m, r, tot;        //1 ≤ N, M ≤ 10000
struct edge{
    int from, to, c;
    edge(){
        c = maxn;  //初始化c=maxn的目的就是因为利用并查集时,我直接把男、女放在一个数组par中,
    }          //女的下标是从maxn+i开始的
}cost[maxr * 2];
bool cmp(edge a, edge b){ return a.c > b.c; }
int par[maxr*2], k;        //并查集    

int find(int x){
    int r = x;
    while (par[r] != r)r = par[r];
    int i = x, j;
    while (par[i] != r){
        j = par[i];
        par[i] = r;
        i = j;
    }
    return r;
}
void unite(int x, int y){
    x = find(x); y = find(y);
    par[x] = par[y];
}
bool same(int x, int y){
    x = find(x); y = find(y);
    return x == y;
}

inline void init(){
    for (int i = 0; i < maxr*2; i++)par[i] = i;
    tot = 0;
    k = 0;
    int x, y, d;
    for (int i = 0; i < r; i++){
        scanf("%d %d %d", &x, &y, &d);
        cost[++k].from = x; cost[k].to = maxn + y; cost[k].c = d;//
        cost[++k].from = maxn + y; cost[k].to = x; cost[k].c = d;//look,从这里我就加了个偏移量maxn,并查集就可以用了
    }
    sort(cost + 1, cost + k + 1, cmp);
}

void solve(){for (int i = 1; i <= k; i++){
        if (!same(cost[i].from, cost[i].to)){
            tot += cost[i].c;
            unite(cost[i].from, cost[i].to);
        }
    }
    printf("%d\n", maxn*(n+m) - tot);
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--){
        scanf("%d %d %d", &n, &m, &r);
        init();
        solve();
    }
//    system("pause");
    return 0;
}
时间: 2024-10-18 09:39:33

poj3723,最 大 生成树的相关文章

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

NOIP2017赛前考试注意事项总结

 考前: 考试前把读入优化和库以及对拍文件打好做好准备工作,另外注意放松心态,太紧张了肯定考不好··将自己的注意力集中起来  考场策略: 考试的基本策略是对每于道题先想个20分钟,如果想不出个靠谱的方法就把赶紧暴力打了一定要打暴力,想不出正解要打暴力,想出了正解对拍也要打暴力,而且把暴力打了之后心里都踏实得多··起码保底了,打完后再想正解.   题目思考: 先要确定大体方向:模拟(往往只有第一题),策略(贪心等),数学,数据结构,图论,dp,字符串,树,二分,三分,搜索,(多半会加上剪枝折半记搜

ZTree id值太大,ZTree没有生成树,ZTree的id值过大

 ZTree id值太大,ZTree没有生成树,ZTree的id值过大 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ?Copyright 蕃薯耀 2017年7月27日 http://www.cnblogs.com/fanshuyao/ 一.问题描述: 今天使用ZTree时,从数据取出数据进行显示

POJ 2349 Arctic Network(最下生成树+求第k大边)

题目链接:http://poj.org/problem?id=2349 题目大意:有n个前哨,和s个卫星通讯装置,任何两个装了卫星通讯装置的前哨都可以通过卫星进行通信,而不管他们的位置. 否则,只有两个前哨之间的距离不超过D,才能通过无线电进行通信.求出能使所有前哨都能直接或间接通信的最小的D. 解题思路:题目要求使所有前哨都能直接或间接通信,那么相当于使n个点相连,至少需要n-1条边.可以将n个点分为s个团,每个团内部时无限通信,团与团之间通过卫星通信.那么就相当于用s个卫星装置建立s-1条边

数据挖掘十大经典算法

一. C4.5  C4.5算法是机器学习算法中的一种分类决策树算法,其核心算法是ID3 算法.   C4.5算法继承了ID3算法的优点,并在以下几方面对ID3算法进行了改进: 1) 用信息增益率来选择属性,克服了用信息增益选择属性时偏向选择取值多的属性的不足: 2) 在树构造过程中进行剪枝: 3) 能够完成对连续属性的离散化处理: 4) 能够对不完整数据进行处理. C4.5算法有如下优点:产生的分类规则易于理解,准确率较高.其缺点是:在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导

bestcoder #71 1003 找位运算&amp;的最大生成树

Clarke and MST Accepts: 33 Submissions: 92 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天克拉克变成了一名图论研究者. 他学习了最小生成树的几个算法,于是突发奇想,想做一个位运算and的最大生成树. 一棵生成树是由n-1n−1条边组成的,且nn个点两两可达.一棵生成树的大小等于所有在生成树上的边的权

NOIP2013 货车运输(最大生成树+LCA)

模拟考试的时候暴搜,结果写丑了,分都不分 下来啃了一下题解,发现要用到一个叫做倍增的东西,还没有学过.但是老师说的,没有那个东西,写暴力也有30~40分... 我觉得最大生成树还是很好理解的,因为我们要求的是图中任意两个点之间的路径上,使得边权的最小值尽量大.因此首先求最大生成树. 当我们得到最大生成树后,要求两个点之间边权最小值,我们可以首先找到他们的公共祖先.这里有一篇写得很详细的代码,并且注明了各种写法的得分http://blog.csdn.net/gengmingrui/article/

生成树协议(STP)原理与配置PVST+实现负载均衡

交换网络环路的产生 在实际网络环境中,物理环路可以提高网络的可靠性,当一条线路断掉时,另一条线路仍然可以传输数据.但是,当交换机收到广播请求时,交换机就根据转发原理(交换机从除收到该广播帧之外的所有端口转发广播帧),形成了一个环路,这种广播帧会越来越多,最终形成广播风暴,导致网络瘫痪.这种广播风暴只有在物理环路消失时才可能停止. 但是环状的物理线路能够为网络提供备份线路,增强网络的可靠性,这在网络设计中是必要的,因此,这就需要一种解决方法,一方面能够保证网络的可靠性,另一方面还要防止广播风暴的产

算法导论思考题 - 瓶颈生成树

列思路,以后填坑. a. 证明:最小生成树是瓶颈生成树 证略 b. 给定图G和整数b,线性时间内判断瓶颈生成树T值是否不超过b 解:DFS或BFS遍历图G,跳过所有权值大于b的边,最后若有节点未遍历到,则T值大于b,否则不超过b c. 求瓶颈生成树T值 1. 求出边权值的中位数(类似于求nth element一类问题)M,以此将图G的边按权值分成两部分,一部分小于等于M,另一部分大于M 2. 利用b提出的方法判断图G瓶颈生成树的T值是否不超过M,也就是看这个T值位于大小哪半边 3. 若位于小半边