zoukankan      html  css  js  c++  java
  • HDU 4635 Strongly connected 强连通分量

    参考:http://www.cnblogs.com/jackge/p/3231767.html 讲的很好

    感悟:最好的情况肯定是完全图,但是不允许,所以一定是有些符合u->v,但是v不能到u,

             在保证这样的情况,最大化边数,最终会形成两个图,然后应用不等式

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <utility>
    using namespace std;
    typedef long long LL;
    const int N=1e5+5;
    const int INF=0x3f3f3f3f;
    struct Edge{
       int u,v,next;
    }edge[N];
    int head[N],tot,n,m;
    void add(int u,int v){
        edge[tot].u=u;
        edge[tot].v=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    stack<int>s;
    bool instack[N];
    int dfn[N],low[N],clk,cnt,bel[N],in[N],out[N],bcc[N];
    void targin(int u){
       dfn[u]=low[u]=++clk;
       instack[u]=true;s.push(u);
       for(int i=head[u];~i;i=edge[i].next){
           int v=edge[i].v;
           if(!dfn[v]){
              targin(v);
              low[u]=min(low[u],low[v]);
           }
           else if(instack[v])
            low[u]=min(low[u],dfn[v]);
       }
       if(low[u]==dfn[u]){
         ++cnt;int k;
         do{
            k=s.top();
            s.pop();
            instack[k]=false;
            bel[k]=cnt;++bcc[cnt];
         }while(k!=u);
       }
    }
    int main()
    {
        int T,cas=0;
        scanf("%d",&T);
        while(T--){
          printf("Case %d: ",++cas);
          scanf("%d%d",&n,&m);
          for(int i=1;i<=n;++i){
            head[i]=-1;dfn[i]=0;instack[i]=false;
            bcc[i]=0;
          }
          clk=cnt=tot=0;
          for(int i=1;i<=m;++i){
             int u,v;
             scanf("%d%d",&u,&v);
             add(u,v);
          }
          for(int i=1;i<=n;++i)
            if(!dfn[i])targin(i);
          if(cnt==1){
            printf("-1
    ");continue;
          }
          for(int i=1;i<=cnt;++i)in[i]=out[i]=0;
          for(int i=0;i<tot;++i){
            int u=bel[edge[i].u],v=bel[edge[i].v];
            if(u==v)continue;
            ++out[u];++in[v];
          }
          int ans=INF;
          for(int i=1;i<=cnt;++i)
            if(!in[i]||!out[i])ans=min(ans,bcc[i]);
          LL aim=1ll*n*(n-1)-1ll*ans*(n-ans)-m;
          printf("%I64d
    ",aim);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    C# 关键字 之 virtual
    Set NOCOUNT 和 SET XACT_ABORT
    radl+ReportViewer (转)
    销售利润分析案例
    实现动态展现报表:2种开发思路
    jdk,tomcat,myecplise程序安装步骤
    BI报表工具选型的整理总结
    MyEclipse 快捷键
    oracle biee
    跨数据库
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5499957.html
Copyright © 2011-2022 走看看