[Tarjan縮點] POJ1236題解

嗯剛剛A了它。。

真是感動。。。。

Tarjan縮點在聯賽中考的可能性很大

所以必須要好好寫一寫

恩先放題目簡介

Network of Schools
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 11443   Accepted: 4555

Description

A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the “receiving schools”). Note that if B is in the distribution list of school A, then A does not necessarily appear in the list of school B 
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

The first line contains an integer N: the number of schools in the network (2 <= N <= 100). The schools are identified by the first N positive integers. Each of the next N lines describes a list of receivers. The line i+1 contains the identifiers of the receivers of school i. Each list ends with a 0. An empty list contains a 0 alone in the line.

Output

Your program should write two lines to the standard output. The first line should contain one positive integer: the solution of subtask A. The second line should contain the solution of subtask B.

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.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章