POJ 1308(树的判定)

内容目录

给定一个有向图,问这是不是树?

各种判……

出现2条相同的边不是树,自己指向自己不是树,除根节点入度为0外其它点入度必须为1,森林,环都不是树……

program P1308;
const
   maxn=15;
Var
   i,j:longint;
   b:array[1..maxn,1..maxn] of boolean;
   indegree:array[1..maxn] of longint;
   bo:array[1..maxn] of boolean;
   queue:array[1..maxn+10] of longint;
procedure skip;
var
   x,y:longint;
begin
   repeat
      read(x,y);
   until (x=0) and (y=0);
end;
function main:longint;
var
   i,j,k,x,y,root,node:longint;
begin
   read(x,y);
   if (x=-1) and (y=-1) then exit(-1);
   if (x=0) and (y=0) then exit(1);
   while (x>0) and (y>0) do
   begin
      if b[x,y] or b[y,x] or (x=y) or (indegree[y]=1) then
      begin
         skip;
         exit(0);
      end;
      b[x,y]:=true;
      bo[x]:=true;bo[y]:=true;
      inc(indegree[y]);
      read(x,y);
   end;
   root:=0;
   node:=0;
   for i:=1 to maxn do
   begin
      if bo[i] then inc(node);
      if (indegree[i]=0) and bo[i] then
      begin
         if root=0 then root:=i else exit(0);
      end;
   end;
   if (root=0) then exit(0);
   i:=1;j:=1;
   queue[1]:=root;
   bo[root]:=false;
   while i<=j do
   begin
      for k:=1 to maxn do
         if b[queue[i],k] then
         begin
            if not(bo[k]) then exit(0);
            bo[k]:=false;
            inc(j);
            queue[j]:=k;
         end;
      inc(i);
   end;
   if (j<>node) then exit(0);
   exit(1);
end;
begin
   i:=1;
   while (true) do
   begin
      fillchar(indegree,sizeof(indegree),0);
      fillchar(b,sizeof(b),0);
      fillchar(bo,sizeof(bo),0);
      j:=main;
      if j=1 then writeln('Case ',i,' is a tree.')
      else if j=0 then writeln('Case ',i,' is not a tree.')
      else break;
      inc(i);
   end;
end.