hdu2363Cycling 二分+最短路

//一个无向图 ,每个点都有高度,
//问从起点1到终点n的最高点减最低点的差值最小的前提下的最短路和这个差值
//由于n<100所以可以先将这n个点按升序排,枚举这个最短路的左边最小mi,二分找最小的右边ma
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std ;
const int maxn = 110 ;
const int maxm = 5010 ;
const int inf = 0x3f3f3f3f ;
struct Edge
{
    int v  ,w ;
    int next ;
}edge[maxm<<1] ;
int n , m ;
int head[maxn] , vis[maxn] , dis[maxn] , h[maxn] , a[maxn];
int nedge ;
void addedge(int u , int v , int w)
{
    edge[nedge].v = v ;
    edge[nedge].w = w ;
    edge[nedge].next = head[u] ;
    head[u] = nedge++ ;
}
bool dijkstra(int mi , int ma)
{
     if(h[1] < mi || h[1] > ma) return false ;
    for(int i = 2;i <= n;i++)
    dis[i] = inf ;
    dis[1] = 0 ;
    memset(vis , 0 , sizeof(vis)) ;
    while(1)
    {
        int mi_1  = inf, pos ;
        for(int i = 1; i <= n ;i++)
        if(!vis[i] && dis[i] < mi_1)
        mi_1 = dis[pos = i] ;
        if(mi_1 == inf)break;
        vis[pos] = 1 ;
        for(int i = head[pos] ; i != -1 ;i = edge[i].next)
        {
            int v = edge[i].v ;
            if(h[v] < mi || h[v] > ma)continue ;
            if(dis[v] > dis[pos] + edge[i].w)
            dis[v] = dis[pos] + edge[i].w ;
        }
    }
    if(dis[n] == inf)return false  ;
    else return true ;
}
int find(int l , int r)
{
    int pos = l ;
    while(l <= r)
    {
        int mid = (l + r) >> 1 ;
        if(!dijkstra(a[pos] , a[mid]))
        l = mid + 1 ;
        else r = mid - 1;
    }
    return l ;
}
int main()
{
    //freopen("in.txt" ,"r" , stdin) ;
   // freopen("out.txt" ,"w" ,stdout) ;
    int t ;
    scanf("%d" , &t) ;
    while(t--)
    {
        scanf("%d%d" , &n , &m) ;
        memset(head , -1 , sizeof(head)) ;
        nedge = 0 ;
        for(int i = 1;i <= n;i++)
        {
            scanf("%d" , &h[i]) ;
            a[i] = h[i] ;
        }
        sort(a + 1 , a + 1 + n);
        int len_a = unique(a + 1 , a + 1 + n) - a ;
        while(m--)
        {
            int u , v , w ;
            scanf("%d%d%d" , &u  ,&v , &w) ;
            addedge(u , v , w) ;
            addedge(v , u , w) ;
        }
        int mi = 0  , ma = inf  , len = inf ;
        for(int i = 1;i <= len_a;i++)
        {
           if(a[i] > h[1])break;
           int r = find(i , len_a) ;
           if(r <= len_a)
           {
               if(a[r] - a[i] < ma - mi)
               {
                   dijkstra(a[i] , a[r]) ;
                   mi = a[i] , ma = a[r] , len = dis[n] ;
               }
               if(a[r] - a[i] == ma - mi)
               {
                   dijkstra(a[i] , a[r]) ;
                   if(dis[n] < len)
                   mi = a[i] , ma = a[r] , len = dis[n] ;
               }
           }
        }
        printf("%d %d\n" , ma - mi , len) ;
    }
    return 0 ;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-08 15:11:52

hdu2363Cycling 二分+最短路的相关文章

HDU 1839 Delay Constrained Maximum Capacity Path(二分+最短路)

题目地址:HDU 1839 我去..原来这题这么简单...网络流中这种二分建图的方式做了一大堆了..这种题还能难倒我吗...白天一直没怎么看懂题,对题意懵懵懂懂的...晚上好好看了看题,这不就是网络流中练的最多的那种二分建图模型吗....只是把网络流算法改成最短路就行了..但是两个地方手残了没能在实验室当场A掉..sad... 这题就是二分最小容量,对满足容量的加边,对时间求最短路.如果最短时间比规定时间少的话就可以继续增加容量,直到不能增加为止. 代码如下: #include <iostrea

【HDU 1839】 Delay Constrained Maximum Capacity Path(二分+最短路)

[HDU 1839] Delay Constrained Maximum Capacity Path(二分+最短路) Delay Constrained Maximum Capacity Path Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1515    Accepted Submission(s): 481 Problem

二分+最短路

二分+最短路 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu POJ 3662 Description 多年以后,笨笨长大了,成为了电话线布置师.由于地震使得某市的电话线全部损坏,笨笨是负责接到震中市的负责人.该市周围分布着N(1<=N<=1000)根据1……n顺序编号的废弃的电话线杆,任意两根线杆之间没有电话线连接,一共有p(1<=p<=10000)对电话杆可以拉电话线.

POJ 2391Ombrophobic Bovines(二分+最短路+网络流之最大流)

题目地址:http://poj.org/problem?id=2391 这个题WA了一晚上,原因是数组开小了,然后又TLE了一天,原因是数组改的过大了....不多说什么了... 思路不难,建图也不难,二分时间,然后把每个田地之间的最短距离用floyd最短路求出来.然后建立一个源点与汇点,将田地拆分成两个点,在距离之内的进行连边,要单向连边.然后将源点与田地相连,权值为每个田地的牛的数目,再把另一边的田地与汇点相连,权值为每个田地最大可避雨的牛的数目.拆开的田地之间权值可以为无穷大. 代码如下:

hdu 2962 Trucking (二分+最短路Spfa)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 Trucking Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1763    Accepted Submission(s): 618 Problem Description A certain local trucking co

P1462 通往奥格瑞玛的道路 (二分+最短路)

题目 P1462 通往奥格瑞玛的道路 给定\(n\)个点\(m\)条边,每个点上都有点权\(f[i]\),每条边上有边权,找一条道路,使边权和小于给定的数\(b\),并使最大点权最小. 解析 二分一下钱,然后跑最短路,判断一下如果只有这么多钱的话能不能到终点(最短路边权和是不是不超过\(b\)),套个最短路板子,套个二分板子,没了. 代码 //二分+最短路 #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10;

二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园

BZOJ 2709: [Violet 1]迷宫花园 Sample Input 5 10.28 9 9 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ##E # ######### 4.67 9 9 ######### # ## ## ### #S# # # # E ## # # ##### # ## ### # ##### # # # # ######### 39.06 9 9 ######### # # # # # # # #

hdu2962Trucking 二分+最短路

//一个无向图,每一条路有限制载重和长度 //问从起点到终点的最大载重,以及在最大载重的情况下的最短路是多少 //二分最大栽重,对于每个载重,小于这个载重的路径不走 #include<iostream> #include<cstring> #include<cstdio> using namespace std ; const int maxn = 1010 ; const int inf = 0x3f3f3f3f ; int vis[maxn] , dis[maxn]

poj3662Telephone Lines——二分+最短路

题目:http://poj.org/problem?id=3662 二分答案找出符合条件的最小长度: 假设了每个长度后,以这个为标准对每条边赋值,0为小于等于,1为大于,然后按这个值来跑最短路,在看看能否使用不超过k根长电线: 注意不能到达要输出-1! 不知为何l从0开始就A了,从最短的电线开始就是WA,可怖的细节: 总之,0和1这个技巧很美,打破了最短路的常规思路. 代码如下: #include<iostream> #include<cstdio> #include<cst