• hiho week 38 P1 : 二分·二分答案


    P1 : 二分·二分答案

    Time Limit:10000ms
    Case Time Limit:1000ms
    Memory Limit:256MB

    描述

    在上一回和上上回里我们知道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行:一个整数,表示舰队需要的最小索敌值。

    Sample Input
    5 6 2 5
    1 2 3
    1 3 2
    1 4 4
    2 5 2
    3 5 5
    4 5 3
    Sample Output
    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
    ",ans);
    55     }
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    三路快排
    双路快排
    随机快排
    快速排序
    双向链表
    单向链表
    堆排序
    二分插入、bisect
    jmockit使用总结-MockUp重点介绍
    java拼接字符串、格式化字符串方式
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4356368.html
Copyright © 2020-2023  润新知