zoukankan      html  css  js  c++  java
  • hdu 4635 Strongly connected 强连通缩点

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635

    题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来就是强连通图,输出-1即可;

    思路:最后得到的图肯定分为两部分x和y,且两部分均为强连通分量,要么x的点到y的所有点有边,要么,从y的所有点到x的所有点有边;(其中只有入度或出度为0的点才可能成为x或y

    则有         x+y=n 

    答案为 ans = y*(y-1) + x*(x-1)+ y*x - m;

    化简后 ans = n*n - n -n*x - x*x - m;

    由以上化简试,x越小,ans值越大(答案最多为一百亿,long long 之)

    #include "stdio.h"  //hdu 4635 强连通缩点
    #include "string.h"
    #include "vector"
    #include "stack"
    using namespace std;
    
    #define N 201000
    #define INF 0x3fffffff
    
    long long n,m;
    int time;
    stack<int> q;
    int dfn[N],low[N];
    int MIN(int x,int y) { return x<y?x:y; }
    long long MAX(long long x,long long y) { return x>y?x:y; }
    
    struct node
    {
        int x,y;
        int next;
    }edge[2*N];
    int idx,head[N];
    
    bool vis[N];
    
    void Init()
    {
        idx=0;
        memset(head,-1,sizeof(head));
    }
    
    void Add(int x,int y)
    {
        edge[idx].x = x;
        edge[idx].y = y;
        edge[idx].next = head[x];
        head[x] = idx++;
    }
    
    int countt;  //统计缩点个数
    int num[N];  //统计每个缩点内的点的个数
    int ru_du[N],chu_du[N];  //统计缩点的出,入度
    int belong[N]; //标记点属于哪个缩点
    
    void DFS(int x)
    {
        int i,y;
        q.push(x);
        vis[x] = true;
        dfn[x] = low[x] = ++time;
        for(i=head[x]; i!=-1; i=edge[i].next)
        {
            y = edge[i].y;
            if(!dfn[y])
            {
                DFS(y);
                low[x] = MIN(low[x],low[y]);
            }
            else if(vis[y])   //强双连通图出现的新判断条件
                low[x] = MIN(dfn[y],low[x]);
        }
        if(low[x]==dfn[x])
        {
            int temp;
            countt++;
            while(1)
            {
                temp = q.top();
                q.pop();
                belong[temp] = countt;
                num[countt]++;
                vis[temp] = false;  //还原了~
                if(temp==x) break;
            }
        }
    }
    
    long long Solve()
    {
        int i;
        int x,y;
        time = countt = 0;
        memset(dfn,0,sizeof(dfn));
        memset(num,0,sizeof(num));
        memset(belong,0,sizeof(belong));
        memset(vis,false,sizeof(vis));
        for(i=1; i<=n; ++i)
        {
            if(!dfn[i])
                DFS(i);
        }
        if(countt==1) return -1;
        memset(ru_du,0,sizeof(ru_du));
        memset(chu_du,0,sizeof(chu_du));
        for(i=0; i<idx; ++i)
        {
            x = edge[i].x;
            y = edge[i].y;
            if(belong[x]!=belong[y])
            {
                chu_du[belong[x]]++;
                ru_du[belong[y]]++;
            }
        }
        long long ans=0,mint;
        for(i=1; i<=countt; ++i)
        {
            if(chu_du[i]==0 || ru_du[i]==0){
                mint = num[i];
                ans = MAX(ans,n*n-n-mint*(n-mint)-m);
            }
        }
        return ans;
    }
    
    int main()
    {
        int T,Case=0;
        int i;
        int x,y;
        scanf("%d",&T);
        while(T--)
        {
            Init();
            Case++;
            scanf("%lld %lld",&n,&m);
            for(i=0; i<m; ++i)
            {
                scanf("%d %d",&x,&y);
                Add(x,y);
            }
            printf("Case %d: ",Case);
            printf("%lld
    ",Solve());
        }
    }
    



  • 相关阅读:
    【STM32F429】第6章 RL-USB调试组件使用方法(重要)
    【STM32F407】第6章 RL-USB调试组件使用方法(重要)
    IAR9.10下载(2021-02-23)
    【STM32H7】第5章 RL-USB协议栈移植(MDK AC6)
    【STM32F429】第5章 RL-USB移植(MDK AC6)
    【STM32F407】第5章 RL-USB移植(MDK AC6)
    【STM32H7】第4章 RL-USB移植(MDK AC5)
    【STM32F429】第4章 RL-USB移植(MDK AC5)
    【STM32F407】第4章 RL-USB移植(MDK AC5)
    【STM32H7】第3章 RL-USB协议栈介绍
  • 原文地址:https://www.cnblogs.com/ruo-yu/p/4411968.html
Copyright © 2011-2022 走看看