# 最小乘积生成树

  1 type
2 ans=record
3 p,q:longint;
4 end;
5 var
6 s,u,v,x,y:array[0..10000] of longint;
7 f:array[0..200] of longint;
8 i,j,k,n:longint;
9 anss,ans1,ans2:ans;
10 o1,o2:int64;
11 procedure swap(var x,y:longint);
12 var
13 w:longint;
14 begin
15     w:=x; x:=y; y:=w;
16 end;
17 procedure sort(l,r:longint);
18 var
19 w,mid,i,j:longint;
20 begin
21     i:=l; j:=r;
22     mid:=s[(l+r) div 2];
23     repeat
24       while s[i]<mid do
25         inc(i);
26       while s[j]>mid do
27         dec(j);
28       if not(i>j) then
29       begin
30           swap(s[i],s[j]);
31           swap(u[i],u[j]);
32           swap(v[i],v[j]);
33           swap(x[i],x[j]);
34           swap(y[i],y[j]);
35           inc(i);
36           dec(j);
37       end;
38     until i>j;
39     if l<j then sort(l,j);
40     if i<r then sort(i,r);
41 end;
42 function find(x:longint):longint;
43 begin
44     if f[x]=x then exit(x);
45     find:=find(f[x]);
46     f[x]:=find;
47 end;
48 function kl:ans;
49 var
50 t,fx,fy,i:longint;
51 sum:ans;
52 begin
53     sort(1,k);
54     for i:=1 to n do f[i]:=i;
55     sum.p:=0; sum.q:=0; t:=0;
56     for i:=1 to k do
57     begin
58         fx:=find(x[i]);
59         fy:=find(y[i]);
60         if fx<>fy then
61         begin
62             f[fx]:=fy;
63             inc(t);
64             sum.p:=sum.p+u[i];
65             sum.q:=sum.q+v[i];
66             if t=n-1 then
67             break;
68         end;
69     end;
70     o1:=anss.p*anss.q;
71     o2:=sum.p*sum.q;
72     if (o1>o2)or((o1=o2)and(anss.p>sum.p)) then
73     anss:=sum;
74     kl:=sum;
75 end;
76 procedure solve(a,b:ans);
77 var
78 aa,bb,cc,i:longint;
79 c:ans;
80 begin
81     aa:=(a.q-b.q);   bb:=(b.p-a.p);  cc:=a.p*b.q-a.q*b.p;
82     for i:=1 to k do
83         s[i]:=u[i]*aa+v[i]*bb;
84     c:=kl;
85     if c.p*aa+c.q*bb+cc>=0 then exit;
86     solve(a,c);
87     solve(c,b);
88 end;
89 begin
91     for i:=1 to k do
92     begin
94         inc(x[i]); inc(y[i]);
95     end;
96     anss.p:=trunc(sqrt(maxlongint)); anss.q:=trunc(sqrt(maxlongint));
97     s:=u; ans1:=kl;
98     s:=v; ans2:=kl;
99     solve(ans1,ans2);
100     writeln(anss.p,' ',anss.q);
101 end.
102 
View Code

(bzoj 2395)

posted @ 2017-03-27 15:37  jkl~  阅读(198)  评论(0编辑  收藏  举报