`
king_tt
  • 浏览: 2229649 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

HDU 2363 Cycling(二分+枚举+限制最短路,好题)

 
阅读更多

链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2363


题目大意:

小明从家里走到学校去考试, 路上有各个交叉点,它们有自己的海拔高度。 小明从家里走到学校的路上,必然会经过不同的交叉点,因此会不断的走上走下,忐忐忑忑,这让他很不安,会影响他考试的发挥。因此,他要选择一条起伏最小的路去学校。所谓的“起伏最小”,是指这条路上海拔最高的点与海拔最低的点的差值最小。

在起伏最小的前提下,还要求出路程距离最短。


分析与总结:

这题让我想起以前做过的一题,HDU1598,不过那时是用最小生成树做的,而且那题只需要输出最小差而不用求最短路。

这题中,根据高度差的递增,明显满足条件的路径数量也是递增的,因此可以二分“高度差”。

光有“高度差”还是不够的,因为“起伏值”等于最大高度减最小高度, 所以需要再枚举最小高度(下限low), 在根据最小高度+“高度差”得到最大高度(上限up), 有了low和up这两个条件,就可以进行求限制最短路。

做这题WA了有20+, 因为在求最短路时没有排除掉超过“上限”的边。

之后试着最小生成树的方法做了下,先求出“最小差”和上限与下限,然后再求最短路,但是WA了,纠结中...



代码:

二分+枚举+最短路

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int INF = 0x7fffffff;
const int VN  = 120;
const int EN  = 10005;

int n;
int m;
int size;
int head[VN];
int h[VN];
int order[VN];
int d[VN];
int up;  // 上界
int low; // 下界
bool inq[VN];

struct Edge{
    int v,next;
    int w;
}E[EN];

void addEdge(int u,int v,int w){
    E[size].v=v;
    E[size].w=w;
    E[size].next=head[u];
    head[u]=size++;
}

int SPFA(int src){
    memset(inq, 0, sizeof(inq));
    for(int i=0; i<=n; ++i)d[i]=INF;
    d[src]=0;
    if(h[src]<low || h[src]>up) return INF;  // 起点不符合条件直接返回INF
    queue<int>q;
    q.push(src);
    while(!q.empty()){
        int u=q.front();  q.pop();
        if(h[u]<low || h[u]>up) continue;  // 排除符合和限制的
        inq[u] = false;
        for(int e=head[u]; e!=-1; e=E[e].next)if(h[E[e].v]>=low&&h[E[e].v]<=up){//有限制
            int tmp=d[u]+E[e].w;
            if(d[E[e].v] > tmp){
                d[E[e].v] = tmp;
                if(!inq[E[e].v]){
                    inq[E[e].v]=true;
                    q.push(E[e].v);
                }
            }
        }
    }
    return d[n];
}

int main(){
    int T, u, v;
    int len, Min, Max;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        size=0;
        memset(head, -1, sizeof(head));
        for(int i=1; i<=n; ++i){
            scanf("%d", &h[i]);
            order[i]=h[i];
            if(h[i]<Min)Min=h[i];
            if(h[i]>Max)Max=h[i];
        }
        for(int i=0; i<m; ++i){
            scanf("%d%d%d",&u,&v,&len);
            addEdge(u,v,len);
            addEdge(v,u,len);
        } 

        sort(order+1, order+1+n);
        int left=0, right=Max-Min+1, mid;
        int ans, dif=INF, minlen=INF;
        while(left < right){ // 二分“高度差”
            mid = (left+right)>>1;
            bool flag=false;
            for(int i=1; i<=n; ++i){ // 枚举最低海拔
                low=order[i];
                up=order[i]+mid; // 得到海拔上限
                int tmp=SPFA(1);
                if(tmp!=INF){
                    flag=true;
                    ans=tmp;
                    break;
                }
            } 
            if(flag){
                right=mid;
                if(mid<dif){
                    dif=mid;
                    minlen=ans;
                }
                else if(mid==dif && ans<minlen){
                    minlen=ans;
                }
            }
            else{
                left=mid+1;
            } 
        }
        printf("%d %d\n", dif, minlen);
    }
    return 0;
}



—— 生命的意义,在于赋予它意义。

原创http://blog.csdn.net/shuangde800By D_Double (转载请标明)






分享到:
评论

相关推荐

    acm入门之枚举搜索

    acm入门之枚举搜索,学校第一次acm培训,包括枚举及其优化,dfs和bfs

    HDU+2000-2099+解题报告

    1. **基础算法**:如排序(快速排序、归并排序、冒泡排序等)、搜索(二分查找、深度优先搜索、广度优先搜索等)。 2. **动态规划**:这类问题通常需要找到一种状态转移方程,通过递推或自底向上的方法求解。例如...

    HDU+2000-2099+解题报告.zip

    4. **排序与搜索**:快速排序、归并排序、二分查找等经典算法在HDU题目中经常出现。解题报告会深入讲解这些算法的原理和应用场景,并给出高效的实现代码。 5. **字符串处理**:包括KMP算法、Manacher's Algorithm等...

    hdu 3341(ac自动机+状态压缩)

    hdu 3341(ac自动机+状态压缩) 题意:容易理解... 思路:首先一开始容易想到要用到dp,开设一个dp[41][41][41][41][501]的数组来解决,但是明显内存已经超出范围了,于是就想如何减少内存呢?只要知道A、T、C、G其中...

    ACM HDU题目分类

    ACM HDU 题目分类是指对 HDU 在线判题系统中题目的分类,总结了大约十来个分类。这些分类将有助于编程选手更好地理解和解决问题。 DP 问题 DP(Dynamic Programming,动态规划)是一种非常重要的算法思想,在 ACM ...

    离线OJ题库(HDU ZJU等,部分有答案)

    离线OJ题库是为编程爱好者和程序员提供的一种便捷的学习资源,主要包含来自不同在线判题系统(如HDU - 浙江大学多模式在线评测系统,ZJU - 浙江大学在线评测系统等)的编程题目。这类题库通常包含多种编程语言的题目...

    hdu.rar_hdu

    1. **基础算法**:如排序(冒泡、选择、插入、快速、归并等)、搜索(线性、二分、深度优先、广度优先等)。 2. **高级算法**:包括动态规划(状态转移、记忆化搜索)、贪心策略、回溯法、分支限界法等。 3. **...

    最短路(HDU-2544).rar

    此外,最短路问题的变种,如带有容量限制的最短路、多目标最短路等,也值得进一步研究。 总结,最短路问题在理论和实践上都有着重要的地位。理解并掌握各种算法不仅可以深化对图论的理解,还能在实际项目中发挥关键...

    HDU刷题地图+精选详细笔记

    本人准备2020年保研机试时刷的题目(虽然最后机试取消了,...来自某中流985,在HDU和vjudge平台上大概刷了400道。本文件地图(excel表格)包含了绝大部分我刷过的题目,笔记中具有思路、代码、总结和心得。 大佬勿入!

    hdu 5007 Post Robot

    hdu 5007 Post Robot 字符串枚举。 暴力一下就可以了。

    ACM hdu 线段树题目+源代码

    ACM hdu 线段树题目+源代码 线段树是一种非常重要的数据结构,它广泛应用于算法竞赛和实际编程中。今天,我们将通过 ACM hdu 的几个题目来学习和掌握线段树的基本概念和应用。 线段树的基本概念 线段树是一种...

    hdu.rar_HDU 1089.cpp_OJ题求和_hdu_horsekw5_杭电obj

    【标题】"hdu.rar_HDU 1089.cpp_OJ题求和_hdu_horsekw5_杭电obj" 提供的信息是关于一个压缩文件,其中包含了一个名为 "HDU 1089.cpp" 的源代码文件,这个文件是为了解决杭州电子科技大学(Hangzhou Dianzi ...

    HDU二分匹配及其应用

    HDU二分匹配及其应用,此PPT是刘春英老师版权所有, 特此贡献给广大编程爱好者,特别是对于ACMer

    hdu 1695 GCD(欧拉函数+容斥原理).docx

    "hdu 1695 GCD(欧拉函数+容斥原理)" 题目大意是:给定 a, b, c, d, k,找到一队 x, y,满足 g(x, y) = k,且 x ∈ [1, b], y ∈ [1, d],问有多少对符合要求的 (x, y)。 思路是:gcd(x, y) == k 解释 x, y 都能...

    (HDUACM2010版_13)二分匹配及其应用

    杭电ACM课件2014版之(HDUACM2010版_13)二分匹配及其应用

    hdu 300+ AC 代码

    HDU 300+ AC 代码集合是一个包含超过300个已通过验证的算法解决方案的资源,这些代码主要用于解决各类计算机编程竞赛中的问题。这些竞赛通常由杭州电子科技大学(HDU)主办,旨在提升参赛者的算法设计、编程和问题...

    杭电HDU2050题的ac程序

    一个十分简单的程序,能够ac杭电hdu的第2050题,无注释,简单明了

    hdu题目分类

    在IT领域的编程竞赛中,HDU(HaoDong University)OJ(Online Judge)是一个备受推崇的在线编程平台,提供了大量的算法问题供参赛者挑战和学习。根据给定文件的信息,我们可以深入探讨HDU ACM题目分类中的几个关键...

    hdu 1753 大明A+B

    Problem Description 话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。 这时他已经不是那个只会做100以内加法的那个“小明”了,...请在一行里面输出输出A+B的值,请输出最简形式。

    HDUc++上机测试真题(错题汇集1

    在C++编程语言中,`new`和`delete`是两个关键的操作符,它们与C语言中的`malloc`和`free`有所不同。`new`不仅分配内存,还会根据指定的类型调用对应的构造函数来初始化对象,而`malloc`仅仅分配内存,不涉及对象的...

Global site tag (gtag.js) - Google Analytics