zoukankan      html  css  js  c++  java
  • HDU 4587 TWO NODES(割点)(2013 ACM-ICPC南京赛区全国邀请赛)

    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 directly relevant to the previous two nodes. cntCompent is the number of connected components of X independently.  Thus, given a certain undirected graph G, you are supposed to calculating the value of stab.
     

    Input

    The input will contain the description of several graphs. For each graph, the description consist of an integer N for the number of nodes, an integer M for the number of edges, and M pairs of integers for edges (3<=N,M<=5000).  Please note that the endpoints of edge is marked in the range of [0,N-1], and input cases ends with EOF.
     

    Output

    For each graph in the input, you should output the value of stab.

    题目大意:给一个n个点m条边的无向图,删掉任意两个点,求最大联通分量数。

    思路:枚举要被删掉的第一个点,然后用tarjan求剩下的每一个点被删掉后能增加的联通分量数。根据dfs的性质,有多少个分支的lowu ≥ pre[u],删掉u后就有多少个联通分量,删掉第一个点的时候剩下的块数加上删掉第二个点的联通分量数,就是删掉第一个点可以获得的最大连通分量数。要注意的是,如果要删掉的点是一个孤立的点,那么它的连通分量数反而会减少。时间复杂度为O(nm),12S可以承受。

    代码(5000MS):

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 const int MAXN = 5010;
     8 const int MAXE = MAXN * 2;
     9 
    10 int head[MAXN];
    11 int to[MAXE], next[MAXE];
    12 int pre[MAXN], cut[MAXN];
    13 int n, m, dfs_clock, ecnt, stab;
    14 
    15 void init() {
    16     memset(head, 0, sizeof(head));
    17     ecnt = 1;
    18 }
    19 
    20 void add_edge2(int u, int v) {
    21     to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
    22     to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++;
    23 }
    24 
    25 int del;
    26 
    27 int dfs(int u, int fa) {
    28     int lowu = pre[u] = ++dfs_clock;
    29     for(int p = head[u]; p; p = next[p]) {
    30         int &v = to[p];
    31         if(v == del) continue;
    32         if(!pre[v]) {
    33             int lowv = dfs(v, u);
    34             lowu = min(lowu, lowv);
    35             if(lowv >= pre[u]) ++cut[u];
    36         } else if(pre[v] < pre[u] && v != fa) {
    37             lowu = min(lowu, pre[v]);
    38         }
    39     }
    40     if(fa < 0) --cut[u];
    41     return lowu;
    42 }
    43 
    44 int main() {
    45     while(scanf("%d%d", &n, &m) != EOF) {
    46         init();
    47         while(m--) {
    48             int a, b;
    49             scanf("%d%d", &a, &b);
    50             add_edge2(a, b);
    51         }
    52         stab = 0;
    53         for(int i = 0; i < n; ++i) {
    54             del = i;
    55             int sum = 0;
    56             memset(pre, 0, sizeof(pre));
    57             memset(cut, 0, sizeof(cut));
    58             dfs_clock = 0;
    59             for(int u = 0; u < n; ++u) {
    60                 if(u == i || pre[u]) continue;
    61                 ++sum;
    62                 dfs(u, -1);
    63             }
    64             int maxcut = -1;
    65             for(int u = 0; u < n; ++u) if(u != i)
    66                 maxcut = max(maxcut, cut[u]);
    67             stab = max(stab, sum + maxcut);
    68         }
    69         printf("%d
    ", stab);
    70     }
    71 }
    View Code
  • 相关阅读:
    js 遍历数组对象求和
    小程序使用微信地址or小程序跳转设置页
    css内容渐入效果实现
    flutter实现文字超出最大宽度显示省略号
    flutter查看安全码SHA1
    Uncaught (in promise)
    小程序iphone蒙层滚动穿透
    map中使用箭头函数遇到的坑
    骨架屏css样式
    javascript(js)反转字符串
  • 原文地址:https://www.cnblogs.com/oyking/p/3279514.html
Copyright © 2011-2022 走看看