• 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
    ",-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
    ",ans);
                cas++;
        }
        return 0;
    }
  • 相关阅读:
    五一集训——图论
    Luogu P3942 将军令
    8.14 Round 1
    8.10 Round 1
    8.9 Round 1
    8.7 Round 2
    8.7 Round 1
    8.6 Round 1
    8.5 Round 2
    FHQ-Treap
  • 原文地址:https://www.cnblogs.com/BruceNoOne/p/3231244.html
Copyright © 2020-2023  润新知