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\n", ans);
    }
    return 0;
}
时间: 2024-11-06 09:38:30

hdu4587-TWO NODES(割点)的相关文章

HDU 4587 TWO NODES 割点

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4587 题意: 删除两个点,使连通块的数目最大化 题解: 枚举删除第一个点,然后对删除了第一个点的图跑割点更新答案. 代码: #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> using namespace std; c

双连通问题

一些定义: 割点集合(割集):在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合. 点连通度:最小割点集合中的顶点数. 割边集合:如果有一个边集合,删除这个边集合以后,原图变成多个连通块,就称这个点集为割边集合. 边连通度:最小割边集合中的边数. 点双连通:如果一个无向连通图的点连通度大于1,则称该图是点双连通的,简称双连通或重连通.割点:一个图有割点,当且仅当这个图的点连通度为1,则割点集合的唯一元素被称为

hdu4587 求割点变形

http://acm.hdu.edu.cn/showproblem.php?pid=4587 Problem Description Suppose that G is an undirected graph, and the value of stab is defined as follows: Among the expression,G-i, -j is the remainder after removing node i, node j and all edges that are

HDU 4587 TWO NODES 枚举+割点

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587 TWO NODES Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1448    Accepted Submission(s): 441 Problem Description Suppose that G is an undir

HDOJ 题目4587 TWO NODES(双联通,割点,枚举)

TWO NODES Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1367    Accepted Submission(s): 410 Problem Description Suppose that G is an undirected graph, and the value of stab is defined as fo

SPF(poj 1523) 割点入门

1 /***************************************** 2 SPF(poj 1523) 3 割点入门 4 http://poj.org/problem?id=1523 5 6 ******************************************/ 7 8 #include<iostream> 9 #include<algorithm> 10 #include<cstdio> 11 #include<cstring&

HDU 4587 无向图的割点

TWO NODES Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1137    Accepted Submission(s): 333 Problem Description Suppose that G is an undirected graph, and the value of stab is defined as fol

【POJ 1523】SPF(割点)

儿子数大于1的树根或者 Low[v] >= DFN[u]的非树根节点v 就是割点. #include <cstdio> #include <cstring> const int N = 1001; const int M = 1000010; struct Edge { int to,next; bool cut;//是否为桥的标记 }edge[M]; int head[N],tot; int Low[N],DFN[N],Stack[N]; int Index,top; bo

POJ1523 SPF(割点)

题目求一个无向图的所有割点,并输出删除这些割点后形成几个连通分量.用Tarjan算法: 一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边). 顺便求出每个结点的DFS序dfn[u] 和 每个结点能沿着它和它的儿子的返祖边达到的结点最小的DFS序low[u]. 一个点是割点当且仅当—— 这个点是生成树的根,且有x(x>=2)个的子树,删除这个点后就形成x个连通分量. 这个点不是树根,且其存在x(x>=1)个儿子的low值小于等于该点的d