Welcome to Liukejie|

liukejie

园龄:1年8个月粉丝:5关注:11

2023-07-01 11:20阅读: 21评论: 0推荐: 0

AT4733 [ABC132E] Hopscotch Addict 题解

题目传送门


思路

分层图跑最短路。


题目中说每次只能走 3 步, 我们可以把一条边拆成三条边,
拆成 122332 的三条边权为 1 的边。

连边时,可以把边建在所有边的后面:

add (x, y + n) ;
add (x + n, y + n * 2) ;
add (x + n * 2, y) ;

然后跑一遍从 S 开始的最短路。

因为每个点都跑了三遍, 最终答案 valt÷3

其他题解跑最短路大多数用的是 Dijkstra ,我就用 SPFA 写吧。

代码如下:

#include <stdio.h>
#include <cstring>
#include <queue>

using namespace std;

const int N = 3e5 + 10; // 这里数组要开三倍,因为要连三条边。
const int INF = 0x3f3f3f3f;

void add (int, int) ;
void SPFA (int) ;

bool f[N];

int n, m;
int s, t;
int tot;
int val[N];
int now[N], pre[N], son[N];

queue <int> q;

main () {
    scanf ("%d %d", &n, &m) ;
    
    for (int x, y; m; -- m) {
        scanf ("%d %d", &x, &y) ;
        
        // 连三条边。
        add (x, y + n) ;
        add (x + n, y + n * 2) ;
        add (x + n * 2, y) ;
    }
        
    scanf ("%d %d", &s, &t) ;
    
    SPFA (s) ;
    
    if (val[t] == INF)
        puts ("-1") ;
    else
        printf ("%d", val[t] / 3) ; // 最终答案除以三。
}

void add (int x, int y) { // 建图。
    pre[++ tot] = now[x];
    son[tot] = y;
    now[x] = tot;
}

void SPFA (int s) { // SPFA 求最短路。
    memset (val, 0x3f, sizeof val) ;
    val[s] = 0;
    q.push (s) ;
    
    for (; !q.empty () ;) {
        int x = q.front () ;
        q.pop () ;
        f[x] = 1;
        
        for (int i = now[x]; i; i = pre[i]) {
            int y = son[i];
            
            if (val[y] > val[x] + 1) {
                val[y] = val[x] + 1;
                   
                if (!f[y]) {
                    f[y] = 1;
                    q.push (y) ;
                }
            }
        }
    }
}

完结撒花 ∼∼∼

posted @   liukejie  阅读(21)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起