• HDU4635 Strongly connected


    给定一个有向图 
    求最多可以加多少条边 使加了边以后还是一个有向图而不是强联通图 
    由于不是一个强连通图,那么至少要有两个连通块。 
    也就是只有两个连通块时,加的边是最多的。 
    设有两个连通块 
    一个里有x个点,另一个里有个y个点 
    则第一个连通块中的路最多可以使x*(x-1) 
    第二个连通块中的路最多可以使y*(y-1) 
    两个连通块之间的路最多可以是(x*y) 
    那么一共可以连成x * (x-1)+y * (y-1)+x*y条边 
    又因为x+y=n 
    那么化简以后就是n*n-n-x*y 
    那么当x或y是0时 才有可能是答案 
    也就是找出入度或者出度是0的连通块 
    然后在减去一开始已经存在m条路 
    找出max(n*n+n-x*y-m)就是答案

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn = 100005;
    const int maxm = 100005;
    int n, m;
    int top, tol, cnt;
    int stacksize;
    
    struct Node{
        int u;
        int v;
        int next;
    };
    Node node[maxm];
    int dfn[maxn];
    int low[maxn];
    int vis[maxn];
    int num[maxn];
    int indi[maxn];
    int oudi[maxn];
    int head[maxn];
    int stack[maxn];
    int point[maxn];
    
    void init() {
        tol = top = stacksize = cnt = 0;
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
        memset(num, 0, sizeof(num));
        memset(indi, 0, sizeof(indi));
        memset(oudi, 0, sizeof(oudi)); 
        memset(node, 0, sizeof(node));
        memset(head, -1, sizeof(head));
        memset(vis, false, sizeof(vis));
        memset(point, 0, sizeof(point));
        memset(stack, 0, sizeof(stack));
    }
    
    void addnode(int u, int v) {
        node[tol].u = u;
        node[tol].v = v;
        node[tol].next = head[u];
        head[u] = tol++;
    }
    
    void dfs(int u) {
        int v;
        dfn[u] = low[u] = ++cnt;
        stack[stacksize++] = u;
        vis[u] = true;
        for(int i=head[u]; i!=-1; i=node[i].next) {
            v = node[i].v;
            if(!dfn[v]) {
                dfs(v);
                low[u] = min(low[u], low[v]);
            } else if(vis[v]) {
                low[u] = min(low[u], dfn[v]);
            }
        }
        if(low[u] == dfn[u]) {
            top++;
            do{
                v = stack[--stacksize];
                vis[v] = false;
                num[top]++;
                point[v] = top;
            } while(v != u);
        }
    }
    
    void tarjan() {
        for(int i=1; i<=n; i++) {
            if(!dfn[i]) {
                dfs(i);
            }
        }
    }
    
    int solve() {
        for(int u=1; u<=n; u++) {
            for(int i=head[u]; i+1; i=node[i].next) {
                int v = node[i].v;
                if(point[u] != point[v]) {
                    oudi[point[u]]++;
                    indi[point[v]]++;
                }
            }
        }
        int ans = 0;
        for(int i=1; i<=top; i++) {
            if(!oudi[i] || !indi[i]) {
                ans = max(ans, n*n-n-m-(n-num[i])*num[i]);
            }
        }
        return ans;
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        int cas = 1;
        while(T--) {
            init();
            scanf("%d%d", &n, &m);
            for(int i=0; i<m; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                addnode(u, v);
            }
            tarjan();
            if(top == 1) {
                printf("Case %d: -1
    ", cas++);
            } else {
                int ans = solve();
                printf("Case %d: %d
    ", cas++, ans);
            }
        }
    }
    View Code
  • 相关阅读:
    [译]Vulkan教程(09)窗口表面
    [译]Vulkan教程(08)逻辑设备和队列
    [译]Vulkan教程(07)物理设备和队列家族
    Linux命令行文本工具
    go语言周边
    go第三方常用包
    Centos6安装gcc4.8及以上版本
    pyenv设置python多版本环境
    Redis慢日志
    PHP-CPP开发扩展(七)
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/9148314.html
Copyright © 2020-2023  润新知