1. 程式人生 > >BZOJ1116:[POI2008]CLO && 加強版on Luogu P3465

BZOJ1116:[POI2008]CLO && 加強版on Luogu P3465

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