hdu2962 Trucking (最短路+二分查找)

Problem Description

A certain local trucking company would like to transport some goods on a cargo truck from one place to another. It is desirable to transport as much goods as possible each trip. Unfortunately, one cannot always use the roads in the shortest route: some roads may have obstacles (e.g. bridge overpass, tunnels) which limit heights of the goods transported. Therefore, the company would like to transport as much as possible each trip, and then choose the shortest route that can be used to transport that amount.

For the given cargo truck, maximizing the height of the goods
transported is equivalent to maximizing the amount of goods transported. For
safety reasons, there is a certain height limit for the cargo truck which cannot
be exceeded.

Input

The input consists of a number of cases. Each case
starts with two integers, separated by a space, on a line. These two integers
are the number of cities (C) and the number of roads (R). There are at most 1000
cities, numbered from 1. This is followed by R lines each containing the city
numbers of the cities connected by that road, the maximum height allowed on that
road, and the length of that road. The maximum height for each road is a
positive integer, except that a height of -1 indicates that there is no height
limit on that road. The length of each road is a positive integer at most 1000.
Every road can be travelled in both directions, and there is at most one road
connecting each distinct pair of cities. Finally, the last line of each case
consists of the start and end city numbers, as well as the height limit (a
positive integer) of the cargo truck. The input terminates when C = R = 0.

Output

For each case, print the case number followed by the
maximum height of the cargo truck allowed and the length of the shortest route.
Use the format as shown in the sample output. If it is not possible to reach the
end city from the start city, print "cannot reach destination" after the case
number. Print a blank line between the output of the cases.

Sample Input

5 6

1 2 7 5

1 3 4 2

2 4 -1 10

2 5 2 4

3 4 10 1

4 5 8 5

1 5 10

5 6

1 2 7 5

1 3 4 2

2 4 -1 10

2 5 2 4

3 4 10 1

4 5 8 5

1 5 4

3 1

1 2 -1 100

1 3 10

0 0

Sample Output

Case 1:

maximum height = 7

length of shortest route = 20

Case 2:

maximum height = 4

length of shortest route = 8

Case 3:

cannot reach destination

这个题花了我和我老婆一下午的时间 本来以为很简单 后来越想越复杂 改了好多遍 最后还PE了一遍T^T,唉 。。。。结果还被我老婆说了

题目大意是有n个点m条路 每条路都有一个限高,最后给出一个起点 一个终点和车所能装货物的最大高度,求在车装货物高度尽量高的情况下的最短路

先用二分列举货物的高度 再用SPFA找最短路就OK0.0,,,噢噢噢噢 最后要注意下输出格式 是在测试数据之间有空行

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

struct node
{
    int h,len;
} map[1010][1010];

int start,end,height,c;
int node[1010];
const int inf=9999999;

int Spfa(int high)
{
    for (int i=1;i<=c;i++)
    node[i]=inf;
    queue<int>q;
    int inq[1010]= {0};
    int tm=start;
    node[tm]=0;
    inq[tm]=1;
    q.push(tm);
    while (!q.empty())
    {
        int s=q.front();
        q.pop();
        for (int i=1; i<=c; i++)
        {
            //cout<<s<<i<<" "<<node[i]<<" "<<map[s][i].len<<endl;
            if (map[s][i].h>=high&&node[i]>map[s][i].len+node[s])
            {
                node[i]=map[s][i].len+node[s];
                //cout<<"   "<<i<<" "<<node[i]<<endl;
                if (!inq[i])
                {
                    q.push(i);
                    inq[i]=1;
                }
            }
        }
        inq[s]=0;

    }
    if (node[end]!=inf)
        return node[end];
    else
        return -1;
}

int main ()
{
    int r,maxx,minn,h,k=1;
    while (cin>>c>>r&&(c||r))
    {
        int ans=-1,cmp=-1;
        for(int i=1;i<=c;i++)
        {
            for(int j=1;j<=c;j++)
            {
                map[i][j].len=inf;
                map[i][j].h=0;
            }
        }
        maxx=0,minn=inf;
        for (int i=1; i<=r; i++)
        {
            int a,b,len;

            cin>>a>>b>>h>>len;
            if(h==-1) h=inf;
            if (minn>h) minn=h;
            if (maxx<h) maxx=h;
            //cout<<minn<<" "<<maxx<<endl;
            if (map[a][b].len>len)
                map[a][b].len=map[b][a].len=len;
            if (map[a][b].h<h)
                map[a][b].h=map[b][a].h=h;
        }
        cin>>start>>end>>height;
        maxx=height>maxx?maxx:height;
        int l=minn,r=maxx;
        while (l<=r)
        {
            int mid=(r+l)>>1;
            //cout<<l<<" "<<r<<" "<<mid<<endl;
            int flag=Spfa(mid);
            if (flag!=-1)
            {
                l=mid+1;
                ans=mid;
                cmp=flag;
            }
            else
                r=mid-1;
        }
        if(k>1)
        printf("\n");
        printf("Case %d:\n",k++);
        if(ans==-1)
        printf("cannot reach destination\n");
        else
        {
            printf ("maximum height = %d\n",ans);
        printf ("length of shortest route = %d\n",cmp);
        }
    }
    return 0;
}

  

hdu2962 Trucking (最短路+二分查找)

时间: 2024-10-11 16:07:04

hdu2962 Trucking (最短路+二分查找)的相关文章

hdu 2962 Trucking 最短路+二分。。Dijkstra+SPFA两种算法实现。

Trucking Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1966    Accepted Submission(s): 680 Problem Description A certain local trucking company would like to transport some goods on a cargo

二分查找

递归版(在区间[x, y)中找v的位置) 1 //递归版二分查找 2 int bsearch(int * A, int x, int y, int v) 3 { 4 5 if(v<a[x] || v>a[y-1]) return -1; 6 int m = x + (y-x)/2; //此处能不能用int m = (x+y)/2,需要仔细考虑(暂时想不到原因) 7 if(A[m]==v) return m; 8 else if(A[m]>v) return bsearch(A, x, m

二分查找总结

最近刷leetcode和lintcode,做到二分查找的部分,发现其实这种类型的题目很有规律,题目大致的分为以下几类: 1.最基础的二分查找题目,在一个有序的数组当中查找某个数,如果找到,则返回这个数在数组中的下标,如果没有找到就返回-1或者是它将会被按顺序插入的位置.这种题目继续进阶一下就是在有序数组中查找元素的上下限.继续做可以求两个区间的交集. 2.旋转数组问题,就是将一个有序数组进行旋转,然后在数组中查找某个值,其中分为数组中有重复元素和没有重复元素两种情况. 3.在杨氏矩阵中利用二分查

二分查找JAVA实现

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 一.概念 二分查

rwkj 1430 二分查找

#include<iostream>using namespace std;int n,k,a[10000]; int binsearch(int low,int high){ int i,len,s;while(low<high) { len=(high+low)/2; for(s=0,i=0;i<n;i++) s+=a[i]/len; if(s>k) low=len+1; else if(s<k) high=len-1; else return len; }}int

uva:10487 - Closest Sums(二分查找)

题目:10487 - Closest Sums 题目大意:给出一组数据,再给出m个查询的数字.要求找到这组数据里的两个数据相加的和最靠近这个查询的数据,输出那两个数据的和. 解题思路:二分查找,这样找到的话,就输出查询的数值,但是要注意找不到的情况:这里最靠近的值不一定是在找不到的时刻的前一次数据,所以要维护最靠近的要查询数的数值. 代码: #include <stdio.h> #include <algorithm> #include <stdlib.h> using

php二分查找

<?php /** * 二分查找:查找一个值在数组中的位置 *@$val:查找的值 *@$arr:操作的数组,前提是按顺序排列 */ header("content-type:text/html;charset = utf-8"); function biary_search($arr,$val){ $num = count($arr); $low = 0; $high = $num - 1; while($low<$high){ $mid = floor(($high-$

二分查找算法的 JavaScript 实现

二分查找在查找[指定值]在[有序]数据中的[位置]时是一种高效的算法. 以下仅提供 ES5 版本. var arr = [0, 2, 4, 27, 28, 54, 67, 74, 75, 79, 86, 97, 289, 290, 678] function binarySearch(arr, val) { var start = 0, end = arr.length - 1; while (start <= end) { var mid = Math.floor((start + end)

深入浅出数据结构C语言版(12)——从二分查找到二叉树

在很多有关数据结构和算法的书籍或文章中,作者往往是介绍完了什么是树后就直入主题的谈什么是二叉树balabala的.但我今天决定不按这个套路来.我个人觉得,一个东西或者说一种技术存在总该有一定的道理,不是能解决某个问题,就是能改善解决某个问题的效率.如果能够先了解到存在的问题以及已存在的解决办法的不足,那么学习新的知识就更容易接受,也更容易理解. 万幸的是,二叉树的讲解是可以按照上述顺序来进行的.那么,今天在我们讨论二叉树之前,我们先来讨论一种情形.一种操作:假设现在有一个数组,数组中的数据按照某