当前位置: 首页 > article >正文

搜索,CF 1666L - Labyrinth

目录

一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

二、解题报告

1、思路分析

2、复杂度

3、代码详解


一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

L - Labyrinth


二、解题报告

1、思路分析

考虑 从 s出发,搜索到 t,然后从t 沿着反向边一路往上走,不经过s -> t路径上的点最终到达s,那么说明找到了 两条首尾相同且不相交路径

如下图,黑色为正向边路径,红色为反向边路径

考虑从 s 开始dfs,额外添加参数 p 记录上一个点,rev 记录当前是否走逆向,如果当前为逆向那么后续只能逆向走

搜索的时候注意不能在s 就开始走逆向

以及 遇到搜索过的点,如果当前为逆向并且 该点为s,其实可以接着搜(找到了答案)

2、复杂度

时间复杂度: O(N + M)空间复杂度:O(N + M)

3、代码详解

 ​
#include <bits/stdc++.h>

// #define DEBUG

using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;

constexpr int inf32 = 1E9 + 7;
constexpr i64 inf64 = 1E18 + 7;

void solve() {
    int n, m, s;
    std::cin >> n >> m >> s;

    -- s;

    std::vector<std::vector<std::pair<int, int>>> adj(n);
    for (int i = 0; i < m; ++ i) {
        int u, v;
        std::cin >> u >> v;
        -- u, -- v;
        adj[u].emplace_back(v, 0);
        adj[v].emplace_back(u, 1);
    }

    std::vector<bool> vis(n);
    std::vector<int> nxt0(n, -1), nxt1(n, -1);

    auto dfs = [&](auto &&self, int u, int p, bool rev) -> bool {
        if (u == s && rev) {
            return true;
        }

        vis[u] = true;

        for (auto &[v, d] : adj[u]) {
            if (v == p) {
                continue;
            }

            if (vis[v] && !(v == s && d == 1)) {
                continue;
            }

            if (d == 0 && rev == 0) {
                nxt0[u] = v;
                if (self(self, v, u, 0)) {
                    return true;
                }
                nxt0[u] = -1;
            } else if(d == 1 && u != s) {
                nxt1[u] = v;
                if (self(self, v, u, 1)) {
                    return true;
                }   
                nxt1[u] = -1;
            }
        }

        vis[u] = false;

        return false;
    };


    if (dfs(dfs, s, -1, false)) {
        std::cout << "Possible\n";

        int cur = s;
        std::vector<int> path;
        while (cur != -1) {
            path.push_back(cur);
            cur = nxt0[cur];
        }

        std::cout << path.size() << '\n';
        for (int i = 0; i < path.size(); ++ i) {
            std::cout << path[i] + 1 << " \n"[i + 1 == path.size()];
        }

        cur = path.back();
        path.clear();
        while (cur != -1) {
            path.push_back(cur);
            cur = nxt1[cur];
        }

        std::reverse(path.begin(), path.end());

        std::cout << path.size() << '\n';
        for (int i = 0; i < path.size(); ++ i) {
            std::cout << path[i] + 1 << " \n"[i + 1 == path.size()];
        }
    } else {
        std::cout << "Impossible\n";
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

#ifdef DEBUG
    int START = clock();
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif

    int t = 1;
    // std::cin >> t;

    while (t --) {
        solve();
    }
#ifdef DEBUG
    std::cerr << "run-time: " << clock() - START << '\n';
#endif
    return 0;
}


http://www.kler.cn/a/395649.html

相关文章:

  • 视频编码基础入门
  • spring boot整合https协议
  • 大模型研究报告 | 2024年中国金融大模型产业发展洞察报告|附34页PDF文件下载
  • 【论文阅读】WaDec: Decompiling WebAssembly Using Large Language Model
  • 单片机设计电流与温度监控python上位机监控平台设计
  • uni-app之数据驱动的picker选择器( uni-data-picker)之可以选择到任意级别
  • ui->tableView升序
  • 自动驾驶3D目标检测综述(二)
  • 安科瑞ARD2F智能型电动机保护器在某水泥厂的应用-安科瑞黄安南
  • 京东 2025届秋招 自然语言处理
  • 为以人工智能为中心的工作负载重新设计的全局控制台
  • 如何在C#中处理必盈接口返回的股票数据?
  • 数据结构与算法:二分搜索/二分查找的python实现与相关力扣题35.搜索插入位置、74.搜索二维矩阵
  • A036-基于SpringBoot的产业园区智慧公寓管理系统
  • Transformer中的算子:其中Q,K,V就是算子
  • MySQL 5.7 源码导读
  • Leecode刷题C语言之最少翻转次数使二进制矩阵回文①
  • Excel SUMIFS
  • 无人机云台基础——CKESC电调小课堂10
  • JsonCpp
  • 【Java Web】MVC与分层开发
  • Gin路由深入
  • STM32芯片EXIT外部中断的配置与原理
  • FPGA 第6讲 简单组合逻辑多路选择器
  • Datawhale模型压缩技术Task2之模型剪枝
  • 基于Java Springboot旅游信息推荐系统