• 【图论好题】ABC #142 Task F Pure


    题目大意

    给定一个 $N$ 个点 $M$ 条边的有向图 $G$,无重边、自环。找出图 $G$ 的一个导出子图(induced subgraph) $G'$,且 $G'$ 中的每个点的入度和出度都是 1。

    数据范围

    • $ 1 le N le 1000$
    • $ 0 le M le 2000$

    分析

    导出子图 $G'$ 中的每个点的入度和出度都是 1 相当于说 $G'$ 是一个(cycle)。

    若不考虑 $G'$ 是导出子图这个条件,则可通过 DFS 判断图 $G$ 中是否有环,若有,同时还可以找出一个环。

    下面给出环的一个性质:
    若有向图 $C$ 是一个环,则往 $C$ 中添一条边将产生一个更小的环。

    读者自证不难。

    因此若有向图 $G$ 中有环,则 $G$ 中的最小环必然是 $G$ 的导出子图。

    于是原问题可以转化成求图 $G$ 中的最小环。

    更进一步,可以先在图 $G$ 上 DFS,找出一个环 $C$,设 $C$ 的点集是 $V_C$;接着在由 $V_C$ 导出的子图 $G_C$ 上找一个最小环 $C'$,则 $C'$ 是 $G_C$ 的导出子图,从而也是 $G$ 的导出子图。

    上述论证用到了导出子图的一个性质:
    若 $B$ 是 $A$ 的导出子图,$C$ 是 $B$ 的导出子图,则 $C$ 也是 $A$ 的导出子图。

    Implementation

    下列代码是最暴力的实现。

    int n, m; scan(n, m);
    if (n == 1) {
        println(-1);
        return 0;
    }
    
    vv<int> g(n);
    rep (m) {
        int a, b; scan(a, b); --a, --b;
        g[a].pb(b);
    }
    
    vb used(n);
    vb vis(n);
    int lim;
    int root;
    bool flag;
    
    function<void(int,int)> dfs = [&](int u, int d) {
        vis[u] = true;
        if (d == lim) {
            FOR (v, g[u]) {
                if (v == root) {
                    flag = true;
                    println(d + 1);
                    break;
                }
            }
        }
        else {
            FOR (v, g[u]) {
                if (!vis[v] && !used[v]) {
                    dfs(v, d + 1);
                    if (flag) break; // 别忘了这里的 break
                }
            }
        }
        if (flag) println(u + 1);
    };
    
    for (lim = 1; lim < n; ++lim) {
        fill(all(used), false);
        rng (i, 0, n) {
            fill(all(vis), false);
            flag = false;
            root = i;
            dfs(i, 0);
            if (flag) {
                return 0;
            }
            used[i] = true;
        }
    }
    
    println(-1);
    
  • 相关阅读:
    join_tab计算代价
    outer join test
    突然觉得mysql优化器蛮简单
    将数据库字段从float修改为decimal
    小米初体验
    简述安装android开发环境
    Rust语言:安全地并发
    awk里的各种坑
    ubuntu下使用C语言开发一个cgi程序
    Ubuntu下安装和配置Apache2
  • 原文地址:https://www.cnblogs.com/Patt/p/11605688.html
Copyright © 2020-2023  润新知