Dijsktra: 先找到一个与源点s相连最短路s--->k,然后通过 k 更新
与源点相连的点,
思路:先用二分不断逼近最高的高度下的最短路;
在确定一个高度时候,就开始用Dijskstra 去找是否存在最短的路
在求最短的路的时候,要判断路中的立交桥的高度要 >= 每次逼近的假设高度
与源点相连的点,
思路:先用二分不断逼近最高的高度下的最短路;
在确定一个高度时候,就开始用Dijskstra 去找是否存在最短的路
在求最短的路的时候,要判断路中的立交桥的高度要 >= 每次逼近的假设高度
不断进行这样的过程 最后二分将逼近一个值,使高度最大下的一个最短路;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int _max = 0x3f3f3f3f;
const int maxn = 1005;
int mp[maxn][maxn];
int hei[maxn][maxn];
int dist[maxn];
bool visit[maxn];
int pre[maxn];
int n, m, st, en, H, tt;
void inint()
{
for(int i = 1; i <maxn; i++)
for(int j = 1; j <maxn; j++)
{
mp[i][j] = _max;
hei[i][j] = 0;
}
}
void input()
{
for(int i = 0; i < m; i++)
{
int u, v, h, w;
scanf("%d%d%d%d", &u, &v, &h, &w);
if(mp[u][v] > w) mp[u][v] = mp[v][u] = w;
if(h == -1) hei[u][v] = hei[v][u] = _max;//
else hei[u][v] = hei[v][u] = h;
}
scanf("%d%d%d", &st, &en, &H);
}
bool Dijsktra(int mid)
{
int k;
memset(visit, false, sizeof(visit));
for(int i = 1; i <= n; i++)
{
if(hei[st][i] >= mid) dist[i] = mp[st][i];//
else dist[i] = _max;
pre[i]=st;//记录每个节点的前驱,方便比较立交桥是否大于mid;
}
dist[st] = 0;
visit[st] = true;
for(int i = 1; i < n; i++)
{
int _min = _max;
for(int j = 1; j <= n; j++)
{
if(!visit[j] && dist[j] < _min && hei[pre[j]][j] >= mid)//判断立交桥是否满足
{
_min = dist[j];
k = j;
}
}
if(_min == _max) return false;//说明在mid这个高度值下没有;
if(k == en) return true;//满足
visit[k] = true;
for(int j = 1; j <= n; j++)
{
if(!visit[j] && dist[j] > dist[k] + mp[k][j] && mp[k][j]!=_max && hei[k][j] >= mid)//只需判断k--->j中立交桥是否满足
{ //其他在之前的判断中一定满足;
dist[j] = dist[k] + mp[k][j];
pre[j] = k;
}
}
}
return false;
}
void jsuan()
{
bool first;
int l = 1;
int r = H;
int ans;
while(r-l>=0)
{
int mid = (l+r)>>1;
first = Dijsktra(mid);
if(first)
{
l = mid+1;
ans = dist[en];//要把计算的结果存在ans中 否则可能这次满足 下次就不满足 但dist[en],被初始化,的不到结果;
} // 在这错了一下午。。。。。。。。。。。。。
else r = mid-1;
}
if(tt > 0) printf("\n");
printf("Case %d:\n", ++tt);
if(r!=0)
{
printf("maximum height = %d\n", r);
printf("length of shortest route = %d\n", ans);
}
else if(r==0)
printf("cannot reach destination\n");
}
int main()
{
tt=0;
while(scanf("%d%d", &n, &m),(n+m))
{
inint();
input();
jsuan();
}
return 0;
}