bzoj 1433 二分图匹配

裸地匈牙利或者最大流,直接匹配就行了

需要注意的是(我就没注意细节WA了好多次。。。)

每个人和自己之间的边是0,但是应该是1

不是在校生是没有床的。。。。

/**************************************************************

    Problem: 1433

    User: BLADEVIL

    Language: Pascal

    Result: Accepted

    Time:84 ms

    Memory:268 kb

****************************************************************/

 

//By BLADEVIL

var

    t, n, m                 :longint;

    i                       :longint;

    size                    :array[0..100] of longint; 

    know                    :array[0..100,0..100] of longint;

    flag, bed               :array[0..100] of boolean;

    link                    :array[0..100] of longint;

     

function find(x:longint):boolean;

var

    i                       :longint;

begin

    for i:=1 to n do

        if know[x,i]=1 then

            if (not flag[i]) and (bed[i]) then

            begin

                flag[i]:=true;

                if (link[i]=0) 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),0);

    fillchar(size,sizeof(size),0);

    fillchar(know,sizeof(know),0);

    fillchar(bed,sizeof(bed),false);

    for i:=1 to n do read(size[i]);

    for i:=1 to n do if size[i]=1 then bed[i]:=true;

    for i:=1 to n do

    begin

        read(x);

        if (size[i]=1) and (x=0) then size[i]:=0;

    end;

    for i:=1 to n do

        for j:=1 to n do read(know[i,j]);

    for i:=1 to n do know[i,i]:=1;

    ans:=0; sum:=0;

    for i:=1 to n do if size[i]=0 then inc(sum);

    for i:=1 to n do

        if size[i]=0 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:=1 to t do main;

end.

 

你可能感兴趣的:(二分图)