HDU 4635 Strongly connected 强连通分量

Posted shuguangzw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\\n");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\\n",aim);
    }
    return 0;
}
View Code

 

以上是关于HDU 4635 Strongly connected 强连通分量的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4635 Strongly connected 强连通分量

hdu 4635 Strongly connected (tarjan)

HDU 4635 Strongly connected (有向图的强连通分量)

HDU 4635 Strongly connected (Tarjan+一点数学分析)

HDU 4635 Strongly connected (强连通分量+缩点)

HDU 4635 Strongly connected(强连通分量缩点+数学思想)