TYVJ(腾讯大战360) 题解
题目链接http://www.tyvj.cn/ (P1356)
现在,腾讯与360由于身处异地,非常迫切地想在最短的时间内相遇,然后干一架。但是由于双方的技术员都在努力地编程序想干掉对方,所以他们希望你来帮他们找到一个最好的方案使得相遇的时间最短。
在此我们定义"相遇"为:两个人皆在同一个有编号的城市上就可以了,并且这两个人均可以站在原地等另外一个人。也就是说,在这里我们不考虑两人在路中间相遇。
输入格式:
输入数据第一行:N和M(用空格隔开) 表示这是一个N个点的图并且有M条边
第二行到第M+1行 为这个图的详细信息。
每行共有被空格隔开的三个数:a b c。表示编号为a的城市到编号为b的城市
有一个双向边,并且要过这条双向边所需要花费的时间为c。
最后一行有两个数:S和T,S表示腾讯所处的城市(也就是深圳),T表示360所处的
城市(也就是北京)
输出格式:
输出只有一行,D,表示二者"相遇"的最短时间。当然,如果无法相遇则输出"Peace!"
注意,题目不要理解错了,腾讯和360两者可以同时移动,因此这道题需要执行两遍SPFA,然后枚举每个点,求出两个点到其他点的距离中较大值的最小值.
下面附上C++代码:
#include <iostream>
#include <cstring>
using namespace std;
struct
{
int x,y,n,z;}e[20000];
int d[20000];
bool v[20000];
int f[20000];
int q[1000000];
int d2[20000];
int o;
void add(int a,int b,int c)
{
o++;
e[o].x=a;
e[o].y=b;
e[o].z=c;
e[o].n=f[a];
f[a]=o;
}
int main()
{
int n,m;
cin>>n>>m;
for (int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
int head,tail;
head=1;tail=0;
int start,end;
cin>>start>>end;
q[1]=start;
memset(d,127,sizeof(d));
d[start]=0;
while (tail<=head)
{
tail++;
int l=q[tail];
v[l]=false;
int t=f[l];
while (t!=0)
{
if (d[l]+e[t].z<d[e[t].y])
{ d[e[t].y]=d[l]+e[t].z;
if (v[e[t].y]==false)
{
head++;
q[head]=e[t].y;
v[e[t].y]=true;
}
}
t=e[t].n;
}
}
head=1;
tail=0;
memset(d2,127,sizeof(d2));
d2[end]=0;
q[1]=end;
memset(v,0,sizeof(v));
while (tail<=head)
{
tail++;
int l=q[tail];
v[l]=false;
int t=f[l];
while (t!=0)
{
if (d2[l]+e[t].z<d2[e[t].y])
{ d2[e[t].y]=d2[l]+e[t].z;
if (v[e[t].y]==false)
{
head++;
q[head]=e[t].y;
v[e[t].y]=true;
}
}
t=e[t].n;
}
}
int maxx=2000000000;
for (int i=1;i<=n;i++)//枚举每个点,然后去D和D2中较大的一个最小值.
{ if (d[i]>=d2[i])
if (d[i]<maxx) maxx=d[i];
if (d2[i]>=d[i])
if (d2[i]<maxx) maxx=d2[i];
}
if (maxx<2000000000)
cout<<maxx<<endl; else cout<<"Peace!"<<endl;
return 0;
}