[グラフ理論、良いタイトル] ABCの#142タスクFピュア

効果の対象に

重いエッジ点ループバックの$ $ N $ M $縁なし、有向グラフGの$ $与えられます。$ G $ののグラフ検索サブグラフ(誘発部分グラフ)$ G「$ 、すべての$ 1と$ G」度と各点のうちを。

データ範囲

  • $ 1 \ N \ル$ 1000
  • $ \ 2000 $ 0 \ M

分析

部分グラフ$ G $で「度$ 1の各点のうち$ Gと言うと等価である」は、ループ(サイクル)。

かかわらず、$ G「$は、この条件があれば、図DFS $ Gの$を介してリングするかどうかを決定することができるだけでなく、リングを特定することができるサブグラフです。

所与の環の以下の特性:
有向グラフの$ Cの$シクロアルキルがある場合、$ C $エッジに追加する小さなリングを生成します。

読者の証人は難しいことではありません。

有向グラフ$ Gの$リングが存在する場合したがって、最小リングの次に$ G $は$ G $誘導されるサブグラフでなければなりません。

したがって、元の問題は、図$ G $を求める最小環に変換することができます。

それはDFSリングの$ C $を見つけることが可能ですさらに、$ C $の設定点セットが$ $ V_Cであり、その後、V_C $ $ $ g_c派生サブマップ上で最も最小限のリング$ C「$ $を見つけ、 $ C「$ $ $のg_c誘導されるサブグラフは、それによってGがサブグラフを$$します。

誘導された部分グラフの特性は、上記使用実証:
$ B $ $ A $はサブグラフである場合、$ C $ $ B $は$ C $ $ A $はサブグラフを誘導し、次いで、サブグラフです。

実装

次のコードは、暴力の実現です。

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);

おすすめ

転載: www.cnblogs.com/Patt/p/11605688.html
おすすめ