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;
}