効果の対象に
重いエッジ点ループバックの$ $ 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);