HDU 2962 Trucking

http://acm.hdu.edu.cn/showproblem.php?pid=2962   我醉了  一定要二分h吗

Trucking

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1938    Accepted Submission(s): 670


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
 

Source
 

Recommend
gaojie   |   We have carefully selected several similar problems for you:   2722  1690  1598  1217  1142 
题目大意:给c个城市r条路,r个描述。每个描述包括,起点 终点 高度 距离。要求在高度h限制内,的最大高度(此最大高度为起点到终点的所有路径中高度的最小值),并求最出短路径。
思路:二分枚举1~h,在limit的限制下求最短路。用spfa代码如下

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 1000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657
#define INF 1<<30
const ull inf = 1LL << 61;
const double eps=1e-5;
const int maxm=1005*1005/2;
using namespace std;

bool cmp(int a,int b){
return a>b;
}
int n,m;
int pre[maxn];
struct node
{
int next,v,hight,w;
}edge[maxm];
int vis[maxn];
int dist[maxn];
int h;
void init()
{
int i,x,y,w,hight1;
memset(pre,-1,sizeof(pre));
int Index=1;
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&hight1,&w);
if(hight1!=-1)hight1=hight1;
else hight1=INF;

edge[Index].hight=hight1;
edge[Index].v=y;
edge[Index].w=w;
edge[Index].next=pre[x];
pre[x]=Index++;

edge[Index].hight=hight1;
edge[Index].v=x;
edge[Index].w=w;
edge[Index].next=pre[y];
pre[y]=Index++;
}
}
int spfa(int a,int b,int limit)
{
cle(vis);
vis[a]=1;
for(int i=1;i<=n;i++)dist[i]=INF;
dist[a]=0;
queue<int>q;
q.push(a);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int j=pre[u];j!=-1;j=edge[j].next)
{
if(edge[j].hight>=limit)
{
int e=edge[j].v;
if(dist[e]>edge[j].w+dist[u])
{
dist[e]=edge[j].w+dist[u];
if(!vis[e])
{
q.push(e);
vis[e]=1;
}
}
}
}
}
return dist[b];
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int cas=0;int a,b;
while(cin>>n>>m)
{
if(n==0&&m==0)break;
cas++; if(cas!=1)cout<<endl;
init();
scanf("%d%d%d",&a,&b,&h);
int low=1,high=h+1,ans_len=INF,ans_h=0;
while(low<high)
{
int limit=(low+high)>>1;
int r=spfa(a,b,limit);
if(r==INF)
{
high=limit;
}
else
{
low=limit+1;
if(limit>ans_h){ans_h=limit;ans_len=r;}///高度优先
else if(limit==ans_h&&r<ans_len)ans_len=r;///最短路~
}
}
printf("Case %d:\n",cas);
if(ans_len==INF)cout<<"cannot reach destination"<<endl;
else
{
printf("maximum height = %d\n", ans_h);
printf("length of shortest route = %d\n",ans_len);
}

}
return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值