tarjan算法很犀利,不解释,不解释。。。
缩点然后判断度数
#include<iostream>
#include<vector>
#include<cstring>
#include<deque>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<iomanip>
#include<algorithm>
#include<cassert>
#define pb push_back
using namespace std;
const int maxn = 111;
vector<int>g[maxn];
vector<int>v[maxn];
vector<int>s;
bool hash[maxn][maxn];
int be[maxn];
int dfn[maxn];
int low[maxn];
bool ins[maxn];
int n,df,nb;
int in[maxn];
int out[maxn];
int sa,sd;
void tarjan(int now)
{
low[now] = dfn[now] = df++;
s.pb(now);
ins[now] = true;
int to;
for(int i=0;i<g[now].size();i++)
{
to = g[now][i];
if(!dfn[to])
{
tarjan(to);
low[now] = min(low[to],low[now]);
}
else if( ins[to] )
{
low[now] = min(low[to],low[now]);
}
}
if(low[now] == dfn[now] )
{
while(s.back()!=now)
{
to = s.back();
be[to] = nb;
s.pop_back();
ins[to] = false;
}
be[now] = nb++;
ins[now] = false;
s.pop_back();
}
return ;
}
void start()
{
s.clear();
nb = df = 1;
memset(ins,false,sizeof(ins));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(be,0,sizeof(be));
memset(hash,false,sizeof(hash));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
/* for(int i=1;i<=n;i++)
{
cout<<"dfn["<<i<<"] == "<<dfn[i]<<endl;
cout<<"low["<<i<<"] == "<<low[i]<<endl;
cout<<"be["<<i<<"] == "<<be[i]<<endl;
} */
nb--;
if(nb==1)
{
sa = 1;
sd = 0;
return ;
}
int from,to;
for(int i=1;i<=n;i++)
{
from = be[i];
for(int j=0;j<g[i].size();j++)
{
to = be[g[i][j]];
if(from != to && !hash[from][to] )
{
hash[from][to] = true;
v[from].pb(to);
}
}
}
for(int i=1;i<=nb;i++)
{
from = i;
for(int j=0;j<v[i].size();j++)
{
to = v[i][j];
out[from]++;
in[to]++;
}
}
sa = 0;
sd = 0;
for(int i=1;i<=nb;i++)
{
if(!in[i])
{
sa++;
}
if(!out[i])
{
sd++;
}
}
sd = max(sa,sd);
return ;
}
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
g[i].clear();
v[i].clear();
}
int x;
for(int i=1;i<=n;i++)
{
while(cin>>x)
{
if( !x )
{
break;
}
g[i].push_back(x);
}
}
start();
cout<<sa<<endl<<sd<<endl;
}
return 0;
}