算是简单题目, 遇到有两个变量同时变化时,一般的做法是二分一个变量,求另外一个变量。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int M = 1005;
const int inf = 9999999;
int dist[M][M];
int hight[M][M];
int s, e, maxn, minn, len;
int n, m, ans, Case= 1, mid;
void init() {
minn = inf;
ans = -1;
len = inf;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++){
dist[i][j] = inf;
hight[i][j] = 0;
}
}
}
void input() {
int x, y, h, d;
for(int i = 0; i < m; i++) {
scanf("%d%d%d%d", &x, &y, &h, &d);
dist[x][y] = dist[y][x] = d;
if(h == -1){
hight[x][y] = hight[y][x] = inf;
}else {
hight[x][y] = hight[y][x] = h;
}
if(h != -1)
minn = min(h, minn);
}
scanf("%d%d%d", &s,&e, &maxn);
if(Case > 1)
printf("\n");
}
int Dijstra(int mid) {
int dis[M];
int vist[M];
int index, mmin;
for(int i = 1; i <= n; i++) {
if(hight[s][i] >= mid){
dis[i] = dist[s][i];
}else {
dis[i] = inf;
}
vist[i] = 0;
}
dis[s] = 0;
vist[s] = 1;
for(int k = 0; k <= n; k++) {
mmin = inf;
for(int i = 1; i <= n; i++) {
if(!vist[i] &&dis[i] < mmin) {
mmin = dis[i];
index = i;
}
}
if(mmin == inf)
break;
vist[index] = 1;
for(int i = 1; i <= n; i++) {
if(!vist[i] && dis[i] > dis[index] + dist[index][i] && hight[index][i] >= mid) {
dis[i] = dis[index] + dist[index][i];
}
}
}
return dis[e];
}
void work() {
int temp;
mid = (maxn + minn)/2;
while(maxn >= minn) {
temp = Dijstra(mid);
if(temp != inf){
ans = mid;
len = temp;
minn = mid + 1;
}else {
maxn = mid - 1;
}
mid = (maxn + minn)/2;
}
}
void output() {
printf("Case %d:\n", Case++);
if(ans != -1) {
printf("maximum height = %d\n", ans);
printf("length of shortest route = %d\n", len);
}else {
printf("cannot reach destination\n");
}
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF && (n || m)) {
init();
input();
work();
output();
}
return 0;
}