• hdu 4635 Strongly connected 强连通分量


    http://acm.hdu.edu.cn/showproblem.php?pid=4635

    强连通分量缩点之后+简单计算,具体见代码

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 100100;
    struct Edge {
        int v , next;
        Edge () {}
        Edge (int v ,  int next) : v(v) , next(next) {};
    }edge[maxn<<1];
    int E , head[maxn];
    int n , m;
    void init() {
        E = 0; memset(head,-1,sizeof(int) * (n+1));
    }
    void addedge(int u,int v) {
        edge[E] = Edge(v , head[u]); head[u] = E++;
    }
    int idx , cnt ;
    int dfn[maxn] , low[maxn] , id[maxn];
    int sta[maxn] , top;
    bool ins[maxn];
    void tarjan(int u) {
        dfn[u] = low[u] = ++ cnt;
        sta[++top] = u;
        ins[u] = true;
        int v;
        for(int i=head[u];i!=-1;i=edge[i].next) {
            v = edge[i].v;
            if(!dfn[v]) {
                tarjan(v); low[u] = min(low[u] , low[v]);
            }
            else if(ins[v]) low[u] = min(low[u] , dfn[v]);
        }
        if(low[u] == dfn[u]) {
            idx ++;
            do {
                v = sta[top--];
                ins[v] = false;
                id[v] = idx;
            }while(u != v);
        }
    }
    void solve() {
        idx = cnt = top = 0;
        memset(ins , false , sizeof(int) * (n+1));
        memset(dfn , 0 ,sizeof(int) * (n+1));
        for(int i=1;i<=n;i++) {
            if(!dfn[i]) tarjan(i);
        }
    }
    int ccc[maxn];
    bool bb[maxn] , cc[maxn];
    int main() {
        int T;
        scanf("%d" , &T);
        int cas = 1;
        while(T--) {
            scanf("%d%d",&n,&m);
            printf("Case %d: " , cas ++);
            int mm = m;
            init(); int u , v;
            while(m--) {
                scanf("%d%d",&u,&v);
                addedge(u  , v);
            }
            solve();
            //printf("check  idx is %d
    " , idx);
            if(idx == 1) {
                printf("-1
    ");
                continue;
            }
            for(int i=1;i<=idx;i++) ccc[i] = 0;
            for(int i=1;i<=n;i++) ccc[ id[i] ] ++;
    
            for(int i=1;i<=idx;i++) bb[i] = cc[i] = false;
            for(int u=1;u<=n;u++) {
                for(int i=head[u];i!=-1;i=edge[i].next) {
                    int v = edge[i].v;
                    if(id[u] != id[v]) bb[ id[u] ] = cc[ id[v] ] = true;
                }
            }
            long long  ans = 0;
            for(int i=1;i<=idx;i++) {
                if(bb[i] && cc[i]) continue;
                long long  n1 = ccc[i] , n2 = n - n1;
                long long  tt = n1 * (n1 - 1) + n2 * (n2 - 1) + n1 * n2;
                if(tt > ans) ans = tt;
            }
            ans -= mm;
            //printf("%lld
    " , ans);
            cout << ans << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    个人作业——软件工程实践总结&个人技术博客
    个人作业——软件评测
    结对第二次作业——某次疫情统计可视化的实现
    结对第一次—疫情统计可视化(原型设计)
    软工实践寒假作业(2/2)
    软工实践寒假作业(1/2)
    C#MD5判断文件是否修改
    Socket抓包工具WireShark使用
    C#窗体最大化最小化等比例缩放
    QMessageBox
  • 原文地址:https://www.cnblogs.com/tobec/p/3231416.html
Copyright © 2020-2023  润新知