http://acm.hdu.edu.cn/showproblem.php?pid=2962
题意:找能够到达终点的最大高度下的最短路
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <utility>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
//#include <ctime>
#include <ctype.h>
using namespace std;
#define L long long
#define inf 0x3fffffff
#define M 1005
struct son{
int v;
int h;
int w;
};
vector<son> g[M];
bool inq[M];
int n, dist[M];
void init ()
{
for (int i = 1; i <= n; i++)
g[i].clear();
}
void spfa (int u, int limit)
{
int i, v, h, w;
for (i = 1; i <= n; i++)
{
dist[i] = inf;
inq[i] = false;
}
queue<int> q;
q.push (u);
inq[u] = true;
dist[u] = 0;
while (!q.empty())
{
u = q.front();
q.pop();
inq[u] = false;
for (i = 0; i < g[u].size(); i++)
{
h = g[u][i].h;
if (h < limit) //高度限制
continue;
v = g[u][i].v;
w = g[u][i].w;
if (dist[u] + w < dist[v])
{
dist[v] = dist[u] + w;
if (!inq[v])
{
q.push (v);
inq[v] = true;
}
}
}
}
}
int main()
{
int m, u, v, h, w, cc = 1, dd = 1, l, r, mid, res;
son x;
while (scanf ("%d%d", &n, &m), (n||m))
{
if (dd == 2)
printf ("\n");
dd = 2;
init();
while (m--)
{
scanf ("%d%d%d%d", &u, &v, &h, &w);
if (h == -1)
h = inf;
x.v = v, x.h = h, x.w = w;
g[u].push_back (x);
x.v = u;
g[v].push_back (x);
}
scanf ("%d%d%d", &u, &v, &h);
l = 0, r = h;
while (l < r) //二分查找最大高度【也可以暴力从大到小枚举】
{
mid = (l+r+1) / 2;
spfa (u, mid);
if (dist[v] != inf)
l = mid, res = dist[v]; //记录mid高度下u到v的最短路
else r = mid - 1;
}
printf ("Case %d:\n", cc++);
if (l == 0)
puts ("cannot reach destination");
else printf ("maximum height = %d\nlength of shortest route = %d\n", l, res);
}
return 0;
}