http://codeforces.com/contest/982/problem/F
糊了假算法啊.. fst * 2感觉很不好..
标算 也就是乐滋滋的做法 很棒啊
首先两个特判无解
1.原图没有环
2.把原图一个环的点集去掉之后如果还有环
然后把原图中的环扣出来
此时答案的点集是环的点集的子集
考虑一下环上的边产生的贡献
他们都会对使得一段区间\([l, r]\)不能加入到答案内
求出\([l, r]\)的话dp一下就好了
然后我们就打标记把这一段区间删除掉
答案就是没有被删除的点集
复杂度\(O(n + m)\)
#include <bits/stdc++.h>
#define fo(i, n) for(int i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); ++ it)
using namespace std;
#define SZ(x) ((int) (x).size())
#define mem(x, b) memset((x), b, sizeof (x))
typedef long long ll;
#define QAQ cerr << "233\n";
// by piano
template<typename tp> inline void read(tp &x) {
x = 0;char c = getchar(); bool f = 0;
for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
if(f) x = -x;
}
template<typename tp> inline void arr(tp *a, int n) {
for(int i = 1; i <= n; i ++)
cout << a[i] << " ";
puts("");
}
const int N = 3e5 + 233;
int dfn[N], low[N], dfs_clock = 0;
int sccno[N], scc_cnt = 0;
int S[N], top = 0;
vector<int> scc[N], g1[N], g2[N], vec1[N], vec2[N];
int cir[N], num = 0, idx[N], vis[N];
int n, m, st, e_cnt = 0;
pair<int, int> e[N << 2];
inline void link(int x, int y) {
g1[x].push_back(y); g2[y].push_back(x);
}
inline void GG(void) {
puts("-1"); exit(0);
}
inline void tarjan(int u, int fat, int fff) {
dfn[u] = low[u] = ++ dfs_clock; S[++ top] = u;
for(auto v: fff ? g1[u] : vec1[u]) {
if(!dfn[v]) tarjan(v, u, fff), low[u] = min(low[u], low[v]);
else if(!sccno[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]) {
scc[++ scc_cnt].clear();
for(;;) {
int v = S[top --];
sccno[v] = scc_cnt; scc[scc_cnt].push_back(v);
if(v == u) break;
}
}
}
inline int dfs(int u) {
if(vis[u]) return u == st;
cir[++ num] = u; vis[u] = true;
for(auto &v: g1[u]) if(dfs(v)) return true;
-- num;
return false;
}
inline void doit(int fff) {
mem(dfn, 0); mem(low, 0); mem(sccno, 0);
dfs_clock = scc_cnt = top = 0;
int circle_num = 0;
for(int i = 1; i <= n; i ++) if(!dfn[i]) tarjan(i, 0, fff);
for(int i = 1; i <= n; i ++)
if(low[i] == dfn[i] && SZ(scc[sccno[i]]) > 1) {
circle_num ++; st = i;
}
if(circle_num > 1) {
GG();
}
}
namespace solver {
struct NODE {
int mn, mx;
NODE(int _mn = 1e9 ,int _mx = 0) {
mn = _mn; mx = _mx;
}
inline void ovo(void) {
cout << mn << " " << mx << "\n";
}
}F1[N], F2[N];
int cnt[N], vis[N];
inline void dp(void) {
auto ban = [&] (int l, int r) -> void {
if(r > num || l < 1 || l > r) return ;
++ cnt[l]; -- cnt[r + 1];
};
for(int i = 1; i <= num; i ++) {
if(F1[cir[i]].mx >= i) ban(i + 1, F1[cir[i]].mx - 1);
if(F1[cir[i]].mn <= i) ban(i + 1, num);
if(F2[cir[i]].mx >= i) ban(1, i - 1);
}
for(int i = 1; i <= num; i ++) cnt[i] += cnt[i - 1];
for(int i = 1; i <= num; i ++) if(!cnt[i]) {
cout << cir[i] << "\n";
return ;
}
GG();
}
inline void upd(NODE &a, int mn, int mx) {
a.mn = min(a.mn, mn);
a.mx = max(a.mx, mx);
}
inline void dfs1(int u) {
if(vis[u]) return ;
vis[u] = true;
for(auto &v: vec1[u]) {
if(!idx[v]) {
dfs1(v);
upd(F1[u], F1[v].mn, F1[v].mx);
}
else upd(F1[u], idx[v], idx[v]);
}
}
inline void dfs2(int u) {
if(vis[u]) return ;
vis[u] = true;
for(auto &v: vec2[u]) {
if(!idx[v]) {
dfs2(v);
upd(F2[u], F2[v].mn, F2[v].mx);
}
else upd(F2[u], idx[v], idx[v]);
}
}
void main(void) {
mem(vis, 0);
for(int i = 1; i <= n; i ++) dfs1(i);
mem(vis, 0);
for(int i = 1; i <= n; i ++) dfs2(i);
dp();
}
}
main(void) {
read(n); read(m);
for(int i = 1; i <= m; i ++) {
int x, y; read(x); read(y);
link(x, y);
}
doit(1); mem(vis, 0); dfs(st);
fo(i, num) idx[cir[i]] = i;
for(int i = 1; i <= n; i ++)
for(auto &v: g1[i]) {
if(idx[i] && idx[v] == idx[i] % num + 1) continue;
else {
vec1[i].push_back(v);
vec2[v].push_back(i);
}
}
doit(0);
solver::main();
}