学习了一下可合并堆的一种写法——左偏树
感觉左偏树是一种类似启发式的方法
学习左偏树后这题就水过去了

 1 var fa,l,r,a,d:array[0..1000010] of longint;
 2     v:array[0..1000010] of boolean;
 3     i,n,m,x,y,f:longint;
 4     ch:char;
 5 
 6 function getf(x:longint):longint;
 7   begin
 8     if fa[x]<>x then fa[x]:=getf(fa[x]);
 9     exit(fa[x]);
10   end;
11 
12 procedure swap(var a,b:longint);
13   var c:longint;
14   begin
15     c:=a;
16     a:=b;
17     b:=c;
18   end;
19 
20 function merge(x,y:longint):longint;
21   begin
22     if x=0 then exit(y);
23     if y=0 then exit(x);
24     if a[x]>a[y] then swap(x,y);
25     r[x]:=merge(r[x],y);
26     if d[r[x]]>d[l[x]] then swap(l[x],r[x]);
27     d[x]:=d[r[x]]+1;  //d表示这个节点到最近的可插入节点的距离,根据左偏树性质易得
28     exit(x);
29   end;
30 
31 begin
32   readln(n);
33   for i:=1 to n do
34   begin
35     read(a[i]);
36     fa[i]:=i;
37   end;
38   d[0]:=-1;
39   readln(m);
40   for i:=1 to m do
41   begin
42     read(ch);
43     if ch='M' then
44     begin
45       readln(x,y);
46       if v[x] or v[y] then continue;
47       x:=getf(x);
48       y:=getf(y);
49       if x=y then continue;
50       f:=merge(x,y);
51       fa[x]:=f;
52       fa[y]:=f;
53     end
54     else begin
55       readln(x);
56       if v[x] then
57       begin
58         writeln(0);
59         continue;
60       end;
61       x:=getf(x);
62       v[x]:=true;
63       writeln(a[x]);
64       fa[x]:=merge(l[x],r[x]);
65       fa[fa[x]]:=fa[x];
66     end;
67   end;
68 end.
69 
70  
View Code

 

posted on 2015-01-26 17:56  acphile  阅读(120)  评论(0编辑  收藏  举报