bzoj 1059 二分图匹配

我们知道,对于每一行来说,交换行,是不改变这行的状态的,

交换列只是改变颜色的顺序,对于颜色的个数也没有改变,列

也同样存在这一性质

那么最后我们要求的是主对角线上都是黑色,也就是每行选一个黑

色的,且任意两行选的黑色的不在同一列,我们构造一张二分图,

图的一边是行,另一边是列,所以对于每个黑点连边,二分图匹配即可

//By BLADEVIL

var

    t                                :longint;

    i                                :longint;

    pre, other                        :array[0..40010] of longint;

    last                            :array[0..300] of longint;

    l                                :longint;

    flag                            :array[0..300] of boolean;

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

    

procedure connect(x,y:longint);

begin

    inc(l);

    pre[l]:=last[x];

    last[x]:=l;

    other[l]:=y;

end;



function find(x:longint):boolean;

var

    q, p                            :longint;

begin

    q:=last[x];

    while q<>0 do 

    begin

        p:=other[q];

        if not flag[p] then

        begin

            flag[p]:=true;

            if (link[p]=0) or (find(link[p])) then

            begin

                link[p]:=x;

                exit(true);

            end;

        end;

        q:=pre[q];

    end;

    exit(false);

end;

    

procedure main;

var

    n                                :longint;

    i, j                            :longint;

    x                                :longint;

begin

    read(n);

    l:=0;

    fillchar(last,sizeof(last),0);

    for i:=1 to n do 

        for j:=1 to n do 

        begin

            read(x);

            if x=1 then connect(i,j);

        end;

    fillchar(link,sizeof(link),0);

    

    for i:=1 to n do 

    begin

        fillchar(flag,sizeof(flag),false);

        if not find(i) then

        begin

            writeln('No');

            exit;

        end;

    end;

    writeln('Yes');

end;

    

    

begin

    read(t);

    for i:=1 to t do main;



end.

 

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