友好城市
【问题描述】
小 w 生活在美丽的 Z 国。 Z 国是一个有 n 个城市的大国, 城市之间有 m 条单向公路(连接城市 i、 j 的公路只能从 i 连到 j)。 城市 i、 j 是友好城市当且仅当从城市 i 能到达城市 j 并且从城市 j 能到达城市 i。 如果 k 个城市两两互为友好城市, 那么我们称这 k 个城市是友好城市群, k 为友好城市群的大小。
现在小 w 想知道友好城市群的大小最大为多少, 你能告诉他吗?
【输入格式】
第一行包含两个整数 n 和 m。
接下来 m 行, 每行两个整数 i 和 j, 表示有从城市 i 到城市 j 的一条单向公路。
【输出格式】
共一行一个整数表示答案。
【输入输出样例】
输入:
10 12
3 7
1 2
4 5
7 10
10 8
6 8
2 1
3 8
10 3
6 8
7 3
4 1
输出:
3
【数据范围】
对于 30%的数据, n,m<=100
对于 80%的数据, n<=1000,m<=100000
对于 100%的数据, n,m<=100000
裸的tarjan强连通分量题,只是为了打个tarjan板子。(然而我也不是很懂tarjan算法的原理)
1 program friend(input,output); 2 type 3 etype=record 4 t,next:longint; 5 end; 6 var 7 e:array[0..100010]of etype; 8 a,dfn,low,q:array[0..100010]of longint; 9 inq:array[0..100010]of boolean; 10 n,m,i,x,y,cnt,top,ans:longint; 11 procedure add(x,y:longint); 12 begin 13 inc(cnt);e[cnt].t:=y;e[cnt].next:=a[x];a[x]:=cnt; 14 end; 15 procedure tarjan(k:longint); 16 var 17 i:longint; 18 begin 19 inc(cnt);dfn[k]:=cnt;low[k]:=cnt; 20 inc(top);q[top]:=k;inq[k]:=true; 21 i:=a[k]; 22 while i<>0 do 23 begin 24 if dfn[e[i].t]=0 then begin tarjan(e[i].t);if low[e[i].t]<low[k] then low[k]:=low[e[i].t]; end 25 else if inq[e[i].t] and (dfn[e[i].t]<low[k]) then low[k]:=dfn[e[i].t]; 26 i:=e[i].next; 27 end; 28 if dfn[k]=low[k] then 29 begin 30 i:=0; 31 while q[top]<>k do begin inq[q[top]]:=false;dec(top);inc(i); end; 32 dec(top);inq[k]:=false;inc(i); 33 if i>ans then ans:=i; 34 end; 35 end; 36 begin 37 assign(input,'friend.in');assign(output,'friend.out');reset(input);rewrite(output); 38 readln(n,m); 39 fillchar(a,sizeof(a),0);cnt:=0; 40 for i:=1 to m do begin readln(x,y);add(x,y); end; 41 fillchar(dfn,sizeof(dfn),0); 42 ans:=0; 43 fillchar(inq,sizeof(inq),false); 44 for i:=1 to n do if dfn[i]=0 then begin cnt:=0;top:=0;tarjan(i); end; 45 write(ans); 46 close(input);close(output); 47 end.