pku2186(HAOI2006) Popular Cows(受欢迎的牛)

问题抽象成图论,对于每一对欢迎关系(A,B),我们从A向B连一条有向边,得到的图是有可能存在环的,

在原图上使用Tarjan算法,得到一个新图(有向无环),如果缩后仅剩一个点,答案为n,即任意点都被其他点欢迎,

否则统计每一个新点的出度,对于出度为0的点的个数

1:答案是该点包含的原图点数,其他的牛都不能被他们欢迎

>=2:答案为0,出度为0的点间互不欢迎。

View Code
  1 program pku2186(input,output);
  2 type
  3     node=^link;
  4     link=record
  5         goal:longint;
  6         next:node;
  7     end;
  8 var
  9     l          :array[0..11000] of node;
 10     color    :array[0..11000] of longint;
 11     out      :array[0..11000] of longint;
 12     n,m     :longint;
 13     dfn,low :array[0..11000] of longint;
 14     stack   :array[0..20000] of longint;
 15     instack :array[0..11000] of boolean;
 16     colour,cnt,top:longint;
 17     answer,answer_color,sum:longint;
 18 procedure add(xx,yy:longint);
 19 var
 20     tt:node;
 21 begin
 22     new(tt);
 23     tt^.goal:=yy;
 24     tt^.next:=l[xx];
 25     l[xx]:=tt;
 26 end;{ add }
 27 procedure init;
 28 var
 29     i,xx,yy:longint;
 30 begin
 31     readln(n,m);
 32     for i:=1 to n do
 33     begin
 34         instack[i]:=false;
 35         dfn[i]:=0;
 36         low[i]:=0;
 37         color[i]:=0;
 38         out[i]:=0;
 39         l[i]:=nil;
 40     end;
 41     for i:=1 to m do
 42     begin
 43         readln(xx,yy);
 44         add(xx,yy);
 45     end;
 46 end;{ init }
 47 procedure dfs(now:longint);
 48 var
 49     t:node;
 50 begin
 51     inc(cnt);
 52     dfn[now]:=cnt;
 53     low[now]:=cnt;
 54     inc(top);
 55     stack[top]:=now;
 56     instack[now]:=true;
 57     t:=l[now];
 58     while t<>nil do
 59     begin
 60         if dfn[t^.goal]=0 then
 61         begin
 62             dfs(t^.goal);
 63             if low[t^.goal]<low[now] then
 64                 low[now]:=low[t^.goal];
 65         end
 66         else
 67         begin
 68             if (instack[t^.goal])and(dfn[t^.goal]<low[now]) then
 69                 low[now]:=dfn[t^.goal];
 70         end;
 71         t:=t^.next;
 72     end;
 73     if dfn[now]=low[now] then
 74     begin
 75         inc(colour);
 76         while true do
 77         begin
 78             color[stack[top]]:=colour;
 79             instack[stack[top]]:=false;
 80             dec(top);
 81             if stack[top+1]=now then
 82                 break;
 83         end;
 84     end;
 85 end;{ dfs }
 86 procedure tarjan();
 87 var
 88     i:longint;
 89 begin
 90     colour:=0;
 91     for i:=1 to n do
 92     if dfn[i]=0 then
 93         dfs(i);
 94 end;{ tarjan }
 95 procedure main;
 96 var
 97     t:node;
 98     i:longint;
 99 begin
100     for i:=1 to n do
101     begin
102         t:=l[i];
103         while t<>nil do
104         begin
105             if color[i]<>color[t^.goal] then
106                 inc(out[color[i]]);
107             t:=t^.next;
108         end;
109     end;
110     answer_color:=0;
111     sum:=0;
112     answer:=0;
113     for i:=1 to colour do
114         if out[i]=0 then
115         begin
116             inc(sum);
117             answer_color:=i;
118         end;
119     if colour=1 then
120     begin
121         answer:=n;
122         exit;
123     end;
124     if sum>=2 then
125         answer:=0;
126     if sum=1 then
127     begin
128         for i:=1 to n do
129             if color[i]=answer_color then
130                 inc(answer);
131     end;
132 end;{ main }
133 procedure print;
134 begin
135     writeln(answer);
136 end;{ print }
137 begin
138     init;
139     tarjan;
140     main;
141     print;
142 end.
posted @ 2012-05-04 17:19  Codinginging  阅读(572)  评论(0编辑  收藏  举报