【SPFA】【最短路】 腾讯大战360

19 篇文章 0 订阅
14 篇文章 0 订阅

题目:

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值