题意/Description:
John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出。但是,第二天John的儿子Small John将这n封信都拿出了信封。不幸的是,Small John无法将拿出的信正确地装回信封中了。
将Small John所提供的n封信依次编号为1,2,…,n;且n个信封也依次编号为1,2,…,n。假定Small John能提供一组信息:第i封信肯定不是装在信封j中。请编程帮助Small John,尽可能多地将信正确地装回信封。
读入/Input:
第一行是一个整数n(n≤100)。信和信封依次编号为1,2,…,n。
接下来的各行中每行有2个数i和j,表示第i封信肯定不是装在第j个信封中。文件最后一行是2个0,表示结束。
输出/Output:
输出的各行中每行有2个数i和j,表示第i封信肯定是装在第j个信封中。请按信的编号i从小到大顺序输出。若不能确定正确装入信封的任何信件,则输出“none”。
题解/solution:
水水的最大匹配。
代码/Code:
var
n:longint;
ls:array[0..201]of longint;
v:array[0..201]of boolean;
a:array[0..201,0..201]of boolean;
function find(x:longint):boolean;
var
i,k:longint;
begin
find:=true;
for i:=1 to n do
if not v[i] and a[x,i] then
begin
k:=ls[i]; ls[i]:=x;
v[i]:=true;
if (k=0) or find(k) then exit;
ls[i]:=k;
end;
find:=false;
end;
procedure main;
var
t,i:longint;
f:boolean;
begin
f:=false;
fillchar(ls,sizeof(ls),0);
for i:=1 to n do
begin
fillchar(v,sizeof(v),false);
find(i);
end;
for i:=1 to n do
begin
t:=ls[i]; ls[i]:=0;
a[t,i]:=false;
fillchar(v,sizeof(v),false);
if not find(t) then
begin
ls[i]:=t;
writeln(i,' ',t);
f:=true;
end;
a[t,i]:=true;
end;
if not f then writeln('none');
end;
procedure init;
var
i,x,y:longint;
begin
fillchar(a,sizeof(a),true);
readln(n);
repeat
readln(x,y);
a[y,x]:=false;
until x+y=0;
end;
begin
init;
main;
end.