zoukankan      html  css  js  c++  java
  • poj2942 Knights of the Round Table,无向图点双联通,二分图判定

    点击打开链接


    无向图点双联通。二分图判定

    <span style="font-size:18px;">#include <cstdio>
    #include <stack>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    struct Edge{
        int u, v;
    };
    const int maxn = 1005;
    int pre[maxn], iscut[maxn], bccno[maxn],dfs_clock, bcc_cnt;
    vector<int> G[maxn], bcc[maxn];
    
    stack<Edge> S;
    
    int dfs(int u, int fa){
        int lowu = pre[u] = ++dfs_clock;
        int child = 0;
        for(int i=0; i<G[u].size(); ++i){
            int v = G[u][i];
            Edge e = (Edge){u, v};
            if(!pre[v]){
                S.push(e);
                child++;
                int lowv = dfs(v, u);
                lowu = min(lowu, lowv);
                if(lowv>=pre[u]){
                    iscut[u] = true;
                    bcc_cnt++; bcc[bcc_cnt].clear();
                    for(;;){
                        Edge x = S.top(); S.pop();
                        if(bccno[x.u]!=bcc_cnt){
                            bcc[bcc_cnt].push_back(x.u); bccno[x.u] = bcc_cnt;
                        }
                        if(bccno[x.v] != bcc_cnt){
                            bcc[bcc_cnt].push_back(x.v); bccno[x.v] = bcc_cnt;
                        }
                        if(x.u==u && x.v==v) break;
                    }
                }
            }
            else if(pre[v]<pre[u] &&v!=fa){
                S.push(e);
                lowu = min(lowu, pre[v]);
            }
        }
        if(fa < 0 && child == 1) iscut[u] = 0;
        return lowu;
    }
    
    void find_bcc(int n){
        memset(pre, 0, sizeof pre );
        memset(iscut, 0, sizeof iscut );
        memset(bccno, 0, sizeof bccno );
        dfs_clock = bcc_cnt = 0;
        for(int i=0; i<n; ++i)
            if(!pre[i]) dfs(i, -1);
    }
    
    int odd[maxn], color[maxn];
    bool bipartite(int u, int b){
        for(int i=0; i<G[u].size(); ++i){
            int v = G[u][i]; if(bccno[v]!=b)continue;
            if(color[v]==color[u]) return false;
            if(!color[v]){
                color[v] = 3 - color[u];
                if(!bipartite(v, b)) return false;
            }
        }
        return true;
    }
    
    int A[maxn][maxn];
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.cpp", "r", stdin);
        freopen("out.cpp", "w", stdout);
    #endif // ONLINE_JUDGE
        int kase = 0, n, m;
        while(scanf("%d%d", &n, &m)==2 &&n){
            for(int i=0; i<n; ++i)G[i].clear();
            memset(A, 0, sizeof A );
            for(int i=0; i<m; ++i){
                int u, v;
                scanf("%d%d", &u, &v);
                u--; v--;
                A[u][v] = A[v][u] = 1;
            }
            for(int u=0; u<n; ++u)//避免重边
                for(int v=u+1; v<n; ++v)
                    if(!A[u][v]) {
                        G[u].push_back(v);
                        G[v].push_back(u);
                    }
    
            find_bcc(n);
    
            memset(odd, 0, sizeof odd );
            for(int i=1; i<=bcc_cnt; ++i){
                memset(color, 0, sizeof color );
                for(int j=0; j<bcc[i].size(); ++j) bccno[bcc[i][j]] = i;
                int u = bcc[i][0];
                color[u] = 1;
                if(!bipartite(u, i))
                    for(int j=0; j<bcc[i].size(); ++j) odd[bcc[i][j]] = 1;
            }
            int ans = n;
            for(int i=0; i<n; ++i) if(odd[i]) ans--;
            printf("%d
    ", ans);
        }
        return 0;
    }
    </span>


  • 相关阅读:
    #2020征文TV#【鸿蒙基地】鸿蒙从窗口开始:Page Ability诞生记
    设计器打开某表单时提示:[某某表单]已经由用户[xxx]打开需解锁
    有效性设置解疑
    表单打开时显示空白页面解决办法
    工作流_知会设置
    单元格中既有公式又可以录入数据,怎么实现?
    更改系统时间
    下拉框改变后,如何清空后面几个单元格的值?
    如何调整人员的部门?
    如何修改iis访问端口
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5056159.html
Copyright © 2011-2022 走看看