裸地匈牙利或者最大流,直接匹配就行了
需要注意的是(我就没注意细节WA了好多次。。。)
每个人和自己之间的边是0,但是应该是1
不是在校生是没有床的。。。。
/**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/
//By BLADEVIL
var
t, n, m :longint;
i :longint;
size :array[..] of longint;
know :array[..,..] of longint;
flag, bed :array[..] of boolean;
link :array[..] of longint;
function find(x:longint):boolean;
var
i :longint;
begin
for i:= to n do
if know[x,i]= then
if (not flag[i]) and (bed[i]) then
begin
flag[i]:=true;
if (link[i]=) or (find(link[i])) then
begin
link[i]:=x;
exit(true);
end;
end;
exit(false);
end;
procedure main;
var
i, j :longint;
x :longint;
ans, sum :longint;
begin
read(n);
fillchar(link,sizeof(link),);
fillchar(size,sizeof(size),);
fillchar(know,sizeof(know),);
fillchar(bed,sizeof(bed),false);
for i:= to n do read(size[i]);
for i:= to n do if size[i]= then bed[i]:=true;
for i:= to n do
begin
read(x);
if (size[i]=) and (x=) then size[i]:=;
end;
for i:= to n do
for j:= to n do read(know[i,j]);
for i:= to n do know[i,i]:=;
ans:=; sum:=;
for i:= to n do if size[i]= then inc(sum);
for i:= to n do
if size[i]= then
begin
fillchar(flag,sizeof(flag),false);
if find(i) then inc(ans);
end;
if sum=ans then writeln('^_^') else writeln('T_T');
end;
begin
read(t);
for i:= to t do main;
end.