zoukankan      html  css  js  c++  java
  • hihocoder hiho第38周: 二分·二分答案 (二分搜索算法应用:二分搜索值+bfs判断可行性 )

    题目1 : 二分·二分答案

    时间限制:10000ms
    单点时限:1000ms
    内存限制: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行:一个整数,表示舰队需要的最小索敌值。

    样例输入
    5 6 2 5
    1 2 3
    1 3 2
    1 4 4
    2 5 2
    3 5 5
    4 5 3
    样例输出
    3

    代码:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <ctype.h>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #define N 10000+10
    
    using namespace std;
    
    struct node
    {
    	int v;
    	int w;
    };
    int n, m, kk, boss;
    
    vector<node>q[100000+10];
    
    bool bfs(int k)
    {   //起点编号为1
        int fa[N]; memset(fa, 0, sizeof(fa));
        fa[1]=kk;
        bool vis[N]; memset(vis, false, sizeof(vis));
        queue<int>p;
        p.push(1); vis[1]=true;
        while(!p.empty())
        {
            int cur=p.front(); p.pop();
            for(int i=0; i<q[cur].size(); i++)
            {
                int dd=q[cur][i].v;
                int ff=q[cur][i].w;
    
                if(vis[dd]==false &&ff<=k )
                {
                    vis[dd]=true;
                    fa[dd]=fa[cur]-1;
                    if(dd==boss && fa[dd]>=0 )
                    {
                        return true;
                    }
                    p.push(dd);
                }
            }
        }
        return false;
    }
    
    
    int main()
    {
    
    	scanf("%d %d %d %d", &n, &m, &kk, &boss);
    	int i, j, k;
        int u, v, w;
        node t;
        int ma=-1, mi=21000000000;
    	for(i=0; i<m; i++)
    	{
    		scanf("%d %d %d", &u, &v, &w);
    		ma=max(ma, w); mi=min(mi, w);
    
    		t.v=v; t.w=w;
    		q[u].push_back(t);
    		t.v=u; t.w=w;
    		q[v].push_back(t); //
    	}
        //二分枚举最大和最小之间的区间
        i=mi; j=ma; int mid;
        int pos;
        while(i<=j)
        {
            mid=(i+j)/2;
            if(bfs(mid)==true )
            {
                if(bfs(mid-1)==false)
                {
                    pos = mid; break;
                }
                else
                    j=mid;
            }
            else
                i=mid;
        }
    	printf("%d
    ", pos);
    	return 0;
    }
    
  • 相关阅读:
    POJ 1681 Painter's Problem(高斯消元法)
    HDU 3530 Subsequence(单调队列)
    HDU 4302 Holedox Eating(优先队列或者线段树)
    POJ 2947 Widget Factory(高斯消元法,解模线性方程组)
    HDU 3635 Dragon Balls(并查集)
    HDU 4301 Divide Chocolate(找规律,DP)
    POJ 1753 Flip Game(高斯消元)
    POJ 3185 The Water Bowls(高斯消元)
    克琳:http://liyu.eu5.org
    WinDbg使用
  • 原文地址:https://www.cnblogs.com/yspworld/p/4361100.html
Copyright © 2011-2022 走看看