codeforces 601A The Two Routes

题意:题目中给你一个n个点的完全图,然后给出其中的m条无向边代表地铁路,剩下的代表公路。行走一个城市就需要花1个小时,两个人在n点之前不能在任何点相遇,然后两个人都是从1出发到n,问两个人最快在n点相遇的时间需要花多少多少?


分析:这道题是当时div 2的第三题,我觉得好难,我根本没有什么想法。

后来,看了别人的代码,我觉得很奇怪,后来才想明白。


其实不管怎么样,总有一个人可以直接到达n点,只需要花一个单位的时间。然后另外一个人就必须选择和这个人相反的方法到n点,而这个人到n的时间就是他们最少花的时间。


智商是我的硬伤呀。

然而这个题的数据不是很大,400个点,直接用Floyd暴力就可以咯。

#include<bits/stdc++.h>
using namespace std;
int w[500][500];
int ww[500][500];
int ss[500][500];
const int inf=1<<29;
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        memset(w,0,sizeof(w));
        for(int i=0;i<500;i++)
        {
            for(int j=0;j<500;j++)
            {
                ww[i][j]=inf;
            }
        }
        for(int i=0; i<m; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            w[u][v]=1;
            w[v][u]=1;
            ww[u][v]=1;
            ww[v][u]=1;
        }
        if(w[1][n]==0)//当1到n之间是公路的话,那么就直接找走铁路需要花的时间
        {
            for(int k=1; k<=n; k++)
            {
                for(int i=1; i<=n; i++)
                {
                    for(int j=i+1; j<=n; j++)
                    {
                        if(k!=i&&k!=j&&ww[i][k]!=inf&&ww[k][j]!=inf)
                        {
                            ww[i][j]=ww[j][i]=min(ww[i][j],ww[i][k]+ww[k][j]);
                        }
                    }
                }
            }
            if(ww[1][n]!=inf)
            printf("%d\n",ww[1][n]);
            else
                printf("-1\n");
        }
        else//相反的情况是一样的,只是帮完全图的值对换一下就可以。直接就可以暴力求解咯。
        {
            for(int i=0;i<500;i++)
            {
                for(int j=0;j<500;j++)
                {
                    if(ww[i][j]==1)
                    {
                        ss[i][j]=inf;
                    }
                    else if(ww[i][j]==inf)
                    {
                        ss[i][j]=1;
                    }
                }
            }
             for(int k=1; k<=n; k++)
            {
                for(int i=1; i<=n; i++)
                {
                    for(int j=i+1; j<=n; j++)
                    {
                        if(k!=i&&k!=j&&ss[i][k]!=inf&&ss[k][j]!=inf)
                        {
                            ss[i][j]=ss[j][i]=min(ss[i][j],ss[i][k]+ss[k][j]);
                        }
                    }
                }
            }
            if(ss[1][n]!=inf)
            printf("%d\n",ss[1][n]);
            else
                printf("-1\n");
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值