hihoCoder 第38周 二分答案+BFS
2015-03-22 21:48
113 查看
题意 在这个游戏里面,海域是N个战略点(编号1..N)组成,其中红色的点表示有敌人驻扎,猫头像的的点表示该地图敌军主力舰队(boss)的驻扎点,虚线表示各个战略点之间的航线(无向边)。
在游戏中要从一个战略点到相邻战略点需要满足一定的条件,即需要舰队的索敌值大于等于这两点之间航线的索敌值需求。
由于提高索敌值需要将攻击机、轰炸机换成侦察机,舰队索敌值越高,也就意味着舰队的战力越低。
另外在每一个战略点会发生一次战斗,需要消耗1/K的燃料和子弹。必须在燃料和子弹未用完的情况下进入boss点才能与boss进行战斗,所以舰队最多只能走过K条航路。
现在Nettle想要以最高的战力来进攻boss点,所以他希望能够找出一条从起始点(编号为1的点)到boss点的航路,使得舰队需要达到的索敌值最低,并且有剩余的燃料和子弹。
特别说明:两个战略点之间可能不止一条航线,两个相邻战略点之间可能不止一条航线。保证至少存在一条路径能在燃料子弹用完前到达boss点。
思路
考虑到直接做FS,有这个索敌值限制确实不好做。但是,一旦确定了索敌值,那么超过这个值得边可以认为没有,那么这个题就是非常基础的BFS。因此我们想到可以枚举索敌值~然后,枚举的话,自然希望二分答案(当然这个专题就是二分嘛~)。把能否到达T作为因变量,索敌值作为自变量,很显然,这是非递减函数,可以二分~复杂度可以接受~
在游戏中要从一个战略点到相邻战略点需要满足一定的条件,即需要舰队的索敌值大于等于这两点之间航线的索敌值需求。
由于提高索敌值需要将攻击机、轰炸机换成侦察机,舰队索敌值越高,也就意味着舰队的战力越低。
另外在每一个战略点会发生一次战斗,需要消耗1/K的燃料和子弹。必须在燃料和子弹未用完的情况下进入boss点才能与boss进行战斗,所以舰队最多只能走过K条航路。
现在Nettle想要以最高的战力来进攻boss点,所以他希望能够找出一条从起始点(编号为1的点)到boss点的航路,使得舰队需要达到的索敌值最低,并且有剩余的燃料和子弹。
特别说明:两个战略点之间可能不止一条航线,两个相邻战略点之间可能不止一条航线。保证至少存在一条路径能在燃料子弹用完前到达boss点。
思路
考虑到直接做FS,有这个索敌值限制确实不好做。但是,一旦确定了索敌值,那么超过这个值得边可以认为没有,那么这个题就是非常基础的BFS。因此我们想到可以枚举索敌值~然后,枚举的话,自然希望二分答案(当然这个专题就是二分嘛~)。把能否到达T作为因变量,索敌值作为自变量,很显然,这是非递减函数,可以二分~复杂度可以接受~
#include <stdio.h> #include <cstring> #include <queue> #include <map> #include <iostream> using namespace std; const int maxn = 10005; const int maxm = 100005; const int maxw = 1000000; typedef pair<int,int> PII; #define fi first #define se second #define MP make_pair int n,m,k,t; struct Edge{ int u,v,c,next; Edge(int u=0,int v=0,int c=0,int next = -1):u(u),v(v),c(c),next(next){ } void set(int u=0,int v=0,int c=0,int next = -1){ this->u = u; this->v = v; this->c = c; this->next = next; } }edge[maxm<<1]; int g[maxn]; int addEdge() { for(int i=0;i<m;i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); //cout<<g[u]<<endl<<g[v]<<endl<<endl; edge[i<<1].set(u,v,c,g[u]); edge[(i<<1)|1].set(v,u,c,g[v]); g[u] = i<<1; g[v] = (i<<1)|1; //cout<<g[u]<<endl<<g[v]<<endl<<endl; } } int init() { memset(g,-1,sizeof(g)); } queue<PII> q; int mark[maxn]; bool bfs(int limit) { while(q.size()!=0) q.pop(); memset(mark,0,sizeof(mark)); q.push(MP(1,0)); while(q.size()!=0) { PII tmp = q.front(); q.pop(); // cout<<tmp.fi<<endl; if(tmp.se >= k) return 0; for(int e=g[tmp.fi];e!=-1;e=edge[e].next) { if(edge[e].c > limit) continue; if(edge[e].v == t) { return 1; } if(mark[edge[e].v] == 1) continue; mark[edge[e].v] = 1; q.push(MP(edge[e].v,tmp.se+1)); } } return 0; } int main() { scanf("%d%d%d%d",&n,&m,&k,&t); int i,j; init(); addEdge(); int l,r,mid; int ans = 0; l = 1; r = maxw+1; while(l < r) { mid = (l+r)/2; // cout<<l<<endl<<r<<endl<<mid<<endl<<endl; if(bfs(mid)) { r = mid; ans = mid; } else { l = mid + 1; } } printf("%d\n",ans); return 0; }
相关文章推荐
- hihocoder hiho第38周: 二分·二分答案 (二分搜索算法应用:二分搜索值+bfs判断可行性 )
- hihocoder 1139 二分答案+BFS求最短路
- hihoCoder#1139(二分+bfs)
- ACM学习历程—Hihocoder 1139 二分·二分答案(bfs)
- 最小生成树 || ( BFS && 二分答案) —— 营救
- 【HDU5652 BestCoder Round 77 (div1) B】【并查集 or 二分答案BFS】India and China Origins 两国中间出现山脉 最早时间断绝联系
- {POJ}{3897}{Maze Stretching}{二分答案+BFS}
- 【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate
- 【hihoCoder 1139】 二分·二分答案
- 弱校胡策 大逃亡(BFS灌水+二分答案)
- 【bzoj 入门OJ】[NOIP 热身赛]Problem B: escape(二分答案+bfs)
- hiho一下 第三十八周 二分·二分答案【二分+bfs】
- 【HDU3681】Prison Break-状态压缩DP+BFS+二分答案
- 【P1902】T12 刺杀大佬【雾】(二分答案+bfs)
- 【算法学习笔记】45. 二分答案 BFS路径 SJTU OJ 1031 二哥在黄山
- HDU 3681 Prison Break(状态压缩DP+BFS+二分答案)
- 洛谷P1902 刺杀大使(二分答案+bfs验证)
- Hihocoder 第三十八周 二分答案
- hihoCoder 1139 二分·二分答案
- HDU 3681 Prison Break (二分答案+状压DP+bfs预处理)