---恢复内容开始---
题目链接: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): 11428 Accepted Submission(s): 1104
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.
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
题目大意:输入C,R,代表城市个数,道路个数,下面的R行,每行4个数,a,b,c,e,分别代表 a和b之间有路,height值是c,length值是e,当c=-1时代表没有限制
最后一行三个数代表起点、终点、height的限制,输出最大的height,如果有一样的,输出最小的总length
思路:这题既要控制最短路,也要控制height值的最大,总思路就是二分+最短路。
二分控制最大的height,最短路控制最小的路径。 值得一提的是这题格式很严格,写不对就是wa...不会PE, 还有时限卡的很紧,能优化的最好都优化了
具体看代码
#include<iostream> #include<string.h> #include<map> #include<cstdio> #include<cstring> #include<stdio.h> #include<cmath> #include<ctype.h> #include<math.h> #include<algorithm> #include<set> #include<queue> typedef long long ll; using namespace std; const ll mod=1e9+7; const int maxn=1e3+10; const int maxk=5e3+10; const int maxx=1e4+10; const ll maxe=1000+10; #define INF 0x3f3f3f3f3f3f #define Lson l,mid,rt<<1 #define Rson mid+1,r,rt<<1|1 int d[maxn];//用来存储起点到该点的最短距离,初始化为足够大 int height[maxn][maxn],le[maxn][maxn];//两点间的height,length int C,R,S,E,limit,max_he,min_le,he;// bool vis[maxn];//是否访问过,初始化false void init() { //memset(height,-1,sizeof(height)); for(int i=1;i<=C;i++) { for(int j=1;j<=i;j++) { le[i][j]=le[j][i]=mod; height[i][j]=-1; } } } bool solve(int mid) { memset(vis,false,sizeof(vis)); for(int i=1;i<=C;i++) { if(height[S][i]>=mid) d[i]=le[S][i]; else d[i]=mod; //d[i]=mod; //vis[i]=false; } //d[S]=0; //he=mod; while(true) { int flag=-1; for(int i=1;i<=C;i++) { if(!vis[i]&&d[i]!=mod&&(flag==-1||d[i]<d[flag]))//没有访问过并且距离不等于mod,因为等于mod代表当前不能走 flag=i; } if(flag==-1) break; if(flag==E) return d[flag]!=mod;//这里也是一步优化,只要走到了结束点就行了 vis[flag]=true; for(int i=1;i<=C;i++) { //if(le[i][flag]>mid) continue; if(height[i][flag]<mid) continue; d[i]=min(d[i],d[flag]+le[flag][i]); //he=min(he,height[i][flag]); //d[i]=min(d[i],d[flag]+le[flag][i]); } } return d[E]!=mod; } int main() { int ca=1; //while(cin>>C>>R) while(scanf("%d%d",&C,&R)!=EOF) { if(C==0&&R==0) break; if(ca!=1) printf(" ");//这个好像一定要放在break的后面,反正我放在前面wa了 init(); int a,b,c,e; for(int i=0;i<R;i++) { scanf("%d%d%d%d",&a,&b,&c,&e); //cin>>a>>b>>c>>e; if(c==-1) c=mod;//c=-1的话,初始化为无穷大 height[a][b]=c; height[b][a]=c; le[a][b]=e; le[b][a]=e; } //cin>>S>>E>>limit; scanf("%d%d%d",&S,&E,&limit); int l=0,r=limit; min_le=0,max_he=0; while(l<=r)//从0~imit开始二分 { int mid=(l+r)/2; if(solve(mid))//mid值可以满足,寻求更大的 { max_he=mid; min_le=d[E]; l=mid+1; } else//不能满足,寻求小的 r=mid-1; } printf("Case %d: ",ca++); if(min_le+max_he==0) printf("cannot reach destination "); else { printf("maximum height = %d ",max_he); printf("length of shortest route = %d ",min_le); } } return 0; }