题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。2,至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。
解法:
1:先跑一边tarjian算法。那么我们可以得出每一个学校在哪一个强连通分量里。然后算出入度为0 的强连通分量的个数。就是第一个答案。
读为0的强连通分量的那些强连通分量连起来。所以算出出度为0和入度为0的最大值,就是第二个的答案。
3:注意如果强连通分量的个数是一个,那么第二个的答案是0.
一开始以为有多组数据然后就打了not eof,之后就不知道为什么一直WA,后面去掉居然就对了……
代码:
var ans,s1,s2,sum,tot,d,i,j,n,x:longint; a:array[1..1000,1..1000] of boolean; dfn,low,stack,be,rd,cd:array[1..1000] of longint; f:array[1..1000] of boolean; function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; procedure tarjan(x:longint); var i,j:longint; begin inc(d); dfn[x]:=d; low[x]:=d; inc(tot); stack[tot]:=x; f[x]:=true; for i:=1 to n do if (dfn[i]=0)and(a[x,i]) then begin tarjan(i); low[x]:=min(low[x],low[i]); end else if (f[i])and(a[x,i]) then low[x]:=min(low[x],low[i]); if low[x]=dfn[x] then begin inc(sum); repeat j:=stack[tot]; dec(tot); f[j]:=false; be[j]:=sum; until j=x; end; end; begin readln(n); fillchar(a,sizeof(a),false); for i:=1 to n do begin read(x); while x>0 do begin a[i,x]:=true; read(x); end; readln; end; fillchar(f,sizeof(f),false); for i:=1 to n do if dfn[i]=0 then tarjan(i); for i:=1 to n do for j:=1 to n do if (a[i,j])and(be[i]<>be[j]) then begin inc(rd[be[j]]); inc(cd[be[i]]); end; for i:=1 to sum do begin if rd[i]=0 then inc(ans); if rd[i]=0 then inc(s1); if cd[i]=0 then inc(s2); end; writeln(ans); if sum=1 then begin s1:=0; s2:=0; end; if s1>s2 then writeln(s1) else writeln(s2); end.