zoukankan      html  css  js  c++  java
  • 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;
        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
    ", getin[i]);
        return 0;
    }
    
    禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载 ,用户转载请注明出处:https://www.cnblogs.com/xcysblog/
  • 相关阅读:
    053573
    053572
    053571
    053570
    053569
    053568
    Android:你好,androidX!再见,android.support
    最新Androidx Fragment的前世今生系列(一)之Fragment的简单使用
    Android开发中如何匹配layout资源(layoutsw480dp layoutsw600dpland layoutsw720dpport)
    Android:Fragment最全面介绍 & 使用方法解析
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9314899.html
Copyright © 2011-2022 走看看