比赛
题目
给出两个位置,求两个位置移动到相遇(不能再路上)的最短路径。
分析
由于边数少,so使用spfa,两遍,一遍从起点,一遍从终点,把到达城市的两种方案求一次最大值,把它们求一次最小值就是答案
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#define M 5001
using namespace std;
struct node{int x,y,w,next;}e[10001];
int list[M],n,m,dis[M],dis1[M],ans=2147483647,ls[M]; bool v[M];
void spfa(int st){
int head=0,tail=1;
do{
head=head%n+1;
int t=ls[list[head]];
while (t>0){
if (dis[e[t].y]>dis[e[t].x]+e[t].w){
dis[e[t].y]=dis[e[t].x]+e[t].w;
if (!v[e[t].y]){
v[e[t].y]=1;
tail=tail%n+1;
list[tail]=e[t].y;
}
}
t=e[t].next;
}
v[list[head]]=0;
}while (head!=tail);
}
int in(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)&&c!='-') c=getchar();
if (c=='-') f=-f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int main(){
n=in(); m=in(); memset(dis,0x7f,sizeof(dis));
for (int i=1;i<=m;i++){
int u1=(i<<1)-1,u2=(i<<1);
e[u1].x=in(); e[u1].y=in(); e[u1].w=in(); e[u1].next=ls[e[u1].x]; ls[e[u1].x]=u1;
e[u2].x=e[u1].y; e[u2].y=e[u1].x; e[u2].w=e[u1].w;e[u2].next=ls[e[u2].x]; ls[e[u2].x]=u2;
}
int st=in(),en=in(); v[st]=1; list[1]=st; dis[st]=0; spfa(st); memset(v,0,sizeof(v));
if (dis[en]==2139062143){puts("Peace!"); return 0;}
for (int i=1;i<=n;i++) dis1[i]=dis[i];
memset(dis,0x7f,sizeof(dis)); dis[en]=0; list[1]=en; v[en]=1;
spfa(en); for (int i=1;i<=n;i++) ans=min(ans,max(dis1[i],dis[i]));
printf("%d",ans); return 0;
}