abc142_f
質問の説明の意味:
所与の\(\ N-)点、\(m個\)をエッジがグラフ指向している((N \ル1000 \ \)\ル2000メートル)を
度の各点のうちサブグラフはに等しくなるように、サブグラフを探す(1 \)\
それも外方側にリング、リングのみポイントを見つけることです
出力プログラム
正解 :
ハンドプレイどんな発見が第一のリングを見つけることができます
リングの内側エッジ、リングが出したとしても、すべてのポイントは、リング内の程度に縮小されていますされている\(1 \)
縮合環シミュレーションプロセス、限りループに見られるように見つけるために最小のリングをすることができます
次いで、使用BFSは有向ツリー、押収された最初の隔世遺伝エッジ答えであっても最小環の2点を、
その後、あなたはパスで(前駆体)を事前に何を覚えることができる、解決策を探します
DFSも持つシーンがあったが、dqkハックされます
コード:
/*
bfs 找环
*/
#include <bits/stdc++.h>
#define N 1005
#define M 2005
using namespace std;
int n, m;
int dep[N];
int head[N], nex[M], to[M], e;
int stk[N], top;
bool instack[N], vis[N], G[N][N];
vector<int> res;
inline int Rd() {
int x = 0; char ch = getchar();
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return x;
}
inline void Ae(int u, int v) {
nex[++e] = head[u], head[u] = e;
to[e] = v;
}
void calc(int u, int v) {
do {
res.push_back(stk[top]);
} while(stk[top--] != v);
int ans = res.size();
printf("%d\n", ans);
for(int i = 0; i < ans; ++i) printf("%d\n", res[i]);
exit(0);
}
void dfs(int u) {
stk[++top] = u;
instack[u] = vis[u] = true;
for(int i = head[u]; i; i = nex[i]) {
int v = to[i];
if(vis[v]) {
if(instack[v]) calc(u, v);
} else {
dfs(v);
}
}
instack[u] = false, --top;
return;
}
int main() {
n = Rd(), m = Rd();
for(int i = 1; i <= m; ++i) {
int u = Rd(), v = Rd();
G[u][v] = true;
Ae(u, v);
}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
if(G[i][j] && G[j][i]) {
puts("2");
printf("%d\n%d\n", i, j);
return 0;
}
}
}
for(int i = 1; i <= n; ++i)
if(!vis[i])
dfs(i);
puts("-1");
return 0;
}