• HDU 4635 Strongly connected


    14:

        关键字 强联通

                题目求最多加多少条边使图不不再是一个强联通

    我们逆向思维:

    先假设n*(n-1)边 那么一定强联通 ,问最少减去多少条边 不再联通

    那么只要枚举一个联通块就可以

    因为其他边肯定与他有联系

    CODE:

    #pragma comment(linker,"/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<stack>
    using namespace std;
    
    const int N=200010;
    const int M=1000020;
    struct node
    {
        int v,next;
    }e[M*2];
    
    int head[N];
    int dfn[N],low[N],dp[N][2];
    int vis[M];
    int n,m,cnt,ans;
    
    void add(int u,int v)
    {
        e[cnt].v=v;
        e[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void dfs(int u)
    {
        dfn[u]=low[u]=cnt++;
        dp[u][0]=dp[u][1]=0;
        for (int i=head[u];i!=-1;i=e[i].next)
        {
            int j=e[i].v;
            if (!vis[i>>1])
            {
                vis[i>>1]=1;
                if (dfn[j]==0)
                {
                    dfs(j);
                    ans+=dfn[u]<low[j];
                    int tmp=dp[j][0]+(dfn[u]<low[j]);
                    if (tmp>dp[u][0]){
                    dp[u][1]=dp[u][0],dp[u][0]=tmp;}
                    else
                    if (tmp>dp[u][1]) dp[u][1]=tmp;
                    low[u]=min(low[u],low[j]);
                }
            else low[u]=min(low[u],dfn[j]);
        }
       }
    }
    int main()
    {
        while (scanf("%d%d",&n,&m))
        {
            if (n==0&&m==0) break;
            cnt=ans=0;
            memset(head,-1,sizeof(head));
            memset(low,0,sizeof(low));
            memset(dfn,0,sizeof(dfn));
            while (m--)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
            }
            cnt=1;
            memset(vis,0,sizeof(vis));
            dfs(1);
            int tmp=0;
            for (int i=1;i<=n;i++)
            tmp=max(tmp,dp[i][0]+dp[i][1]);
            printf("%d
    ",ans-tmp);
        }
        return 0;
    }
    

      

  • 相关阅读:
    【Java】快速排序、归并排序、堆排序、基数排序实现总结
    【Java】二分查找、插值查找、斐波那契查找的实现,及分析
    【Java】Java实现常见的七种排序
    【C】常见的排序
    栈,迷宫问题
    海量数据处理问题
    【C】 布隆过滤器BloomFilter
    哈希变形---位图
    C实现Hash表,链式结构
    C实现Hash表,开放定址法
  • 原文地址:https://www.cnblogs.com/forgot93/p/4295607.html
Copyright © 2020-2023  润新知