# BZOJ1116：[POI2008]CLO & 加强版on Luogu P3465

bzoj没spj，就并查集判一下每个联通块是否有环就好了

Luogu的有spj，这就有点麻烦

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<bitset>
using namespace std;

const int MAXN = 100005, MAXM = 200005;

struct EDGE{
int nxt, to;
EDGE() {nxt = to = 0;}
}edge[MAXM << 1];
int n, m, tot, totedge, getcir;
int fa[MAXN], head[MAXN], deg[MAXN], incir[MAXN], getin[MAXN];
bool has[MAXN], vis[MAXN], def[MAXM << 1];

inline int opp(int x) {
return (x + ((x & 1) ? (1) : (-1)));
}
inline void add(int x, int y) {
edge[++totedge].to = y;
return;
}
int findfa(int x) {
return x == fa[x] ? x : fa[x] = findfa(fa[x]);
}
inline void link(int x, int y) {
int fx = findfa(x), fy = findfa(y);
if(fx == fy) {
has[fx] = has[fy] = true;
return;
}
fa[fx] = fy;
has[fy] = has[fx] = (has[fx] | has[fy]);
return;
}
int dfs(int x, int from) {
if(vis[x]) {
getcir = x;
return x;
}
vis[x] = true;
for(int i = head[x]; i; i = edge[i].nxt) {
int y = edge[i].to;
if(y == from) continue;
incir[x] = dfs(y, x);
if(incir[x] || getcir) break;
}
return (x == incir[x]) ? 0 : incir[x];
}
void efs(int x, int from) {
for(int i = head[x]; i; i = edge[i].nxt) if(!def[i]) {
int y = edge[i].to;
if(y == from) continue;
if(!getin[y]) {
getin[y] = x;
def[i] = def[opp(i)] = true;
efs(y, x);
}
}
return;
}

int main() {
scanf("%d%d", &n, &m);
tot = n;
for(int i = 1; i <= n; ++i) fa[i] = i;
if(m < n) {
puts("NIE");
return 0;
}
register int x, y;
for(int i = 1; i <= m; ++i) {
scanf("%d%d", &x, &y);
}
for(int i = 1; i <= n; ++i) {
fa[i] = findfa(i);
if(!has[fa[i]]) {
puts("NIE");
return 0;
}
}
puts("TAK");
int lastfind = 0;
for(int i = 1; i <= n; ++i) {
if(fa[i] != lastfind) {
lastfind = fa[i];
getcir = 0;
dfs(i, 0);
}
}
lastfind = 0;
for(int i = 1; i <= n; ++i) {
if((incir[i] == i) && (!getin[i])) {
efs(i, 0);
}
}
for(int i = 1; i <= n; ++i) printf("%d\n", getin[i]);
return 0;
}


posted @ 2018-07-15 21:31  AWordThatWeDefine  阅读(109)  评论(0编辑  收藏  举报