讨论 / noi2011 食物链 求教……
fts96 2012-08-16 19:47:00
点我顶贴 收藏 删除
用了一个类似friend-enemy并查集的思想,于是Wa30……求破……

注:eat:该生物吃集合

eaten:该生物被吃集合

iseat:能否x吃y

issame:能否x和y相同

pan:判断是否假话

program rq455;

var

father,eat,eaten:array[1..50000] of longint;

n,k:longint;

a,b,c:array[1..3] of longint;

procedure init;

var i:longint;

begin

readln(n,k);

for i:=1 to n do

begin

father[i]:=i;

eat[i]:=0;

eaten[i]:=0;

end;

end;

function getfather(x:longint):longint;

begin

if father[x]=x then exit(x);

father[x]:=getfather(father[x]);

exit(father[x]);

end;

function issame(x,y:longint):boolean;

begin

if (eat[y]<>0)and(getfather(x)=getfather(eat[y])) then exit(false);

if (eaten[y]<>0)and(getfather(x)=getfather(eaten[y])) then exit(false);

exit(true);

end;

function iseat(x,y:longint):boolean;

begin

if getfather(x)=getfather(y) then exit(false);

if (eat[y]<>0)and(getfather(x)=getfather(eat[y])) then exit(false);

exit(true);

end;

procedure union(x,y:longint);

begin

father[getfather(x)]:=getfather(y);

end;

function pan(d,x,y:longint):boolean;

begin

if (d=2)and(x=y) then exit(false);

if (x>n)or(y>n) then exit(false);

if (d=1)and(not issame(x,y)) then exit(false);

if (d=2)and(not iseat(x,y)) then exit(false);

exit(true);

end;

procedure unionvar(var x,y:longint);

begin

if x=0 then x:=y

else if y=0 then y:=x

else union(x,y);

end;

procedure eat_eaten;

var d,x,y:longint;

i:longint;

z:longint;

t:boolean;

begin

z:=0;

{for i:=1 to k do

begin

readln(d,x,y);

if (d=2)and(x=y) then begin inc(z);continue;end;

if (x>n)or(y>n) then begin inc(z);continue;end;

case d of

1:

begin

if getfather(x+n)=getfather(y+n) then

begin

if getfather(x)<>getfather(y) then inc(z);

end

else

begin

union(x+n,y+n);

union(x,y);

unionvar(eat[x],eat[y]);

unionvar(eaten[x],eaten[y]);

end;

end;

2:

begin

if getfather(x+n)=getfather(y+n) then

begin

if (eaten[y]<>0)and(getfather(x)<>getfather(eaten[y])) then inc(z);

end

else

begin

union(x+n,y+n);

unionvar(x,eaten[y]);

unionvar(y,eat[x]);

unionvar(eaten[x],eat[y]);

end;

end;

end;

end; }

for i:=1 to k do

begin

readln(d,x,y);

if pan(d,x,y) then

begin

case d of

1:

begin

unionvar(x,y);

unionvar(eat[x],eat[y]);

unionvar(eaten[x],eaten[y]);

end;

2:

begin

unionvar(x,eaten[y]);

unionvar(eat[x],y);

unionvar(eaten[x],eat[y]);

end;

end;

end

else inc(z);

end;

writeln(z);

end;

begin

init;

eat_eaten;

end.

eat:吃集合

eaten:该生物被吃集合

iseat:能否x吃y

issame:能否x和y相同

pan:判断是否假话

查看更多回复
提交回复