嗯剛剛A了它。。
真是感動。。。。
Tarjan縮點在聯賽中考的可能性很大
所以必須要好好寫一寫
恩先放題目簡介
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 11443 | Accepted: 4555 |
Description
You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.
Input
Output
Sample Input
5 2 4 3 0 4 5 0 0 0 1 0
Sample Output
1 2嘖嘖居然是IOI的題目
不過IOI的題目在那個時候向來都是水的啊。。[具體參見 “北京2008的大鐘”]
然後就Tarjan縮點搞起
第一問統計有多少入度爲0的
第二問統計入度爲0和出度爲0的最大值
然後就沒了
唯一感動的就是在縮點之後怎麼處理
看程序啦。。
const shuru='test.in';
shuchu='test.out';
var belong,dfn,low,headlist:Array[0..101] of longint;
t,next:Array[0..10001] of longint;
stack:Array[0..101] of longint;
ins,vis:Array[0..101] of boolean;
indu,outdu:array[0..101] of longint;
count1,count2,v,top,scc_cnt,time,x,i,j,k,n,num:longint;
procedure init;
begin
assign(input,shuru);
assign(output,shuchu);
reset(input);
rewrite(output);
readln(n);
for i:=1 to n do headlist[i]:=-1;
fillchar(vis,sizeof(vis),false);
fillchar(ins,sizeof(ins),false);
for i:=1 to n do
begin
read(x);
while x<>0 do
begin
inc(num);
next[num]:=headlist[i];
headlist[i]:=num;
t[num]:=x;
read(X);
end;
end;
close(input);
end;
function min(a,b:longint):longint;
begin
if a<b then exit(A);
exit(b);
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
procedure dfs(u:longint);
var i:longint;
begin
inc(time);
dfn[u]:=time; low[u]:=time;
inc(top);
stack[top]:=u;
i:=headlist[u];
vis[u]:=true; ins[u]:=true;
while i<>-1 do
begin
if not(vis[t[i]]) then begin
dfs(t[i]);
low[u]:=min(low[u],low[t[i]]);
end
else if ins[t[i]] then
low[u]:=min(low[u],dfn[t[i]]);
i:=next[i];
end;
if low[u]=dfn[u] then begin
inc(scc_cnt);
repeat
v:=stack[top];
belong[v]:=scc_cnt;
dec(top);
ins[v]:=false;
until u=v;
end;
end;
procedure main;
begin
top:=0;
init;
for i:=1 to n do if not(vis[i]) then dfs(i);
if scc_cnt=1 then begin
writeln(1);
writeln(0);
halt;
end;
for x:=1 to n do
begin
i:=headlist[x];
while i<>-1 do
begin
if belong[t[i]]<>belong[x] then begin
inc(indu[belong[t[i]]]);
inc(outdu[belong[x]]);
end;
i:=next[i];
end;
end;
for i:=1 to scc_cnt do
begin
if indu[i]=0 then inc(count1);
if outdu[i]=0 then inc(count2);
end;
writeln(count1);
writeln(max(count1,count2));
end;
begin
main;
end.