3 3 3 1 2 2 3 3 1 3 3 1 2 2 3 1 3 6 6 1 2 2 3 3 1 4 5 5 6 6 4
Case 1: -1 Case 2: 1 Case 3: 15
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>
using namespace std;
const int maxn=100010;
int n,m,time,cnt,dfn[maxn],low[maxn],belong[maxn],sum[maxn],in[maxn],out[maxn];
bool visited[maxn];
vector <int > G[maxn];
stack <int > st;
void initial()
{
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(sum,0,sizeof(sum));
memset(belong,0,sizeof(belong));
memset(visited,0,sizeof(visited));
while(!st.empty()) st.pop();
for(int i=0; i<maxn; i++) G[i].clear();
time=1;
cnt=0;
}
void input()
{
int u,v;
scanf("%d %d",&n,&m);
for(int i=0; i<m; i++)
{
scanf("%d %d",&u,&v);
G[u].push_back(v);
}
}
void tarjan(int u)
{
dfn[u]=low[u]=time++;
st.push(u);
visited[u]=1;
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(visited[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
cnt++;
while(1)
{
int t=st.top();
st.pop();
belong[t]=cnt;
sum[cnt]++;
visited[t]=0;
if(t==u) break;
}
}
}
void ready()
{
for(int i=1; i<=n; i++)
for(int j=0; j<G[i].size(); j++)
{
int u=belong[i],v=belong[G[i][j]];
if(u!=v)
{
out[u]++;
in[v]++;
}
}
}
long long get_ans()
{
long long ans=-1;
for(int i=1; i<=cnt; i++)
{
if(!in[i] || !out[i])
{
long long x=sum[i],y=n-sum[i];
ans=max(ans,x*(x-1)+y*(y-1)+x*y-m);
}
}
return ans;
}
void solve(int co)
{
for(int i=1; i<=n; i++) if(!dfn[i]) tarjan(i);
if(cnt==1)
{
printf("Case %d: -1\n",co);
return ;
}
ready();
printf("Case %d: %I64d\n",co,get_ans());
}
int main()
{
int T;
scanf("%d",&T);
for(int co=1; co<=T; co++)
{
initial();
input();
solve(co);
}
return 0;
}
hdu 4635 Strongly connected (Tarjan+缩点)
原文:http://blog.csdn.net/u012596172/article/details/44568415