#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <stack>
#define MAX 110
using namespace std;
typedef struct MAP{
int to;
MAP *next;
}MAP;
MAP *map[MAX],node[MAX*MAX];
int n,cou,ind,scc,sccf[MAX],low[MAX],numed[MAX];
int ins[MAX];
stack <int> s;
void init()
{
int i;
for(i=0; i<=n; i++)
numed[i] = i;
cou = scc = 0;
ind = 1;
memset(ins,0,sizeof(ins));
memset(low,0,sizeof(low));
memset(node,'/0',sizeof(node));
memset(map,'/0',sizeof(map));
memset(numed,0,sizeof(numed));
memset(sccf,0,sizeof(sccf));
}
void input()
{
int i,x;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
while( scanf("%d",&x) && x )
{
node[cou].to = x;
node[cou].next = map[i];
map[i] = &node[cou++];
}
}
}
void Tarjan(int u)
{
int v;
low[u] = numed[u] = ind++;
s.push(u);
ins[u] = 1;
MAP *head = map[u];
while( head != NULL )
{
v = head->to;
if( !numed[v] )
{
Tarjan(v);
if( low[v] < low[u] )
low[u] = low[v];
}
else
if( ins[v] && numed[v] < low[u] )
low[u] = numed[v];
head = head->next;
}
if( numed[u] == low[u] )
{
scc++;
do
{
v = s.top();
s.pop();
ins[v] = 0;
sccf[v] = scc;
}while( u != v );
}
}
int Atask() // 找入度为0的点。
{
int indegree[MAX],ans = 0,i;
MAP *head;
memset(indegree,0,sizeof(indegree));
for(i=1; i<=n; i++)
{
head = map[i];
while( head != NULL )
{
if( sccf[i] != sccf[head->to] )
indegree[sccf[head->to]]++;
head = head->next;
}
}
for(i=1; i<=scc; i++)
if( indegree[i] == 0 )
ans++;
return ans;
}
int Btask()//找出度为0的点。
{
int outd[MAX],ans = 0,i;
MAP *head;
memset(outd,0,sizeof(outd));
for(i=1; i<=n; i++)
{
head = map[i];
while( head != NULL )
{
if( sccf[i] != sccf[head->to] )
outd[sccf[i]]++;
head = head->next;
}
}
for(i=1; i<=scc; i++)
if( outd[i] == 0 )
ans++;
return ans;
}
int main()
{
int i,ansa,ansb;
init();
input();
for(i=1; i<=n; i++)
if( !numed[i] )
Tarjan(i);
if( scc == 1 ) // 特殊处理。
printf("1/n0/n");
else
{
ansa = Atask();
ansb = Btask();
printf("%d/n%d/n",ansa,max(ansa,ansb));
}
return 0;
}
(精)(图论加强)(强连通图)
最新推荐文章于 2021-03-12 10:03:34 发布
