二分查找+最短路
二分限制高度,然后求最短路
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; const int INF=0x7FFFFFFF; const int maxn=1000+10; struct Edge { int from,to,lim,len; } e[maxn*maxn]; int N,M,tot; int st,en,Lim; vector<int>G[maxn]; int disLen[maxn]; int flag[maxn]; int Min,Max,Mid; void init() { for(int i=0; i<=N; i++) G[i].clear(); tot=0; } void SPFA() { queue<int>Q; for(int i=0; i<=N; i++) disLen[i]=INF; memset(flag,0,sizeof flag); disLen[st]=0; flag[st]=1; Q.push(st); while(!Q.empty()) { int h=Q.front(); Q.pop(); flag[h]=0; for(int i=0; i<G[h].size(); i++) { int id=G[h][i]; if(e[id].lim<Mid) continue; if(disLen[h]+e[id].len<disLen[e[id].to]) { disLen[e[id].to]=disLen[h]+e[id].len; if(flag[e[id].to]==0) { flag[e[id].to]=1; Q.push(e[id].to); } } } } } int main() { int T=1; while(~scanf("%d%d",&N,&M)) { if(N==0&&M==0) break; init(); for(int i=1; i<=M; i++) { int u,v,f,c; scanf("%d%d%d%d",&u,&v,&f,&c); if(f==-1) f=INF; e[tot].from=u; e[tot].to=v; e[tot].lim=f; e[tot].len=c; G[u].push_back(tot); tot++; e[tot].from=v; e[tot].to=u; e[tot].lim=f; e[tot].len=c; G[v].push_back(tot); tot++; } scanf("%d%d%d",&st,&en,&Lim); Min=0;Max=Lim; Mid=(Min+Max+1)/2; int ans1,ans2=INF; while (Min < Max) { Mid = (Min+Max+1) >> 1; SPFA(); if (disLen[en] != INF) Min = Mid, ans2 = disLen[en]; else Max = Mid - 1; } if(T!=1) printf(" "); printf("Case %d: ",T++); if(ans2==INF) printf("cannot reach destination "); else printf("maximum height = %d length of shortest route = %d ",Min,ans2); } return 0; }