这道题一看我就感觉做过..但不记得是怎么做的了...第一感是并查集...找出一类一类有公共祖先的点...公共祖先个数则为第一问的解...第二问就是要始各个公共祖先能形成一个圈..并且每个树的叶子要能到达祖先...就写了一个Floyd+DFS的东东...结果过了前面4个数据...WA了...仔细一想...不对啊..这道题用并查集是错误的...
再一研究...发现这道题其实就是个求强连通分量..果然..找到了去年10月自己的这个解题报告..POJ1236..和这道题一模一样..
http://blog.csdn.net/kk303/article/details/6884061
好吧...好久没写Tarjan了...又熟悉复习了一遍..
Program:
/*
ID: zzyzzy12
LANG: C++
TASK: schlnet
*/
#include<iostream>
#include<istream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stack>
#include<map>
#include<algorithm>
#include<queue>
#define oo 2000000005
#define ll long long
#define pi (atan(2)+atan(0.5))*2
using namespace std;
struct node
{
int x,y,next;
}line[10005];
int n,m,_link[105],DFS[105],LOW[105],TYPE[105],num;
int TYPENUM,ans1,ans2;
bool InTheStack[105];
stack<int> mystack;
void Tarjan(int x)
{
int k;
mystack.push(x);
LOW[x]=DFS[x]=++num;
InTheStack[x]=true;
k=_link[x];
while (k)
{
if (!DFS[line[k].y])
{
Tarjan(line[k].y);
LOW[x]=min(LOW[x],LOW[line[k].y]);
}else
if (InTheStack[line[k].y])
{
LOW[x]=min(LOW[x],DFS[line[k].y]);
}
k=line[k].next;
}
if (LOW[x]==DFS[x])
{
TYPENUM++;
do
{
k=mystack.top();
mystack.pop();
TYPE[k]=TYPENUM;
InTheStack[k]=false;
}while (LOW[k]!=DFS[k]);
}
return;
}
int main()
{
freopen("schlnet.in","r",stdin);
freopen("schlnet.out","w",stdout);
scanf("%d",&n);
int x,y,k,p;
bool IN[105],OUT[105];
m=0;
memset(_link,0,sizeof(_link));
for (x=1;x<=n;x++)
{
while (~scanf("%d",&y))
{
if (!y) break;
m++;
line[m].x=x; line[m].y=y;
line[m].next=_link[x]; _link[x]=m;
}
}
memset(DFS,0,sizeof(DFS));
num=0; TYPENUM=0;
for (x=1;x<=n;x++)
if (!DFS[x])
{
memset(InTheStack,false,sizeof(InTheStack));
while (!mystack.empty()) mystack.pop();
Tarjan(x);
}
memset(IN,false,sizeof(IN));
memset(OUT,false,sizeof(OUT));
p=0;
for (k=1;k<=m;k++)
if (TYPE[line[k].x]!=TYPE[line[k].y])
{
OUT[TYPE[line[k].x]]=true;
IN[TYPE[line[k].y]]=true;
}
ans1=ans2=0;
for (k=1;k<=TYPENUM;k++)
{
if (!IN[k]) ans1++;
if (!OUT[k]) ans2++;
}
if (ans1>ans2) ans2=ans1;
if (!ans1) ans1=1;
if (TYPENUM==1) ans2=0;
printf("%d\n%d\n",ans1,ans2);
return 0;
}