# BZOJ1016 [JSOI2008]最小生成树计数

  1 /**************************************************************
2     Problem: 1016
3     User: rausen
4     Language: Pascal
5     Result: Accepted
6     Time:8 ms
7     Memory:344 kb
8 ****************************************************************/
9
10 {\$inline on}
11
12 const prime = 31011;
13
14 var
15   n, m, k, t : longint;
16   i, x, y, z : longint;
17   count, ans : longint;
18   a, b, c, p, cnt, fa : array[0..5000] of longint;
19   flag : boolean;
20
21 procedure add_edge(x, y, z : longint); inline;
22 begin
23   inc(t);
24   a[t] := x;
25   b[t] := y;
26   c[t] := z;
27 end;
28
29 procedure swap(x, y : longint); inline;
30 var
31   t : longint;
32
33 begin
34   t := a[x]; a[x] := a[y]; a[y] := t;
35   t := b[x]; b[x] := b[y]; b[y] := t;
36   t := c[x]; c[x] := c[y]; c[y] := t;
37 end;
38
39 procedure qsort(l, r : longint);
40 var
41   i, j, x : longint;
42
43 begin
44   i := l;
45   j := r;
46   x := c[(i + j) shr 1];
47   repeat
48     while c[i] < x do inc(i);
49     while c[j] > x do dec(j);
50     if i <= j then begin
51       swap(i, j);
52       inc(i);
53       dec(j);
54     end;
55   until i > j;
56   if i < r then qsort(i, r);
57   if l < j then qsort(l, j);
58 end;
59
60 function find_fa(x : longint) : longint;
61 var
62   f : longint;
63
64 begin
65   f := fa[x];
66   if f = x then exit(f);
67   f := find_fa(f);
68   fa[x] := f;
69   exit(f);
70 end;
71
72 procedure make_mst;
73 var
74   i, j, f1, f2 : longint;
75
76 begin
77   for i := 1 to n do
78     fa[i] := i;
79   j := 0;
80   fillchar(cnt, sizeof(cnt), 0);
81   for i := 1 to t do begin
82     if c[i] <> c[i - 1] then inc(j);
83     f1 := find_fa(a[i]);
84     f2 := find_fa(b[i]);
85     if f1 <> f2 then begin
86       inc(cnt[j]);
87       fa[f1] := f2;
88     end;
89   end;
90 end;
91
92 function find_f(x : longint) : longint; inline;
93 begin
94   while fa[x] <> x do
95     x := fa[x];
96   exit(x);
97 end;
98
99 procedure sub(l, r, num : longint);
100 var
101   f1, f2 : longint;
102
103 begin
104   if num = 0 then begin
105     inc(count);
106     if count > prime then
107       count := count - prime;
108     exit;
109   end;
110   if l > r then exit;
111   if r - l + 1 > num then sub(l + 1, r, num);
112   f1 := find_f(a[l]);
113   f2 := find_f(b[l]);
114   if f1 <> f2 then begin
115     fa[f1] := f2;
116     sub(l + 1, r, num - 1);
117     fa[f1] := f1;
118   end;
119 end;
120
121 procedure make_ans;
122 var
123   i, j, f1, f2 : longint;
124
125 begin
126   for i := 1 to n do
127     fa[i] := i;
128   ans := 1;
129   for i := 1 to k do begin
130     count := 0;
131     sub(p[i], p[i + 1] - 1, cnt[i]);
132     ans := (ans * count) mod prime;
133     for j := p[i] to p[i + 1] - 1 do begin
134       f1 := find_fa(a[j]);
135       f2 := find_fa(b[j]);
136       if f1 <> f2 then fa[f1] := f2;
137     end;
138   end;
139 end;
140
141 begin
143   for i := 1 to m do begin
146   end;
147   qsort(1, t);
148   p[1] := 1;
149   k := 1;
150   for i := 2 to t do
151     if c[i] <> c[i - 1] then begin
152       inc(k);
153       p[k] := i;
154     end;
155   p[k + 1] := t + 1;
156   make_mst;
157   make_ans;
158   flag := true;
159   for i := 1 to n do
160     if fa[i] = i then
161       if flag then flag := false
162       else begin
163         writeln(0);
164         exit;
165       end;
166   writeln(ans);
167 end.
View Code

posted on 2014-09-30 08:09  Xs酱~  阅读(...)  评论(... 编辑 收藏