hdu4635强连通

这个题的意思是一个有向图,你最多能加多少条边,它还不会是强连通图,加的边不能有重边。只需这个图变成两个强连通,而且是一个连通分量只能指向另一个连通分量,可以先缩点。

真心没想到

#include<iostream>
using namespace std;
const int N=100010;
struct node
{
    int to,next;
}edge[N];
int head[N],dfn[N],low[N],belong[N],in[N],out[N],num[N];
int tot,index,top,color,n;
int sta[N],instack[N];
__int64 ans;
void add(int a,int b)
{
    edge[tot].to=b;
    edge[tot].next=head[a];
    head[a]=tot++;
}
int min(int a,int b)
{
    if(a<b)return a;
    return b;
}
void tarjan(int u)
{
    int i;
    dfn[u]=low[u]=++index;
    sta[top++]=u;
    instack[u]=1;
    for(i=head[u];i+1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }else
            if(instack[v])
                low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        color++;
        int v;
        do
        {
            v=sta[--top];
            instack[v]=0;
            belong[v]=color;
            num[color]++;
        }while(v!=u);
    }
}
void init()
{
    for(int i=0;i<=n;i++)
    {
        instack[i]=0;
        head[i]=-1;
        dfn[i]=0;
        in[i]=0;
        num[i]=0;
        out[i]=0;
    }
    tot=top=index=color=ans=0;
}
__int64 max(__int64 a,__int64 b)
{
    if(a>b)return a;
    return b;
}
int main()
{
    int m,a,b,i,t,j,cas=0;
    scanf("%d",&t);
    while(cas<t)
    {
        scanf("%d%d",&n,&m);
        init();
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        for(i=1;i<=n;i++)
            if(!dfn[i])
                tarjan(i);
            printf("Case %d: ",cas+1);
            
            if(color==1)
            {
                printf("%d\n",-1);
                cas++;
                continue;
            }
            for(i=1;i<=n;i++)
            {
                for(j=head[i];j+1;j=edge[j].next)
                {
                    int v=edge[j].to;
                    if(belong[i]!=belong[v])
                    {
                        in[belong[v]]++;
                        out[belong[i]]++;
                    }
                }
            }
            __int64 sum=(__int64)n*(n-1)-m;
            
            
            for(i=1;i<=color;i++)
            {
                if(in[i]==0||out[i]==0)
                {
                    ans=max(ans,sum-(__int64)num[i]*(n-num[i]));
                }
            }
            printf("%I64d\n",ans);
            cas++;
    }
    return 0;
}

 

posted on 2013-08-01 21:09  黎昊明  阅读(185)  评论(0编辑  收藏  举报

导航