# bzoj1064

1. 有环 2.两点间有多条路径 3.其他

3.显然最简单，最小是3，最大是每个弱联通块中最长链

2.显然，两点间两条路径的差是答案的倍数

1.出现环，那答案一定是其约数，那么最大答案就是所有环长的最大公约数，最小是最大的大于等于3的最小因数

  1 type node=record
2        po,next,num:longint;
3      end;
4
5 var e:array[0..4000010] of node;
6     p,d:array[0..200010] of longint;
7     v:array[0..200010] of boolean;
8     mi,i,l,r,n,m,len,ans,x,y:longint;
9
10 function min(a,b:longint):longint;
11   begin
12     if a>b then exit(b) else exit(a);
13   end;
14
15 function max(a,b:longint):longint;
16   begin
17     if a>b then exit(a) else exit(b);
18   end;
19
20 function gcd(a,b:longint):longint;
21   begin
22     if b=0 then exit(a)
23     else exit(gcd(b,a mod b));
24   end;
25
27   begin
28     inc(len);
29     e[len].po:=y;
30     e[len].num:=z;
31     e[len].next:=p[x];
32     p[x]:=len;
33   end;
34
35 procedure dfs(x:longint);
36   var i,y:longint;
37   begin
38     v[x]:=true;
39     i:=p[x];
40     while i<>-1 do
41     begin
42       y:=e[i].po;
43       if v[y] then ans:=gcd(ans,abs(d[x]+e[i].num-d[y]))
44       else begin
45         d[y]:=d[x]+e[i].num;
46         dfs(y);
47       end;
48       i:=e[i].next;
49     end;
50   end;
51
52 procedure find(x:longint);
53   var i,y:longint;
54   begin
55     v[x]:=true;
56     l:=min(l,d[x]);
57     r:=max(r,d[x]);
58     i:=p[x];
59     while i<>-1 do
60     begin
61       y:=e[i].po;
62       if not v[y] then
63       begin
64         d[y]:=d[x]+e[i].num;
65         find(y);
66       end;
67       i:=e[i].next;
68     end;
69   end;
70
71 begin
72   len:=-1;
73   fillchar(p,sizeof(p),255);
75   for i:=1 to m do
76   begin
80   end;
81   for i:=1 to n do
82     if not v[i] then dfs(i);
83   if ans<>0 then
84   begin
85     mi:=ans;
86     for i:=3 to ans do
87       if ans mod i=0 then
88       begin
89         mi:=i;
90         break;
91       end;
92   end
93   else begin
94     fillchar(v,sizeof(v),false);
95     for i:=1 to n do
96       if not v[i] then
97       begin
98         d[i]:=0;
99         l:=0;  r:=0;
100         find(i);
101         ans:=ans+r-l+1;
102       end;
103
104     mi:=3;
105   end;
106   if ans<3 then writeln('-1 -1') else writeln(ans,' ',mi);
107 end.
View Code

posted on 2015-06-20 15:49  acphile  阅读(89)  评论(0编辑  收藏