POJ 3228 Gold Transportation(带权并查集,好题)
参考链接:http://www.cnblogs.com/jiaohuang/archive/2010/11/13/1876418.html
题意:地图上某些点有金子,有些点有房子,还有一些带权路径,问把所有金子运到房子里所要经过最小的最大相邻路是多少。
也就是如果光用比“最小的最大相邻路”那条路更小的路是无法运完所有金子的,那么可以先对路径排序,然后一条一条取, 看看是否满足条件:即是否所有并查集的根节点的权值f[i]为非负。
思路:首先想到的是,要能运完所有的金子,那么必须任意一个连通器中的储藏室的总容量V大于等于所含有的金子的总量C,也就是V-C>=0。那么就想到用一个数组存储该镇的状态,若是储藏室,则权值为储藏的 量;若为发现金子的地方,则权值为金子的量的负值。这样每次合并的时候,都要更新一下父节点,即父节点的权值要加上子节点的权值。最后根节点的权值即为该集合中V-C的值。
若根节点的权值为非负,表明该点集中,可以储存宝藏的容量大于等于发现的宝藏,即这个点集能满足要求。
若根节点的权值为负值,表明该点集中还有一定数量的宝藏需要储存,但是该集合已经没有房间能存储下了,即不能满足条件。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm> using namespace std;
const int maxn=;
int n,m;
int father[maxn],f[maxn]; //f[i]表示第i个镇所拥有的宝藏,如果为负值,表明此镇需要运出-f[i]的宝藏。如果为正值,表明可以储存f[i]的宝藏
int ans;
struct Edge {
int u,v,w; //u、v是边的两端点,w是边的权值
bool operator<(const Edge tmp) const{
return w<tmp.w;
}
} edge[]; void init(){
for(int i=;i<=n;i++){
father[i]=i;
f[i]=;
}
}
int find_root(int x) {
if(father[x]!=x){
father[x]=find_root(father[x]);
}
return father[x];
}
void Union(int x,int y){
father[y]=x;
}
//判断是否所有集合都满足根节点的权值大于等于0
bool ok(){
int flag=;
for(int i=;i<=n;i++){
if(father[i]==i && f[i]<){
flag=;
break;
}
}
if(flag)
return true;
else
return false;
}
int main() {
int store;
while(scanf("%d",&n)!=EOF) {
if(n==)
break;
init();
for(int i=; i<=n; i++) {
scanf("%d",&store);
f[i]-=store; //需要运出的宝藏
}
for(int i=; i<=n; i++) {
scanf("%d",&store);
f[i]+=store; //可以储存的宝藏,因为发现宝藏和储存宝藏的地方可能为同一个,所以这里累加就行
}
scanf("%d",&m);
for(int i=; i<=m; i++) {
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
} sort(edge+,edge+m+);
int u,v,i=;
//从最小的边开始取
while(i<=m) {
u=edge[i].u;
v=edge[i].v;
int x=find_root(u);
int y=find_root(v);
if(x!=y){
Union(x,y);
f[x]+=f[y];
if(ok()){
ans=i;
break;
}
}
i++;
}
if(i==m+){
printf("No Solution\n");
}
else{
printf("%d\n",edge[ans].w);
} }
return ;
}
POJ 3228 Gold Transportation(带权并查集,好题)的更多相关文章
- POJ 1773 Parity game 带权并查集
分析:带权并查集,就是维护一堆关系 然后就是带权并查集的三步 1:首先确定权值数组,sum[i]代表父节点到子节点之间的1的个数(当然路径压缩后代表到根节点的个数) 1代表是奇数个,0代表偶数个 2: ...
- POJ 1182 食物链 【带权并查集】
<题目链接> 题目大意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我 ...
- POJ 1182 食物链 (带权并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 78551 Accepted: 23406 Description ...
- POJ 1182 食物链 【带权并查集/补集法】
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说 ...
- POJ 1733 Parity game (带权并查集)
题意:有序列A[1..N],其元素值为0或1.有M条信息,每条信息表示区间[L,R]中1的个数为偶数或奇数个,但是可能有错误的信息.求最多满足前多少条信息. 分析:区间统计的带权并查集,只是本题中路径 ...
- poj 1182 食物链【带权并查集】
设相等的边权为0,吃的边权为,被吃的边权为2,然后用带权并查集在%3的意义下做加法即可 关系为简单环的基本都可以用模环长的方式是用带权并查集 #include<iostream> #inc ...
- A Bug's Life POJ - 2492 (种类或带权并查集)
这个题目的写法有很多,用二分图染色也可以写,思路很好想,这里我们用关于并查集的两种写法来做. 题目大意:输入x,y表示x和y交配,然后判断是否有同性恋. 1 带权并查集: 我们可以用边的权值来表示一种 ...
- 【poj 1962】Corporative Network(图论--带权并查集 模版题)
P.S.我不想看英文原题的,但是看网上题解的题意看得我 炒鸡辛苦&一脸懵 +_+,打这模版题的代码也纠结至极了......不得已只能自己翻译了QwQ . 题意:有一个公司有N个企业,分成几个网 ...
- POJ 1182 食物链(带权并查集)
传送门 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65579 Accepted: 19336 Descri ...
随机推荐
- C++ Priority Queues(优先队列) and C++ Queues(队列)
C++优先队列类似队列, 但是在这个数据结构中的元素按照一定的断言排列有序. empty() 如果优先队列为空,则返回真 pop() 删除第一个元素 push() 加入一个元素 size() 返回优先 ...
- .NET中的标识符、关键字 以及 .NET中的命名规范
1.关键字 C#定义了一些关键字(public/static/void/class/int/string),这些关键字是构成C#基本语法用的. VS中蓝色字的才是关键字. Main.String.Co ...
- WP开发笔记——日期时间DateTime.Now函数
//2008年4月24日 System.DateTime.Now.ToString("D"); //2008-4-24 System.DateTime.Now.ToString(& ...
- php判断是否为手机客户端
function isWap() { $http_agent = isset ( $_SERVER ["HTTP_USER_AGENT"] ) ? $_SERVER ...
- Android:什么是Holo?【Translated By KillerLegend】
Android:什么是Holo? Martin Brinkmann on May 6, 2013 in Google Android 3 [Translated By KillerLegend] 当你 ...
- Application,Session和Cookie
做ASP.NET,肯定会和这几个对象打交道,这些也是基础面试的常见题目,总结一下还是必要的,好在大神已经总结好了,直接参考就好了: http://www.cnblogs.com/breezeblew/ ...
- 3. opencv进行SIFT特征提取
opencv中sift特征提取的步骤 使用SiftFeatureDetector的detect方法检测特征存入一个向量里,并使用drawKeypoints在图中标识出来 SiftDescriptorE ...
- Redis 三:存储类型之字符串
.赋值单个: [赋值多个:mset a b c ] .取值单个: get a [取值多个:mget a b c] .数字递增 incr a 在a的基础上+,那就是返回101 如果预先的值为0,那么返回 ...
- left edge algorithm.
今天在看GCPC 2013 的时候,遇到了一个简单的任务分配的题目. 即给定一系列任务[l,r], 每个人不能同时做两个, 最多需要几个人来完成? 这个问题的一个标准解法是对所有l,r排序,然后遇到l ...
- 实现iOS长时间后台的两种方法:Audiosession和VOIP(转)
分类: Iphone2013-01-24 14:03 986人阅读 评论(0) 收藏 举报 我们知道iOS开启后台任务后可以获得最多600秒的执行时间,而一些需要在后台下载或者与服务器保持连接的App ...