题目链接:http://hihocoder.com/contest/hiho38/problem/1 ,挺难想的解题思路,好题。


按照提示的算法来:

我们需要找什么?
  在这个题目中我们需要找的是路径最长边。比如存在一条路径{1, p[1], p[2], ... , p[j], T}, p = {p[1],p[2],...,p[j]] }, j < K,我们需要找的为 D(P) = Max{w(1, p[1]), w(p[j], T), Max{w(p[i], p[i+1]) | 1 <= i < j} }。则这道题的结果为找出所有从1到T的路径P',求的Min{D(P')}。由于给定的图存在环,所以要枚举出所有1到T的路径是很难的,因此我们需要换个角度去思考这个问题。

这道题结果有什么特殊性?  

  不妨假设答案为j,如果舰队满足j以上的索敌值,那么一定存在至少一条路径可以从1到T,并且路径数量小于K。如果舰队索敌值小于j,则在K条路径的条件下一定无法从1到T。否则j就不是最小值了。

则对于索敌值满足这样一个关系:

可以看出,j值刚好是是否存在路径的一个分界线。如果我们枚举一个j':

  • j'<j,无法到达boss点

  • j'>=j,一定可以到达boss点

则如何快速的找到这个分界线j,就是解决这道题目的关键。

不妨设f(x) = true(索敌值为x时,可以达到boss点), false(索敌值为x时,不能达到boss点)
二分枚举,设定枚举区间[L,R],满足f(L)=false, f(R)=true。每次取中间值Mid=(L+R)/2,若f(Mid)=true,令R=Mid;否则令L=Mid。
当L+1=R时,可以知道R即为我们需要寻找的j。

关于f(x)的求法:

  可以用BFS来判断,这里要用一个数组deep[]记录每个结点的深度信息。所以访问到一个结点时,判断该结点是否能加入队列的条件有三个:该点未访问;到达该点后路径长度不超过k(用deep[]数组来判断);当前的索敌值x不小于这条边的索敌值w。

  如果能在限制条件下到达boss的位置就返回true,否则返回false。

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1000005
const int maxn = + ;
struct Edge {
int v , w;
};
vector <Edge> e[maxn]; //邻接表来表示图
int vis[maxn] , deep[maxn];
bool check(int start , int j , int k , int end)
{ //用BFS来判断,起始点为start,j为最小索敌值,k为限制路径长度
memset(vis , , sizeof(vis));
queue <int> que;
que.push(start);
vis[start] = ;
deep[start] = ;
while(!que.empty()) {
int u = que.front();
que.pop();
for(int i = ; i < e[u].size() ; i++) {
int v = e[u][i].v;
int w = e[u][i].w;
if(!vis[v] && deep[u] < k && j >= w) { //三个条件
if(v == end)
return true;
vis[v] = ;
deep[v] = deep[u] + ;
que.push(v);
}
}
}
return false;
}
int binary_search(int l , int r , int k , int t)
{ //二分答案,区间为[l , r],限制路径长度k,终点为t
int m = (l + r) >> ;
while(l + != r) {
if(check( , m , k , t))
r = m;
else
l = m;
m = (l + r) >> ;
}
return r;
}
int main()
{
int n , m , k , t;
scanf("%d %d %d %d" , &n , &m , &k , &t);
while(m--) {
int u , v , w;
scanf("%d %d %d" , &u , &v , &w);
Edge tmp = {v , w};
e[u].push_back(tmp);
tmp.v = u;
e[v].push_back(tmp);
}
int res = binary_search( , INF , k , t);
printf("%d\n" , res);
return ;
}

hiho一下 第三十八周 二分答案的更多相关文章

  1. hiho一下 第三十九周 归并排序求逆序数

    题目链接:http://hihocoder.com/contest/hiho39/problem/1 ,归并排序求逆序数. 其实这道题也是可以用树状数组来做的,不过数据都比较大,所以要离散化预处理一下 ...

  2. hihocoder第三十六周 二分查找

    题目链接:http://hihocoder.com/contest/hiho36/problem/1 , 一个比较简单的二分. 算法: 由于数据量比较大,O(nlogn)无法通过,所以不能先排序再查找 ...

  3. hihoCoder hiho一下 第四十八周 题目1 : 拓扑排序·二

    题意: 给定一个拓扑图,其中部分结点含有1个病毒,每个结点只要收到病毒就会立即往出边所能到达的点传播,病毒数可叠加,求所有结点的病毒数总和. 思路: 根据拓扑的特点,每个入度为0的点肯定不会再被传播病 ...

  4. hiho一下 第四十八周 拓扑排序·二【拓扑排序的应用 + 静态数组 + 拓扑排序算法的时间优化】

    题目1 : 拓扑排序·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho所在学校的校园网被黑客入侵并投放了病毒.这事在校内BBS上立刻引起了大家的讨论,当 ...

  5. Java进阶(三十八)快速排序

    Java进阶(三十八)快速排序 前言 有没有既不浪费空间又可以快一点的排序算法呢?那就是"快速排序"啦!光听这个名字是不是就觉得很高端呢. 假设我们现在对"6 1 2 7 ...

  6. 达拉草201771010105《面向对象程序设计(java)》第十八周学习总结

    达拉草201771010105<面向对象程序设计(java)>第十八周学习总结 实验十八  总复习 实验时间 2018-12-30 1.实验目的与要求 (1) 综合掌握java基本程序结构 ...

  7. NeHe OpenGL教程 第三十八课:资源文件

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  8. SQL注入之Sqli-labs系列第三十八关、第三十九关,第四十关(堆叠注入)

    0x1 堆叠注入讲解 (1)前言 国内有的称为堆查询注入,也有称之为堆叠注入.个人认为称之为堆叠注入更为准确.堆叠注入为攻击者提供了很多的攻击手段,通过添加一个新 的查询或者终止查询,可以达到修改数据 ...

  9. 微信小程序把玩(三十八)获取设备信息 API

    原文:微信小程序把玩(三十八)获取设备信息 API 获取设备信息这里分为四种, 主要属性: 网络信息wx.getNetWorkType, 系统信息wx.getSystemInfo, 重力感应数据wx. ...

随机推荐

  1. VS(Visual Studio)中快速找出含中文的字符串

    环境:visual studio 2017 1.ctrl + shift + f 打卡全局查找 2.输入(".*[\u4E00-\u9FA5]+)|([\u4E00-\u9FA5]+.*&q ...

  2. Vue实现添加、删除、关键字查询

    从今天开始,将不定期更新关于 Vue 的学习以及各种方法的使用,好了,下面就开始吧 Vue的实例创建首先需要我们引入一个vue.js(也可以在本地npm安装vue,我为了省事就...),然后在HTML ...

  3. JsonParse类

    using System.Data; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System; using Syst ...

  4. AIM Tech Round 5 (rated, Div. 1 + Div. 2) D(SET,思维)

    #include<bits/stdc++.h>using namespace std;const long long mod = 1e9+7;char s[370007][27];long ...

  5. 创建、配置Servlet

    1.创建Servlet 2.选择继承的类及需要覆盖的方法 3.Servlet结构 package com.sysker.servlet; import java.io.IOException; imp ...

  6. SQL Server 2012安装——.net framework 3.5离线安装

    前言 电脑用着一直很不舒服,所以就决定对电脑重新配置一番,在装数据库这里,可谓是屡装屡败.自己感觉太麻烦了,于是每次数据库装失败后,就重装系统,然后配置上网文档,这样一来,弄得自己挺恶心,这次很明显成 ...

  7. Mice and Holes 单调队列优化dp

    Mice and Holes 单调队列优化dp n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离.1 ≤ n, m ≤ 5000. ​ 首先列出朴素的dp方程:\(f[i][j] ...

  8. java线程池之一:创建线程池的方法

    在Java开发过程中经常需要用到线程,为了减少资源的开销,提高系统性能,Java提供了线程池,即事先创建好线程,如果需要使用从池中取即可,Java中创建线程池有以下的方式, 1.使用ThreadPoo ...

  9. jenkins+maven+Tomcat+shell构建自动化部署

    https://yq.aliyun.com/articles/685931 1.官网下载war包:jenkins本质上就是一个web应用,直接下载jenkins的war包通过tomcat运行即可.ht ...

  10. springboot 简单使用shiro登录

    首先引入需要的pom <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shir ...