这题虽然算是一道模板题,但是我是第一次见,先上大佬题解:
https://blog.csdn.net/u013761036/article/details/23261131
还有一个spfa的入门介绍讲的很好:
https://blog.csdn.net/u013445530/article/details/41761687
其实这题的关键是:
还有二分的思想。。。
代码:
//A
#include<stdio.h>
#include<string.h>
#include<queue>
#include<utility>
using namespace std;
#define MAXN 1010
#define INF 0x3f3f3f3f
typedef long long LL;
struct Edge
{
int to,w;
int next;
}E[MAXN*MAXN];
struct Road
{
int from,to;
int h;
int l;
Road(){}
Road(int a,int b,int c,int d):from(a),to(b),h(c),l(d){}
}R[MAXN*MAXN];
int Head[MAXN];
int dis[MAXN];
bool vis[MAXN];
int inqueue[MAXN];//记录每个点的入队次数
int cnt,tot;
void Build(int i)
{
E[++tot].to=R[i].to;
E[tot].w=R[i].l;
E[tot].next=Head[R[i].from];
Head[R[i].from]=tot;
E[++tot].to=R[i].from;
E[tot].w=R[i].l;
E[tot].next=Head[R[i].to];
Head[R[i].to]=tot;
}
bool spfa(int s,int n)
{
int i;
priority_queue<int>pq;
int pre;
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
memset(inqueue,0,sizeof(inqueue));
vis[s]=true;
dis[s]=0;
while(!pq.empty())
pq.pop();
pq.push(s);
while(!pq.empty())
{
pre=pq.top();
pq.pop();
vis[pre]=false;
inqueue[pre]++;
if(inqueue[pre]>n)
return false;
for(i=Head[pre];i!=-1;i=E[i].next)
{
if(dis[E[i].to]>dis[pre]+E[i].w)
{
dis[E[i].to]=dis[pre]+E[i].w;
if(vis[E[i].to]==false)
{
vis[E[i].to]=true;
pq.push(E[i].to);
}
}
}
}
return true;
}
bool Judge(int mid,int s,int e,int n)
{
int i;
tot=0;
memset(E,0,sizeof(E));
memset(Head,-1,sizeof(Head));
for(i=1;i<=cnt;i++)
{
if(R[i].h==-1||R[i].h>=mid)
Build(i);
}
spfa(s,n);
if(dis[e]==INF)
return false;
else
return true;
}
int main()
{
int i;
int kase;
int u,v,w,ll;
int c,rr;
int s,e,h;
int l,r,mid;
int ans1,ans2;//分别记录最大高度和最短距离
kase=0;
while(scanf("%d%d",&c,&rr)&&(c+rr))
{
cnt=0;
memset(R,0,sizeof(R));
for(i=1;i<=rr;i++)
{
scanf("%d%d%d%d",&u,&v,&w,&ll);
R[++cnt]=Road(u,v,w,ll);
}
scanf("%d%d%d",&s,&e,&h);
l=0;
r=h;
ans1=ans2=-1;
while(l<=r)
{
mid=(l+r)/2;
if(Judge(mid,s,e,rr))
{
ans1=mid;
ans2=dis[e];
l=mid+1;
}
else
r=mid-1;
}
if(kase>=1)
printf("\n");
printf("Case %d:\n",++kase);
if(ans1==-1)
printf("%s\n","cannot reach destination");
else
{
printf("maximum height = %d\n",ans1);
printf("length of shortest route = %d\n",ans2);
}
}
}