题意:n个点m条边,每条边有两个权,一个是路的长度,一个是路限制了货车运输的高度。最后一行给出起点,终点,和这部车子可以运输货物放的最大的高度。
思路:这里的枚举限制高度,可以过,高度从大枚举到小,可以过600ms 如果二分的话更快。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stdlib.h>
#include<vector>
using namespace std;
#define INF 999999999
#define MAX 2005
struct edge
{
int from,to;
int gaodu;
int w;
};
vector<int>G[MAX];
vector<edge>edges;
int dis[MAX];
int zx,zy,xg;
int n,m;
int ans1;
void addedge(int x,int y,int gaodu,int w)
{
edge a={x,y,gaodu,w};
edges.push_back(a);
edge b={y,x,gaodu,w};
edges.push_back(b);
G[x].push_back(edges.size()-2);
G[y].push_back(edges.size()-1);
}
bool SPFA(int limt)
{
for(int i=1;i<=n;i++)
{
dis[i]=INF;
}
queue<int>q;
q.push(zx);
dis[zx]=0;
int a;
while(!q.empty())
{
a=q.front();
q.pop();
for(int i=0;i<G[a].size();i++)
{
edge v=edges[G[a][i]];
if(v.gaodu<limt) continue;
if(dis[a]+v.w<dis[v.to])
{
dis[v.to]=dis[a]+v.w;
q.push(v.to);
}
}
}
if(dis[zy]!=INF){ ans1=dis[zy];return 1;}
return 0;
}
int main()
{ int c=1;
while(scanf("%d %d",&n,&m)&&n&&m)
{
for(int i=1;i<=n;i++)
{
G[i].clear();
}
edges.clear();
for(int i=1;i<=m;i++)
{
int x,y,gaodu,w;
scanf("%d %d %d %d",&x,&y,&gaodu,&w);
if(gaodu==-1) gaodu=INF;
addedge(x,y,gaodu,w);
}
scanf("%d %d %d",&zx,&zy,&xg);
int l=0,r=xg,mid,ans=INF;
while(l<=r)
{
mid=(l+r)/2;
if(SPFA(mid)){ans=mid,l=mid+1;}
else r=mid-1;
}
if(c!=1) printf("\n");
printf("Case %d:\n",c++);
if(ans!=INF) printf("maximum height = %d\n",ans);
else
{
printf("cannot reach destination\n");
continue;
}
printf("length of shortest route = %d\n",ans1);
}
}