题目:
题意:
马化腾和周鸿祎吃饱了撑了!他们两个又想搞事情。没事就要干架,但脑子又不好使儿,只能拜托我们求出怎么才能使他们要走的距离最短。
分析:
这题明显是最短路的题目,用Floyd铁定ACTLE。最理想的方法肯定是spfa算法,但因为数据够水小编人品好,所以dij也是可以的。
AC后感想:
前30分钟,一直错得迷迷糊糊,后来才发现,他们两位大佬可以一起走,所以要dij两次。改正后,AC了!
小编绝对不会告诉你们这道题直接输出:"Peace!"可以对6个点!
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read()
{
LL a=0,f=1;char s=getchar();
while(s<'0'||s>'9') {if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') {a=a*10+s-'0';s=getchar();}
return a*f;
}
int maxd,t[5001][5001],p[5001],p1[5001],z[5001],ans1,ans2,mina;
int min(int x,int y)
{
return x>y? y:x;
}
int max(int x,int y)
{
return x>y? x:y;
}
int main()
{
int n,m,a,b;
n=read();m=read();
for(int i=1;i<=5000;i++)//初始化
{
for(int j=1;j<=5000;j++)
t[i][j]=117901065;
t[i][i]=0;
}
for(int i=1;i<=m;i++)
{
a=read();b=read();
t[a][b]=t[b][a]=read();//双向边
maxd=max(max(a,b),maxd);//求出最大的点数
}
a=read();b=read();
//dij初始化
for(int i=1;i<=maxd;i++) p[i]=t[a][i];
z[a]=1;
int l;
for(int i=1;i<=maxd-1;i++)//第一次dij
{
l=117901065;int k=0;
for(int j=1;j<=maxd;j++)
if(z[j]==0&&p[j]<l) l=p[j],k=j;
if(k==0) break;
z[k]=1;
for(int j=1;j<=maxd;j++)
p[j]=min(p[j],p[k]+t[k][j]);
}
//dij初始化
for(int i=1;i<=maxd;i++) p1[i]=t[b][i];
for(int i=1;i<=maxd;i++) z[i]=0;
z[b]=1;
for(int i=1;i<=maxd-1;i++)//第二次
{
l=117901065;int k=0;
for(int j=1;j<=maxd;j++)
if(z[j]==0&&p1[j]<l) l=p1[j],k=j;
if(k==0) break;
z[k]=1;
for(int j=1;j<=maxd;j++)
p1[j]=min(p1[j],p1[k]+t[k][j]);
}
mina=117901065;
for(int i=1;i<=maxd;i++)//枚举两次dij所求出的值的和
{
ans1=p[i];
ans2=p1[i];
mina=min(max(ans1,ans2),mina);//求这两者间耗时最长的那一个,与其他中最短的
}
if(mina!=117901065) printf("%d",mina);//如果可以相遇
else printf("Peace!");
fclose(stdin);
fclose(stdout);
return 0;
}