题意:在最大的高度下面求最短路,由于题目给出限高,所以我们只需要二分高度然后用SPFA
#include <iostream>
#include <string.h>
#include <queue>
#include <vector>
#include <utility>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 205
#define maxn 2005
const int INF = 9999999;
int ht[maxn][maxn];
int mp[maxn][maxn];
int d[maxn];
int mid_ht;
int n,m;
int used[maxn];
void SPFA(int s)
{
fill(d,d+n+1,INF);
queue<int> que;
fill(used,used+n+1,0);
d[s] = 0;
que.push(s);
while(!que.empty())
{
int u = que.front();que.pop();
used[u] = 0;
for(int i = 1; i <= n; i++)
{
if(ht[u][i] >= mid_ht && ht[u][i]|| ht[u][i] == -1)
{
if(d[i] > d[u] + mp[u][i])
{
d[i] = d[u] + mp[u][i];
if(!used[i])
{
used[i] = 1;
que.push(i);
}
}
}
}
}
}
int main()
{
#ifdef xxz
freopen("in.txt","r",stdin);
#endif // xxz
int a,b,c,e;
int Case = 1;
while(~scanf("%d%d",&n,&m))
{
if(n == 0 && m== 0) break;
for(int i = 0; i <= n; i++)
{
fill(mp[i],mp[i]+n+1,INF);
fill(ht[i],ht[i]+n+1,0);
}
for(int i = 0; i < m; i++)
{
scanf("%d%d%d%d",&a,&b,&c,&e);
mp[a][b] = mp[b][a] = e;
ht[a][b] = ht[b][a] = c;
}
int start,End,h;
scanf("%d%d%d",&start,&End,&h);
int l = 0, r = h;
int ans = 0 ,ans2 = INF;
while(l <= r)
{
mid_ht = (l+r)/2;
SPFA(start);
if(d[End] == INF)
{
r = mid_ht - 1;
}
else {
if(ans < mid_ht)
{
ans = mid_ht;
ans2 = d[End];
}
else if(ans == mid_ht && d[End] < ans2)//注意这一项,当高度相同时考虑更小的路径
{
ans2 = d[End];
}
l = mid_ht+1;
}
}
if(Case >1 ) printf("\n");//不然会PE
printf("Case %d:\n",Case++);
if(ans2 == INF || ans == 0)
{
printf("cannot reach destination\n");
}
else {
printf("maximum height = %d\n",ans);
printf("length of shortest route = %d\n",ans2);
}
}
return 0;
}