5 6 1 2 7 5 1 3 4 2 2 4 -1 10 2 5 2 4 3 4 10 1 4 5 8 5 1 5 10 5 6 1 2 7 5 1 3 4 2 2 4 -1 10 2 5 2 4 3 4 10 1 4 5 8 5 1 5 4 3 1 1 2 -1 100 1 3 10 0 0
Case 1: maximum height = 7 length of shortest route = 20 Case 2: maximum height = 4 length of shortest route = 8 Case 3: cannot reach destination
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define INF 0x3fffffff
const int N = 1010;
int n, C, R;
int first[N], dis[N];
struct edge
{
int u, v, w, h, next;
}e[N*N];
void AddEdge(int u, int v, int w, int h)
{
e[n].u = u;
e[n].v = v;
e[n].w = w;
e[n].h = h;
e[n].next = first[u];
first[u] = n++;
}
void SPFA(int start, int limit)
{
queue<int> q;
bool inq[N];
for(int i = 1; i <= C; i++)
dis[i] = INF, inq[i] = false;
dis[start] = 0;
q.push(start);
inq[start] = true;
while(!q.empty())
{
int x = q.front();
q.pop();
inq[x] = false;
for(int i = first[x]; i != -1; i = e[i].next)
{
if(e[i].h < limit)
continue;
if(dis[x] + e[i].w < dis[e[i].v])
{
dis[e[i].v] = dis[x] + e[i].w;
if(!inq[e[i].v])
{
q.push(e[i].v);
inq[e[i].v] = true;
}
}
}
}
}
int main()
{
int u, v, h, l, i, j, cas = 1;
while(~scanf("%d%d",&C,&R) && (C + R))
{
if(cas > 1)
printf("\n");
n = 0;
memset(first, -1, sizeof(first));
for(i = 0; i < R; i++)
{
scanf("%d%d%d%d",&u, &v, &h, &l);
if(h == -1) h = INF;
AddEdge(u, v, l, h);
AddEdge(v, u, l, h); //头插法添加双向边
}
int st, ed, limhet;
scanf("%d%d%d",&st, &ed, &limhet);
int l = 0, r = limhet, ans = INF, mid;
while(l <= r) //二分枚举高度,使高度尽量大
{
mid = (l + r) / 2;
SPFA(st, mid);
if(dis[ed] != INF)
{
l = mid + 1;
ans = dis[ed];
}
else
r = mid - 1;
}
printf("Case %d:\n",cas++);
if(ans != INF)
{
printf("maximum height = %d\n", r);
printf("length of shortest route = %d\n",ans);
}
else
printf("cannot reach destination\n");
}
return 0;
}hdu 2962 Trucking (最短路之SPFA算法 + 二分)
原文:http://blog.csdn.net/lyhvoyage/article/details/19233755