DIJ - The Two Routes - CodeForces 602C

DIJ - The Two Routes - CodeForces 602C

题意:

给 定 一 个 n 个 点 的 无 向 图 , 有 m 条 边 是 铁 路 , 给定一个n个点的无向图,有m条边是铁路, nm

对 于 任 意 两 点 i 和 j , 若 i 、 j 之 间 无 铁 路 , 那 就 存 在 一 条 公 路 。 对于任意两点i和j,若i、j之间无铁路,那就存在一条公路。 ijij

现 在 从 1 号 点 出 发 , 有 两 种 方 案 : 火 车 经 过 铁 路 到 终 点 n , 公 交 车 经 过 公 路 到 终 点 n , 现在从1号点出发,有两种方案:火车经过铁路到终点n,公交车经过公路到终点n, 1nn

所 有 边 ( 铁 路 和 公 路 ) 的 边 权 均 为 1 , 表 示 需 要 花 费 1 个 单 位 的 时 间 , 所有边(铁路和公路)的边权均为1,表示需要花费1个单位的时间, ()11

要 求 两 条 路 径 在 中 间 不 相 遇 , 计 算 最 少 需 要 多 少 时 间 , 火 车 与 公 交 车 均 到 达 终 点 n 。 要求两条路径在中间不相遇,计算最少需要多少时间,火车与公交车均到达终点n。 n

若 火 车 与 公 交 车 中 , 有 一 辆 车 不 能 够 到 达 n , 输 出 − 1 。 若火车与公交车中,有一辆车不能够到达n,输出-1。 n1

输入:

首 行 包 括 两 个 正 整 数 n 和 m , 首行包括两个正整数n和m, nm

接 着 m 行 输 入 m 条 铁 路 的 起 点 u 和 终 点 v 。 接着m行输入m条铁路的起点u和终点v。 mmuv

输出:

一 个 整 数 表 示 答 案 。 一个整数表示答案。

Examples
Input

4 2
1 3
3 4

Output

2

Input

4 6
1 2
1 3
1 4
2 3
2 4
3 4

Output

-1

Input

5 5
4 2
3 5
4 5
5 1
1 2

Output

3

数据范围:

2   ≤   n   ≤   400 , 0   ≤   m   ≤   n ( n   −   1 )     2 , 1   ≤   u ,   v   ≤   n , u   ≠   v 2 ≤ n ≤ 400, 0 ≤ m ≤ \frac{n(n - 1) }{ 2},1 ≤ u, v ≤ n, u ≠ v 2n4000m2n(n1)1u,vn,u=v


分析:

分 析 题 意 我 们 发 现 , 给 定 的 是 一 个 完 全 图 , 分析题意我们发现,给定的是一个完全图,

铁 路 和 公 路 中 , 必 有 一 种 能 够 直 达 n 点 , 即 花 费 为 1 , 铁路和公路中,必有一种能够直达n点,即花费为1, n1

那 么 我 们 要 计 算 的 是 两 种 情 况 分 别 从 1 到 n 的 最 短 路 , 较 长 的 一 条 路 径 的 长 度 。 那么我们要计算的是两种情况分别从1到n的最短路,较长的一条路径的长度。 1n

那 么 跑 两 遍 最 短 路 后 , 输 出 较 大 值 即 可 。 那么跑两遍最短路后,输出较大值即可。

本 题 n ≤ 400 , 用 邻 接 矩 阵 存 图 + 朴 素 版 d i j k s t r a 即 可 。 本题n≤400,用邻接矩阵存图+朴素版dijkstra即可。 n400+dijkstra

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>

#define ll long long

using namespace std;

const int N=410, inf=0x3f3f3f3f;

bool g[N][N];
int n,m;
int dis[2][N];
bool st[N];

int dijkstra(int type)
{
    memset(st,false,sizeof st);
    dis[type][1]=0;
    
    for(int i=0;i<n;i++)
    {
        int t=-1;
        for(int j=1;j<=n;j++)
            if(!st[j] && (t==-1 || dis[type][t]>dis[type][j]))
                t=j;
          
        st[t]=true;
        
        int w;
        for(int j=1;j<=n;j++)
        {
            if((!type && g[t][j]) || (type && !g[t][j])) w=1;
            else w=inf;
            dis[type][j]=min(dis[type][j],dis[type][t]+w);
        }
    }
    
    return dis[type][n]==0x3f3f3f3f ? -1 : dis[type][n];
}

int main()
{
    cin>>n>>m;
    int a,b;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&a,&b);
        g[a][b]=g[b][a]=true;
    }
    
    memset(dis,0x3f,sizeof dis);
    int t1=dijkstra(0), t2=dijkstra(1);

    if(t1==-1 || t2==-1) puts("-1");
    else printf("%d\n",max(t1,t2));
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值