题目:
2010年11月3日,是一个难忘的日子。 腾讯发布消息:存360则,不留QQ。留QQ,则须卸360。 360则表示360与QQ可以共存。 这也就标志着腾讯与360的大战就此开始!
现在,腾讯与360由于身处异地,非常迫切地想在最短的时间内相遇,然后干一架。但是由于双方的技术员都在努力地编程序想干掉对方,所以他们希望你来帮他们找到一个最好的方案使得相遇的时间最短。
在此我们定义“相遇”为:两个人皆在同一个有编号的城市上就可以了,并且这两个人均可以站在原地等另外一个人。也就是说,在这里我们不考虑两人在路中间相遇。
输入:
输入数据第一行:N和M(用空格隔开) 表示这是一个N*N的图并且有M条边,第二行到第M+1行 为这个图的详细信息。
每行共有被空格隔开的三个数:a b c。表示编号为a的城市到编号为b的城市
有一个双向边,并且要过这条双向边所需要花费的时间为c。
最后一行有两个数:S和T,S表示腾讯所处的城市(也就是深圳),T表示360所处的
城市(也就是北京)
输出:
输出只有一行,D,表示二者“相遇”的最短时间。当然,如果无法相遇则输出“Peace!”
样例输入:
3 3
1 2 1
2 3 1
1 3 1
1 3
样例输出:
1
思路:
跑两遍spfa求出360 or 腾讯 到每个城市的最短路径,然后把这些最短路径去个min值,这个值就是答案,如果到不了就可以输出Peace!
题外话:我们学校的lj数据,输出Peace!可以拿60分。。。。。
代码:
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
int n,m,s,t,a[5001][5001],h[5001],tt,ojbk[5001],dis1[5001],dis2[5001],minn;
bool le[5001];
struct node
{
int w,p;
}e[10001];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&s,&t);
scanf("%d",&a[s][t]);
a[t][s]=a[s][t];
e[++tt]=(node){s,ojbk[t]} ;ojbk[t]=tt;//邻接表
e[++tt]=(node){t,ojbk[s]} ;ojbk[s]=tt;
}
scanf("%d%d",&s,&t);
memset(dis1,127/3,sizeof(dis1));
le[s]=1;
dis1[s]=0;
queue<int>z;
z.push(s);
while (!z.empty())//第一遍SPFA
{
int sum=z.front();
z.pop();
for (int i=ojbk[sum];i;i=e[i].p)
if (dis1[e[i].w]>dis1[sum]+a[sum][e[i].w])
{
dis1[e[i].w]=dis1[sum]+a[sum][e[i].w];
if (!le[e[i].w])
{
z.push(e[i].w);
le[e[i].w]=1;
}
}
le[sum]=0;
}
int bottle=s,s=t,t=bottle;
memset(dis2,127/3,sizeof(dis2));
dis2[s]=0;
le[s]=1;
z.push(s);
while (!z.empty())//第二遍SPFA
{
int sum=z.front();
z.pop();
for (int i=ojbk[sum];i;i=e[i].p)
if (dis2[e[i].w]>dis2[sum]+a[sum][e[i].w])
{
dis2[e[i].w]=dis2[sum]+a[sum][e[i].w];
if (!le[e[i].w])
{
z.push(e[i].w);
le[e[i].w]=1;
}
}
le[sum]=0;
}
minn=117901064;//求答案
for(int i=1;i<=n;i++)
if (i!=s&&i!=t) minn=min(minn,max(dis1[i],dis2[i]));
else if (i==s) minn=min(minn,dis1[i]);
else minn=min(minn,dis2[i]);
if (minn!=117901064) printf("%d",minn);
else printf("Peace!");
return 0;
}