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\n" , idx);
        if(idx == 1) {
            printf("-1\n");
            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\n" , ans);
        cout << ans << endl;
    }
    return 0;
}

  

 posted on 2013-08-01 22:44  tobec  阅读(165)  评论(0编辑  收藏  举报