1332 上白澤慧音
時間限制: 1 s
空間限制: 128000 KB
題目等級 : 黃金 Gold
題解
題目描述 Description
給出N個點和M條單向邊,求最大的強連通分量並且輸出最大強連通分量中的所有點
輸入描述 Input Description
第1行:兩個正整數N,M
第2..M+1行:每行三個正整數a,b,t, t = 1表示存在從村莊a到b的單向道路,t = 2表示村莊a,b之間存在雙向通行的道路。保證每條道路只出現一次。
輸出描述 Output Description
第1行: 1個整數,表示最大的絕對連通區域包含的村莊個數。
第2行:若干個整數,依次輸出最大的絕對連通區域所包含的村莊編號。
樣例輸入 Sample Input
5 5
1 2 1
1 3 2
2 4 2
5 1 2
3 5 1
樣例輸出 Sample Output
3
1 3 5
數據範圍及提示 Data Size & Hint
對於60%的數據:N <= 200且M <= 10,000
對於100%的數據:N <= 5,000且M <= 50,000
學強連通算法之後的第一道練習題,也算是一個基礎吧,至少tarjan算法求強連通分量沒有什麼變動,重點是程序裏的 dfs(tarjan)部分
program mys;
type
ab=^node;
node=record
a:longint;
c:ab;
end;
var k,kk,y,i,j,m,n,x,max,z,h,t:longint;
s,ss:array[0..10000]of boolean;
low,c,f:array[0..10000]of longint;
p:array[0..10000]of ab;
function find(x:longint):longint;
begin
if x<>f[x] then f[x]:=find(f[x]);
find:=f[x];
end;
procedure put(x,y:longint);
var i:ab;
begin
i:=p[x];
new(p[x]);
p[x]^.a:=y;
p[x]^.c:=i;
end;
procedure dfs(x:longint);
var y:longint;
i:ab;
begin
inc(t);
s[x]:=true;
ss[x]:=true;
low[x]:=t;
i:=p[x];
while i<>nil do
begin
y:=i^.a;
if s[y]=false then
dfs(y);
y:=find(y);
if (ss[y]=true)and(low[y]<low[x]) then
begin
f[x]:=y;
low[x]:=low[y];
end;
i:=i^.c;
end;
ss[x]:=false;
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y,z);
put(x,y);
if z=2 then
put(y,x);
end;
for i:=1 to n do
begin
s[i]:=false;
ss[i]:=false;
f[i]:=i;
end;
for i:=1 to n do
if s[i]=false then
begin
fillchar(low,sizeof(low),0);
t:=0;
dfs(i);
end;
max:=0;
for i:=1 to n do
inc(c[find(i)]);
for i:=1 to n do
if c[find(i)]>max then
max:=c[find(i)];
writeln(max);
for i:=1 to n do
if c[find(i)]=max then
begin
k:=find(i);
kk:=i;
break;
end;
for i:=kk to n do
if find(i)=k then
write(i,' ');
end.