这是一道 二分+最短路 的题目!
题意是:给你一些城市之间的距离,和卡车的最高高度!然后给出起点和终点!
思路:就是先用二分,找出最大卡车高度,然后在用Dijstra来验证当这个重量时,起点到终点有没有最短路!
代码:
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
const int maxn=1005;
const int inf=0x3f3f3f3f;
int dist[maxn];
bool p[maxn];
int pre[maxn];
int n,m;
int begin1,end1,max1;
struct p
{
int height;//
int length;//用结构体,主要是有两个限制条件,我还看到有人用三维数组
} mp[maxn][maxn];
bool dijstra(int mid)
{
int i,j,pos,min;
for(i=1; i<=n; i++)
{
p[i]=false;
if(mp[begin1][i].height>=mid)//一开始这里忘记了,导致一直错,这里很重要,如果重量都不符合的话,
dist[i]=mp[begin1][i].length;//就根本不会从这条路走,也就意味着距离为无穷大
else
dist[i]=inf;
pre[i]=begin1;//记录前驱,等下下面的高度要用到
}
p[begin1]=true;
dist[begin1]=0;
for(i=1; i<n; i++)
{
min=inf;
for(j=1; j<=n; j++)
{
if(!p[j]&&dist[j]<min&&mp[pre[j]][j].height>=mid)//这里加了一个限制条件,那就是高度
{
min=dist[j];
pos=j;
}
}
p[pos]=true;
if(min==inf)return false;//直接判断不符合条件的情况
if(pos==end1)return true;
for(j=1; j<=n; j++)
{
if(!p[j]&&dist[j]>dist[pos]+mp[pos][j].length&&mp[pos][j].length!=inf&&mp[pos][j].height>=mid)
{
dist[j]=dist[pos]+mp[pos][j].length;
pre[j]=pos;
}
}
}
return false;
}
int main()
{
int tcase=0,i,ans,j;
while(scanf("%d%d",&n,&m),n+m)
{
int a,b,c,d;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
mp[i][j].length=inf;
}
}
for(i=1; i<=m; i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if(c==-1)
c=inf;
mp[a][b].height=mp[b][a].height=c;
if(mp[a][b].length>d)
{
mp[a][b].length=mp[b][a].length=d;
}
}
scanf("%d%d%d",&begin1,&end1,&max1);
if(tcase>0)//这里格式问题,读题目要特别小心
printf("\n");
printf("Case %d:\n",++tcase);
int l=1;
int r=max1;
while(l<=r)
{
int mid=(l+r)>>1;
if(dijstra(mid))
{
ans=dist[end1];
l=mid+1;
}
else
{
r=mid-1;
}
}
if(r!=0)
{
printf("maximum height = %d\n",r);
printf("length of shortest route = %d\n",ans);
}
else if(r==0)
{
printf("cannot reach destination\n");
}
}
return 0;
}