BZOJ1116:[POI2008]CLO && 加強版on Luogu P3465
阿新 • • 發佈:2018-07-15
clas ted 一個 cor ont continue 有環 bzoj poi
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; edge[totedge].nxt = head[x]; head[x] = totedge; 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); add(x, y); add(y, x); link(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; }
BZOJ1116:[POI2008]CLO && 加強版on Luogu P3465