hdu 4635

来源:互联网 发布:阿里云cdn签名 编辑:程序博客网 时间:2024/06/05 13:25

分析:

完全图的边数为 n*(n-1)

若图不为强连通图,那么最多存在两个部

找出每个强连通的个数,当该连通图的入度或出度问为0时计算即可

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <stack>#include <stack>#include <vector>using namespace std;#define maxn 100050vector<int>E[maxn];stack<int>st;int dfn[maxn];int low[maxn];int ins[maxn];int nub[maxn];int cnt ;int time;int belong[maxn];int T;int n , m;int in[maxn];int out[maxn];void init(){    time = cnt = 0;    memset(ins,0,sizeof(ins));    memset(belong,0,sizeof(belong));    memset(nub,0,sizeof(nub));    memset(in, 0, sizeof(in));    memset(out, 0, sizeof(out));    memset(low,0,sizeof(low));    memset(dfn,0,sizeof(dfn));    while(st.size())st.pop();    for(int i = 0 ; i < maxn ;++i)        E[i].clear();}void Tarjan(int u){    low[u] = dfn[u] = ++time;    st.push(u);    ins[u] = 1;    for(int i = 0 ; i < E[u].size() ; ++i)    {        int v = E[u][i];        if( !dfn[v] )        {            Tarjan(v);            low[u] = min( low[u],low[v] );        }        else if( ins[v] )        {            low[u] = min( low[u] , dfn[v] );        }    }    int tmp;    if( low[u] == dfn[u] )    {        cnt++;        do{            tmp = st.top();st.pop();            ins[tmp] = 0;            belong[tmp] = cnt;            nub[cnt]++;        }while( tmp != u );    }}void deal(){    for(int i = 1 ; i <= n ; ++i)    {        if(!dfn[i])        {            Tarjan(i);        }    }    if( cnt == 1 )    {        printf("-1\n");        return ;    }    for(int u = 1; u <= n ; ++u)    {        for (int i = 0; i < E[u].size() ; ++i)        {            int v = E[u][i];            if (belong[u] != belong[v])            {                in[belong[v]] ++;                out[belong[u]] ++;            }        }    }    int result = 0;    for (int i = 1; i <= cnt; i++)    {        if (!in[i] || !out[i])        {            int t = nub[i];            int temp = t * (t - 1) + (n - t) * (n - t - 1) + t * (n - t) - m;            result = result > temp ? result : temp;        }    }    printf("%d\n", result);}int main(){    cin >> T;    int cas = 0;    while ( T-- )    {        init();        cin >> n >> m ;        for(int i = 0  ; i < m ; ++i)        {            int a,b;            scanf("%d %d",&a,&b);            E[a].push_back(b);        }        printf("Case %d: ",++cas);        deal();    }}



原创粉丝点击