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

 

posted @ 2010-11-09 16:25  forever zsz  阅读(506)  评论(0编辑  收藏  举报