zoukankan      html  css  js  c++  java
  • HDU

    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.

    InputThe 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.OutputFor each graph in the input, you should output the value of stab.Sample Input

    4 5
    0 1
    1 2
    2 3
    3 0
    0 2

    Sample Output

    2

    题意:
    问删除两个点后最大的联通块个数
    思路:
    没想到是一个暴力题,看了一下数据范围才反应过来.
    题目既然要删除两个点,那就先枚举删除第一个点,再用割点判断第二个点删除后的联通块个数即可.
    当然,有几点要注意一下:
    1.联通块中点的个数全为1:
    数据: 8 0
    2.联通块中没有割点
     数据:
      3 3
      0 1
      0 2
      1 3

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    
    #define fuck(x) cerr<<#x<<" = "<<x<<endl;
    #define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
    #define ls (t<<1)
    #define rs ((t<<1)|1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 100086;
    const int maxm = 100086;
    const int inf = 0x3f3f3f3f;
    const ll Inf = 999999999999999999;
    const int mod = 1000000007;
    const double eps = 1e-6;
    const double pi = acos(-1);
    
    int Head[maxn], cnt;
    struct edge {
        int Next, v;
    } e[maxm];
    
    void add_edge(int u, int v) {
        e[cnt].Next = Head[u];
        e[cnt].v = v;
        Head[u] = cnt++;
    }
    
    int Index = 0;
    int dfn[maxn], low[maxn], root;
    int vis[maxn];
    
    int exc;
    int ans;
    int flag;
    void dfs(int cur, int father) {
        if(cur==exc){ return;}
        flag++;
        int child = 0;
        Index++;
        dfn[cur] = Index;
        low[cur] = Index;
        for (int k = Head[cur]; k != -1; k = e[k].Next) {
            if(e[k].v==exc){ continue;}
            if (dfn[e[k].v] == 0) {
                child++;
                dfs(e[k].v, cur);
                low[cur] = min(low[cur], low[e[k].v]);
                if (cur != root && low[e[k].v] >= dfn[cur]) {
                    vis[cur]++;
                }
                if (cur == root && child >= 2) {
                    vis[cur]++;
                }
            } else if (e[k].v != father) {
                low[cur] = min(low[cur], dfn[e[k].v]);
            }
        }
    }
    
    
    int main() {
    //    ios::sync_with_stdio(false);
    //    freopen("in.txt", "r", stdin);
    
        int n,m;
        while (scanf("%d%d",&n,&m)!=EOF) {
            memset(Head, -1, sizeof(Head));
            cnt=0;
            for (int i = 1; i <= m; i++) {
                int x, y;
                scanf("%d%d", &x, &y);
                add_edge(x + 1, y + 1);
                add_edge(y + 1, x + 1);
            }
    
            int mx = 0;
            for (int i = 1; i <= n; i++) {
                exc = i;
                ans = 0;
                memset(vis, 0, sizeof(vis));
                memset(dfn, 0, sizeof(dfn));
                Index=0;
                dfn[exc]=-1;
                int tmp = -1;
                for (int j = 1; j <= n; j++) {
                    if (!dfn[j] && j != i) {
                        root = j;
                        flag=0;
                        dfs(j, j);
                        if(flag>1){
                            tmp=0;//如果联通块内只有一个点,那么删除这个点之后,会使联通块少一
                            //所以至少保证有一个联通块内部包含了两个点,否则答案要减一
                        }
                        ans++;//已有的联通块
                    }
                }
    
                for (int j = 1; j <= n; j++) {
                    if(vis[j])tmp=max(tmp,vis[j]);//删去割点之后,可以获得的联通块
                }
                mx = max(ans+tmp, mx);
            }
            printf("%d
    ", mx );
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ASP.NET请求管道、应用程序生命周期、整体运行机制
    PHP面试总结
    ASP.NET MVC源码分析系列
    SQL中的重要语句
    Nicescroll滚动条插件的用法
    Nunit2.5.10快速上手(笔记)
    ucore 源码剖析
    《ucore lab8》实验报告
    《ucore lab7》实验报告
    《ucore lab6》实验报告
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/11194806.html
Copyright © 2011-2022 走看看