POJ 3723 Conscription (Kruskal并查集求最小生成树)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 14661 | Accepted: 5102 |
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, 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 ≤ 10000
0 ≤ R ≤ 50,000
0 ≤ xi < N
0 ≤ yi < M
0 < di < 10000
Output
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
题意:有N+M个顶点,边:两个顶点之间的亲密度。
单独获取某个顶点的花费是10000;
如果两个顶点的亲密度为x,我已经获取了其中一个顶点,那么获取另一个顶点花费10000-x。
现在你要把所有的顶点全部获取,算出最小花费。
【方法1】
我们可以想到这是一个森林,我们需要求最小生成树(最小花费)。
由于权值x越大花费越小,所以我们把权值取反为-x,求出最小生成树(通过关系获取比直接获取可以少花费多少),
然后再加上每个点花费的10000,就得到了我们的总花费。
【方法2】
你可能会说,直接把权值设置为10000-x也可以写,
但是考虑到我们求出最小生成树之后还要再求出连通分量,
总花费 = 最小生成树(通过关系获取)+ 连通分量*10000。 明显比前一种算法复杂度要高(主要是我还不会写连通分量)。 不过不会写不要紧,我们可以用Kruskal算法用到的并查集,
并查集中的parent数组保存的就是属于哪棵树,
所以算一下parent中有几个不同的值就可以得到连通分量。
Kruskal算法讲解:http://www.cnblogs.com/zhangjiuding/p/7796526.html
代码:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;
#define MAX_N 20010
#define MAX_E 50010
#define INF 2147483647 struct edge {
int u,v,cost;
}; bool cmp(const edge & e1,const edge &e2){
return e1.cost < e2.cost;
} edge es[MAX_E]; //边集
int V,E; //顶点数和边数 int par[MAX_N]; //par[i]表示i节点的父节点
int rank[MAX_N]; // 树的高度 //初始化n个元素
void init(int n){
for(int i = ;i < n; i++){
par[i] = i;
rank[i] = ;
}
} //查询包含x节点的树的根
int find(int x){
if(par[x] == x) return x;
else return par[x] = find(par[x]);
} //合并 x和y所属的集合
void unite(int x,int y){
x = find(x);
y = find(y);
if(x == y) return; if(rank[x] < rank[y]){
par[x] = y;
}else{
par[y] = x;
if(rank[x] == rank[y]) rank[x]++;
}
} //判断x和y是否属于同一个集合
bool same(int x,int y){
return find(x) == find(y);
} int kruskal(){
sort(es, es + E, cmp);
init(V);
int res = ;
for(int i = ;i < E; 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;
cin >> t;
while(t--){ int n,m,r;
cin >> n >> m >> r;
V = n+m;
E = r;
for(int i = ;i < r; i++){
edge e;
scanf("%d%d%d",&e.u,&e.v,&e.cost);
e.cost = - e.cost;
e.v += n;
es[i] = e;
} cout << V* + kruskal() << endl;
}
return ;
}
POJ 3723 Conscription (Kruskal并查集求最小生成树)的更多相关文章
- POJ 3723 Conscription(并查集建模)
[题目链接] http://poj.org/problem?id=3723 [题目大意] 招募名单上有n个男生和m个女生,招募价格均为10000, 但是某些男女之间存在好感,则招募的时候, 可以降低与 ...
- POJ 1611 The Suspects (并查集求数量)
Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, wa ...
- Minimum Spanning Tree.prim/kruskal(并查集)
开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可) prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图 #include< ...
- Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 并查集求奇偶元环
D. Dividing Kingdom II Long time ago, there was a great kingdom and it was being ruled by The Grea ...
- C. Edgy Trees Codeforces Round #548 (Div. 2) 并查集求连通块
C. Edgy Trees time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- HDU 3018 Ant Trip (并查集求连通块数+欧拉回路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3018 题目大意:有n个点,m条边,人们希望走完所有的路,且每条道路只能走一遍.至少要将人们分成几组. ...
- TOJ 2815 Connect them (kruskal+并查集)
描述 You have n computers numbered from 1 to n and you want to connect them to make a small local area ...
- Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)
题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接. 思路:两种做法.(1)用prim算法时,输入a,b.令mp[a][b]=0 ...
- POJ-2421Constructing Roads,又是最小生成树,和第八届河南省赛的引水工程惊人的相似,并查集与最小生成树的灵活与能用,水过~~~
Constructing Roads Time Limit: 2000MS Memory Limit: 65536K Description There are N v ...
随机推荐
- ros中文术语表及消息类型表
前言:整理一些ros常用表格,包括中文术语对照表. 一.中文术语表 二.消息类型表 -END-
- tomcat指定JDK版本
在windows环境下以批处理文件方式启动tomcat,只要运行<CATALINA_HOME>/bin/startup.bat这个文件,就可以启动Tomcat. 在启动时,startup. ...
- Spark基本运行流程
不多说,直接上干货! Spark基本运行流程 Application program的组成 Job : 包含多个Task 组成的并行计算,跟Spark action对应. Stage : Job 的调 ...
- Android系统自适应屏幕大小
1.屏幕相关概念1.1分辨率是指屏幕上有横竖各有多少个像素1.2屏幕尺寸指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸android将屏幕大小分为四个级别(smal ...
- 洛谷P3704 [SDOI2017]数字表格
题目描述 Doris刚刚学习了fibonacci数列.用f[i]f[i] 表示数列的第ii 项,那么 f[0]=0f[0]=0 ,f[1]=1f[1]=1 , f[n]=f[n-1]+f[n-2],n ...
- iOS11中navigationBar上 按钮图片设置frame无效 不受约束 产生错位问题 解决
问题描述: 正常样式: 在iOS 11 iPhone X上显示效果: 观察顶部navBar上的左侧按钮 在ios 11 上 这个按钮的图片不受设置的尺寸约束,按其真实大小展示,造成图片错位,影响界 ...
- rem 自适应布局 bootstrap 移动端适配
移动端适配用:rem 自使用布局用:bootstrap
- css3背景渐变以及图片混合渲染模式(二)
http://avnpc.com/pages/photoshop-layer-blending-algorithm http://www.html5cn.org/forum.php?mod=viewt ...
- AC Codeforces Round #499 (Div. 2) E. Border 扩展欧几里得
没想出来QAQ....QAQ....QAQ.... 对于一般情况,我们知道 ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b) 时方程是一定有解的. 如果改成 ax+ ...
- mySql 使用 SQL 文件脚本 failed to open file 注意事项
1.路径不要有中文,其实最好是全英文 2.路径可以有空格 3.路径两头不要加引号 4.作为一个MySQL命令,source C:/lib/a.sql; 后边的分号是要的. 5.使用 unix 路径风格 ...