解题报告 Dormitory

Dormitory

【题目描述】

小蛮妹子有许多的,什么棉花糖啦,蜥蜴啊,小乌龟啊,只有你想不到的没有她没有的。

小蛮妹子的小宠物都住在一个漂亮的大屋子里,每个人都有自己的床位,但是由于小蛮妹子的宠物太多了,以至于这些宠物之间并不是都互相认识。

这些宠物们也有自己的朋友,这些朋友一直羡慕他们住的漂亮大屋子,于是有一天,小蛮妹子出去玩了,一些小宠物也偷偷出去玩了,那些留守的小宠物们开始招待来访的客人。

这些来客都打算在这里住一晚上,可是安排床位就出了麻烦。每个小宠物都只愿意在自己的直接朋友或自己的床上(如果它是小蛮的宠物)睡觉,且一物睡一张床。

询问是否能有一个方案来满足所有在留宿的宠物都能住宿。

【输入格式】

第一行一个数 表示数据组数。

接下来 组数据

每组数据第一行一个数 表示涉及到的总宠物数(包括小蛮的宠物和来客)

接下来一行 个数,第 个数表示第 个宠物是否是在小蛮的宠物 (0 表示不是,表示是)。再接下来一行 个数,第 个数表示第 个人是否出去玩(0 表示不出去表示出去)注意如果第 个人不是小蛮的宠物,那么这个位置上的数是一个随机的数,你应该在读入以后忽略它)

接下来 每行 个数,第 行第 个数表示 和 是否认识 (1 表示认识,表示不认识,第 行 个的值为 0,但是显然自己还是可以睡自己的床),认识的关系是
相互的。

【输出格式】

每一行对应每组数据

若存在方案满足条件 输出  ^.^   ,否则输出  T.T (只有三个字符,没有空格等其他内容)

【输入样例】

1

3

1 1 0

0 1 0

0 1 1

1 0 0

1 0 0

【输出样例】

^.^

【数据hint

对于 30% 的数据满足 1 ≤ n ≤ 12
对于 100% 的数据满足 1 ≤ n ≤ 50,1 ≤ T ≤ 20

 

 

 

 

对于这种问题,本人已开始本来想用匈牙利来着,但是,猛然想起来,二分图不是 NOIP 考察范围。

后来极度后悔,因为出这个题的仁兄不会在乎 NOIP 考不考的......TAT

 

算法,毫无疑问,就是匈牙利。

 

将需要睡觉的动物(包括没出去玩的和来做客的)和相对应的可以让它用来睡觉的床(也就是所有是小蛮的宠物的动物的床)之间连一条边。

然后,跑一边匈牙利中的 find 函数。

如果所有的需要睡觉的动物都可以匹配上,那么显然可以成功,不然则不可以。

 

代码 (艾 FHAI

var

a:array[0..55,0..55]of longint;

l,r:array[0..55]of longint;

pt,ah:array[0..55]of boolean;

v:array[0..55]of boolean;

res:array[0..55]of longint;

i,j,n,t,z,x,rr,ll,ans:longint;

 

function find(x:longint):boolean;

var j,tem:longint;

begin

//writeln('x,',x);

for j:=1 to rr do

    if (not v[r[j]])and(a[x,r[j]]=1) then

    begin

    tem:=r[j];

    v[tem]:=true;

    if (res[tem]=0) or (find(res[tem])) then

        begin

        res[tem]:=x;

        //writeln('tem,',tem,',',res[tem]);

        exit(true);

        end;

    end;

exit(false);

end;       //----------->话说,这个是可以背下来的。

 

begin

assign(input,'dormitory.in');reset(input);

assign(output,'dormitory.out');rewrite(output);

 

readln(t);

for z:=1 to t do

    begin

    fillchar(pt,sizeof(pt),false);

    fillchar(ah,sizeof(ah),false);

    ll:=0;rr:=0;ans:=0;

    readln(n);

    for i:=1to n do

        begin

        read(x);

        if x=1 then

            begin

            inc(rr);r[rr]:=i;pt[i]:=true;

            end

        else

            begin

            inc(ll);l[ll]:=i;ah[i]:=true;

            end;

        end;

    readln;

    for i:=1to n do

        begin

        read(x);

        if (pt[i]) and (x=0) then

            begin

            inc(ll);l[ll]:=i;ah[i]:=true;

            end;

        end;

    readln;

    //for i:=1to ll do write(l[i]);writeln;

    //for j:=1 to rr do write(r[j]);writeln;

    for i:=1 to n do

        begin

        for j:=1to n do

            read(a[i,j]);

        readln;

        end;

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

    if ll>rr then

        begin

        writeln('T.T');

        continue;

        end;

    {for i:=1 to ll do

        for j:=1to rr do

        if a[l[i],r[j]]=1 then write(l[i],',',r[j],',');writeln;  }

    fillchar(res,sizeof(res),0);

    for i:=1 to ll do

        begin

        fillchar(v,sizeof(v),false);

        if find(l[i]) then inc(ans);

        end;

    if ans>=ll then writeln('^.^')

        else writeln('T.T');

    //for i:=1to rr do write(r[i],',',res[r[i]],'/');writeln;

    end;

close(input);close(output);

end.

 

 

 

本人马上发一篇有关匈牙利的博客,敬请关注。

posted @ 2011-10-18 15:15  木小漾  阅读(249)  评论(0编辑  收藏  举报