• hdu4587-TWO NODES(割点)


    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 5005;
    const int M = 100010;
    
    struct Edge {
        int to, next;
    } edge[M];
    int head[N];
    int cntE;
    void addedge(int u, int v) {
        edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;
        edge[cntE].to = u; edge[cntE].next = head[v]; head[v] = cntE++;
    }
    
    int dfn[N], low[N], idx;
    int stk[N], top;
    bool cut[N];
    int block[N];
    // 一个割点可能在很多个连通分量
    // 如果一个双连通分量内的某些顶点在一个奇圈中(即双连通分量含有奇圈
    //  那么这个双连通分量的其他顶点也在某个奇圈中
    // 如果一个双连通分量含有奇圈,则他必定不是一个二分图。反过来也成立,这是一个充要条件。
    int no;
    // block[i] 是去掉i这个节点能够多几个联通块
    void tarjan(int u, int fa) {
        dfn[u] = low[u] = ++idx;
        stk[top++] = u;
        block[u] = 0;
        int son = 0;
        for (int i = head[u]; ~i; i = edge[i].next) {
            int v = edge[i].to;
            if (v == fa || v == no) continue;
            if (!dfn[v]) {
                son++;
                tarjan(v, u);
                low[u] = min(low[u], low[v]);
                if (u != fa && low[v] >= dfn[u]) {
                    cut[u] = true;
                    block[u]++;
                }
                /* 求每一个连通分量
                if (low[v] >= dfn[u]) {
    
                    int x;
                    do {
                        x = stk[--top];
                        push(x);
                    } while (x != v);
                    push(u);
                }
                */
            } else {
                low[u] = min(low[u], dfn[v]);
            }
        }
        if (u == fa) {
            if (son > 1) cut[u] = 1;
            block[u] = son-1;
        }
    }
    
    
    void init() {
        memset(dfn, 0, sizeof dfn);
        top = idx = cntE = 0;
    }
    
    int main()
    {
        int n, m;
        while (~scanf("%d%d", &n, &m)) {
            int u, v;
            memset(head, -1, sizeof head);
            for (int i = 0; i < m; ++i) {
                scanf("%d%d", &u, &v);
                addedge(u, v);
            }
            int ans = 0;
            for (u = 0; u < n; ++u) {
                init(); int cnt = 0; no = u;
                for (v = 0; v < n; ++v) {
                    if (v != u && !dfn[v]) {
                        tarjan(v, v);
                        cnt++;
                    }
                }
                for (v = 0; v < n; ++v) {
                    if (v != u) ans = max(ans, cnt + block[v]);
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    mapreduce参数记录
    find命令使用中记录
    运算符的优先级(从高到低)
    常用字符与ASCII代码对照表
    mysql在liunx上使用记录
    Java 流收集器 ( Stream Collectors )
    CDH 删除Agent节点(退役节点)
    学习记录CombineFileInputFormat类
    读取HBases的数据的三种常见用法
    hash算法学习
  • 原文地址:https://www.cnblogs.com/wenruo/p/5884617.html
Copyright © 2020-2023  润新知