标签:
在上一回和上上回里我们知道Nettle在玩《艦これ》,Nettle在整理好舰队之后终于准备出海捞船和敌军交战了。
在这个游戏里面,海域是N个战略点(编号1..N)组成,如下图所示
其中红色的点表示有敌人驻扎,猫头像的的点表示该地图敌军主力舰队(boss)的驻扎点,虚线表示各个战略点之间的航线(无向边)。
在游戏中要从一个战略点到相邻战略点需要满足一定的条件,即需要舰队的索敌值大于等于这两点之间航线的索敌值需求。
由于提高索敌值需要将攻击机、轰炸机换成侦察机,舰队索敌值越高,也就意味着舰队的战力越低。
另外在每一个战略点会发生一次战斗,需要消耗1/K的燃料和子弹。必须在燃料和子弹未用完的情况下进入boss点才能与boss进行战斗,所以舰队最多只能走过K条航路。
现在Nettle想要以最高的战力来进攻boss点,所以他希望能够找出一条从起始点(编号为1的点)到boss点的航路,使得舰队需要达到的索敌值最低,并且有剩余的燃料和子弹。
特别说明:两个战略点之间可能不止一条航线,两个相邻战略点之间可能不止一条航线。保证至少存在一条路径能在燃料子弹用完前到达boss点。
第1行:4个整数N,M,K,T。N表示战略点数量,M表示航线数量,K表示最多能经过的航路,T表示boss点编号, 1≤N,K≤10,000, N≤M≤100,000
第2..M+1行:3个整数u,v,w,表示战略点u,v之间存在航路,w表示该航路需求的索敌值,1≤w≤1,000,000。
第1行:一个整数,表示舰队需要的最小索敌值。
5 6 2 5 1 2 3 1 3 2 1 4 4 2 5 2 3 5 5 4 5 3
3
解题:二分。。。
1 #include <iostream> 2 #include <queue> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 20010; 6 struct arc{ 7 int to,cost,next; 8 arc(int x = 0,int y = 0,int z = -1){ 9 to = x; 10 cost = y; 11 next = z; 12 } 13 }e[maxn*50]; 14 int head[maxn],d[maxn],tot,N,M,K,T; 15 void add(int u,int v,int cost){ 16 e[tot] = arc(v,cost,head[u]); 17 head[u] = tot++; 18 e[tot] = arc(u,cost,head[v]); 19 head[v] = tot++; 20 } 21 queue<int>q; 22 bool bfs(int value){ 23 while(!q.empty()) q.pop(); 24 q.push(1); 25 memset(d,-1,sizeof(d)); 26 d[1] = 0; 27 while(!q.empty()){ 28 int u = q.front(); 29 q.pop(); 30 for(int i = head[u]; ~i; i = e[i].next){ 31 if(d[e[i].to] == -1 && value >= e[i].cost && d[u] + 1 <= K){ 32 d[e[i].to] = d[u] + 1; 33 q.push(e[i].to); 34 } 35 } 36 } 37 if(d[T] == -1 || d[T] > K) return false; 38 return true; 39 } 40 int main(){ 41 int u,v,w; 42 while(~scanf("%d %d %d %d",&N,&M,&K,&T)){ 43 memset(head,-1,sizeof(head)); 44 for(int i = tot = 0; i < M; ++i){ 45 scanf("%d %d %d",&u,&v,&w); 46 add(u,v,w); 47 } 48 int low = 1,high = 1000000,ans = 0; 49 while(low <= high){ 50 int mid = (low + high)>>1; 51 if(bfs(mid)) ans = mid,high = mid - 1; 52 else low = mid + 1; 53 } 54 printf("%d\n",ans); 55 } 56 return 0; 57 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4356368.html