看来从简单入手到复杂情况的思想还没有形成。。。
这题就需要分情况讨论的,显然每个弱联通块是可以单独拿出来讨论的。
一棵树?最大为树深,最小为3(如果树有那么深的话)
一个环?最大为环上点数,最小为环上点数的最小约数(>=3)
一个弱联通意义下的环?我们可以发现一个性质,如果一个点所练的两条边方向相反,那么这两条边是可以抵消掉的,就变成原来的环啦。
于是我们就有思路了,把有向图转化为无向图,正向边权为1,反向边权为-1。树深就对应着最长链长:最大深度-最小深度(为非正数)+1,环长也可以搞了,一遍bfs两个都搞定。
最后统计答案,若没有环,那么最大为树深之和,最小为3;若有环,树都无效了,最大为所有环长的gcd,最小为gcd的最小约数(>=3).
两个环有公共部分是不影响答案的。
代码:
type
edge=^edgenode;
edgenode=record
t,w:longint;
next:edge;
end;
var
n,m,i,x,y,gcd,sum,d:longint;
con:array[0..100100]of edge;
visit:array[0..100100]of boolean;
dl,dist:array[0..100100]of longint;
procedure ins(x,y,w:longint);
var
p:edge;
begin
new(p);
p^.t:=y;
p^.w:=w;
p^.next:=con[x];
con[x]:=p;
end;
function min(x,y:longint):longint;
begin
if x>y then exit(y)
else exit(x);
end;
function max(x,y:longint):longint;
begin
if x<y then exit(y)
else exit(x);
end;
function qgcd(x,y:longint):longint;
begin
if y=0 then exit(x)
else exit(qgcd(y,x mod y));
end;
function bfs(v:longint):longint;
var
maxdist,mindist,head,tail,x:longint;
p:edge;
begin
head:=1;
tail:=1;
dl[1]:=v;
visit[v]:=true;
dist[v]:=0;
maxdist:=0;
mindist:=0;
while head<=tail do
begin
x:=dl[head];
p:=con[x];
while p<>nil do
begin
if visit[p^.t] then gcd:=qgcd(dist[x]-dist[p^.t]+p^.w,gcd)
else
begin
visit[p^.t]:=true;
inc(tail);
dl[tail]:=p^.t;
dist[p^.t]:=dist[x]+p^.w;
maxdist:=max(maxdist,dist[p^.t]);
mindist:=min(mindist,dist[p^.t]);
end;
p:=p^.next;
end;
inc(head);
end;
exit(maxdist-mindist+1);
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
ins(x,y,1);
ins(y,x,-1);
end;
gcd:=0;
fillchar(visit,sizeof(visit),0);
for i:=1 to n do
if not visit[i] then inc(sum,bfs(i));
gcd:=abs(gcd);
if gcd>0 then
begin
if gcd<3 then writeln(-1,' ',-1)
else
begin
for i:=3 to gcd do
if gcd mod i=0 then break;
writeln(gcd,' ',i);
end;
end
else
begin
if sum<3 then writeln(-1,' ',-1)
else writeln(sum,' ',3);
end;
end.