题目大意
N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,
问题
1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。
2,至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。
分析
先跑一遍taijian算法。然后把一个强连通分量当做一个点,求入度为0的点的个数,就是问题一的答案(因为只有入度为0的强连通分量要分一套软件)。再求出度为0的点的个数,
第二个问题就输出max(入度0,出度0),因为要把这些点连在一起。
代码
const
maxe=50000;
maxv=1000;
type
rec=record
x,y,w,next:longint;
end;
var
n,m:longint;
g:array[1..maxe] of rec;
ls:array[1..maxv] of longint;
v,a,ru,cu:array[1..maxv] of longint;
low,dfn:array[1..maxv] of longint;
zan:array[1..maxv] of longint;
tot,ans,tot1:longint;
i,j,k:longint;
procedure dfs(r:longint);
var
i,j,k:longint;
begin
tot:=tot+1;
zan[tot]:=r;
v[r]:=1;
tot1:=tot1+1;
low[r]:=tot1;
dfn[r]:=tot1;
i:=ls[r];
while i<>0 do
with g[i] do
begin
if dfn[y]=0
then
begin
dfs(y);
if low[r]>low[y] then low[r]:=low[y];
end
else
if (low[r]>dfn[y]) and (v[y]=1)
then low[r]:=dfn[y];
i:=next;
end;
if low[r]=dfn[r]
then
begin
ans:=ans+1;
repeat
j:=zan[tot];
tot:=tot-1;
a[j]:=ans;
v[j]:=0;
until j=r;
end;
end;
begin
readln(n);
k:=0;
ans:=0;
for i:=1 to n do
begin
read(j);
while j<>0 do
begin
k:=k+1;
with g[k] do
begin
x:=i;
y:=j;
next:=ls[i];
ls[i]:=k;
end;
read(j);
end;
end;
for i:=1 to n do
if a[i]=0
then
dfs(i);
for i:=1 to n do
begin
j:=ls[i];
while j<>0 do
with g[j] do
begin
if a[x]<>a[y]
then
begin
cu[a[x]]:=cu[a[x]]+1;
ru[a[y]]:=ru[a[y]]+1;
end;
j:=next;
end;
end;
j:=0;
for i:=1 to ans do
if ru[i]=0 then j:=j+1;
writeln(j);
k:=0;
for i:=1 to ans do
if cu[i]=0 then k:=k+1;
if ans=1 then
begin
write(0);
halt;
end;
if k>j then write(k)
else write(j);
end.