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;
}