Dragons UVALive
来源:互联网 发布:linux dd备份 编辑:程序博客网 时间:2024/05/19 14:17
题目链接:https://vjudge.net/problem/UVALive-7018
题意:n个城市之间有m条路。共有K条龙,第Ki条龙住在Ci城市,初始有Si个头,只要他活着(头的数目不为0)每分钟会长出Ni个头。现要雇佣x名猎人去杀龙,每分钟每个猎人有两种选择:(1)在当前城市砍去龙的一个头;(2)沿着路去往相邻城市。求x的最小值。
思路:二分判断mid是否是最小的可行解。由于城市间共有m条路,有些城市可能是不可达的,这样n个城市可能变成若干个联通快,对每个连通块用二分求解出最小的可行解,所有连通块的最小可行解求和即可。可用并查集将城市根据是否联通分成若干连通块。训练赛时我给的思路学弟写的代码,思路错了两次坑他WA了两次,尴尬啊。
代码如下:
#include<iostream>#include<iomanip>#include<sstream>#include<string>#include<algorithm>#include<vector>#include<list>#include<stack>#include<map>#include<set>#include<queue>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>using namespace std;typedef long long ll;typedef long double ld;typedef pair<int,int> pii;#define rep(a,b,c) for(int (a)=(b);(a)<=(c);(a)++)#define drep(a,b,c) for(int (a)=(c);(a)>=(b);(a)--)const int inf = 0x3f3f3f3f;const int maxn = 1000+10;int n,m,k;int meida[310];int da[310];int fa[310];vector<int>v[310];vector<pair<int,int> >vv[310];int id[310];int geshu;int vis[310];bool check(int mid,int x)//判断第x个联通块雇佣mid个猎人是否可行{ int cun=mid; int sum=0; bool ok = false; int sz=v[x].size(); for(int j=0;j<sz;j++) { int t=v[x][j]; if(!vis[t]) continue; else { int ssz=vv[t].size(); for(int k=0;k<ssz;k++) { if(vv[t][k].second<mid) continue;//若增长速度小于猎人总数,一定可以杀死 else sum+=vv[t][k].first;//若增长速度大于猎人总数,则初始龙头总数之和必须小于猎人总数才行 } } } return mid>=sum;}int finds(int x){ return x==fa[x]?x:(fa[x]=finds(fa[x]));}int main(){ while(scanf("%d%d%d",&n,&m,&k)==3) { if(n==0&&m==0&&k==0) break; for(int i=0;i<=n;i++) { v[i].clear(); vv[i].clear(); } geshu=0; memset(id,-1,sizeof(id)); memset(vis,0,sizeof(vis)); int a,b; for(int i=0;i<=n;i++) fa[i]=i; for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); int aa=finds(a); int bb=finds(b); if(aa!=bb) fa[aa]=bb; } for(int i=1;i<=n;i++)//并查集划分连通块,同一连通块内城市根节点相同 { fa[i]=finds(fa[i]); } for(int i=1;i<=n;i++) { if(id[fa[i]]==-1) {id[fa[i]]=geshu++;v[geshu-1].push_back(i);}//为每个连通块编号并将城市放入对应连通块集合中 else v[id[fa[i]]].push_back(i); } int city,head,inc; for(int i=0;i<k;i++) { scanf("%d%d%d",&city,&head,&inc); vv[city].push_back(make_pair(head,inc));//每个城市可能有若干条龙 vis[city]=1;//标记该城市是否有龙 } int sum=0; for(int i=0;i<geshu;i++)//对每个连通块二分查找其最小可行解 { int l=0,res,mid,r=inf; while(l<=r) { mid=(l+r)/2; if(check(mid,i)) {res=mid;r=mid-1;} else l=mid+1; } sum+=res;//最小可行解求和 } printf("%d\n",sum); } return 0;}
阅读全文
0 0
- Dragons UVALive
- UVALive-6665-Dragons Cruller(BFS+Hash)
- UVALive-6665-Dragons Cruller(Dij+Hash)
- Dragons
- Dragons
- A. Dragons
- Codeforces Dragons
- A. Dragons codeforces+贪心
- CodeForces 230A Dragons
- Codeforces 230A Dragons
- 【CodeForces】A. Dragons
- No Time for Dragons
- CodeForces 230 A. Dragons
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- 我渴望做一只打不倒的小强
- 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理
- PHP进阶(第三弹:正则表达式)
- mysql密码忘记怎么办?
- Unity编程笔记----音效管理器
- Dragons UVALive
- 七大查找算法(附C语言代码实现)
- MOOC清华《面向对象程序设计》第4章:继承基类构造函数实验
- spring boot解决thymeleaf标签未关闭错误
- 剑指Offer—36—两个链表的第一个公共节点
- HR 模态登陆总结
- 【无用】随笔—算是,自辨?吧
- POJ 2689 Prime Distance [素数筛+想法]
- 《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项