ABC 132 | E - Hopscotch Addict

题目描述

给定一个无权有向图G(N个点,M条边),给定起点S和终点T,问是否可以从S走到T。如果可以到达,输出最少步数;如果不能到达,输出-1
规定一步如下:沿G中边的指向走3条边记作一步

数据范围

  • 2N105
  • 0Mmin(105,N(N1))

题解

  • 该题是一个分层图的典型问题,对于分层图问题,整体看上去是个bfs,之所以要分层,主要是考虑到状态表示和状态转移。
  • 比如该题要求的答案不是简单的dist[T],而是dist[T][0],不是从ST的最短路径的长度,而是从ST且长度mod3=0的最短路径的长度,输出的结果是dist[T][0]/3
  • 即该题可以通过思考答案的表示上入手,而长度的记录本质上是个递推,类似于dp中的状态转移。

代码

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

using namespace std;

typedef pair<int, int> pii;

const int N = 1e5 + 10;

int h[N], e[N], ne[N], idx;
int n, m;
int st, ed;
int dist[N][10];

void add(int a, int b){
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void bfs(){
    memset(dist, 0x3f, sizeof dist);
    queue<pii> q;
    q.push({st, 0});
    dist[st][0] = 0;

    while(q.size()){
        auto t = q.front();
        q.pop();
        int ver = t.first, distance = t.second;
        for(int i = h[ver]; i != -1; i = ne[i]){
            int j = e[i];
            int k = (distance + 1) % 3;
            if(dist[j][k] > dist[ver][distance] + 1){
                dist[j][k] = dist[ver][distance] + 1;
                q.push({j, k});
            }
        }
    }
    return;
}

int main()
{
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    for(int i = 1; i <= m; i ++){
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b);
    }
    scanf("%d%d", &st, &ed);
    bfs();
    if(dist[ed][0] == 0x3f3f3f3f) puts("-1");
    else printf("%d\n", dist[ed][0] / 3);

    return 0;
}

posted @   小菜珠的成长之路  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示