| 个人资料Thunder is thunderstruck...照片日志列表 | 帮助 |
|
2月11日 Network Flow & Related Problems 网络流和相关问题 问题 例 算法: 这是算法的伪代码: 4 总流 = 0 5 WHIEL (TRUE) 13 WHILE (TRUE) 32 路径容量 = flow(汇点) # 把那个流加到网络里 适当调整容量 这个方法的运行时间为O(FM),F是最大流 M是弧的数目. 运行时间通常更短, 因为算法每次总是尽可能大的提升流。 为了确定每条弧上的流,比较开始的容量和最后的容量。如果最后的容量变少了,区别就在于通过这条弧的流。 当有回路的时候,这个算法可能产生死循环。 实例 扩展 扩展到无向图,只需要简单的把无限边扩展为两条相反方向的弧就可以了。 如果您想要限制任意一个节点的通过量,把一个节点拆成两个,一个流入节点,一个流出节点,把流入的弧连到流入节点里,流出弧连到流出节点里,在流入节点和流出节点之间加上一条弧,容量为限制。 如果您有多源点汇点,建立一个虚拟的源点和虚拟的汇点,虚拟的源点射出弧到每个源点,汇点射出弧到虚拟汇点。容量无限。 如果您有实数型的权,这个问题不再保证能出解,尽管答案能逐渐逼近。 可选问题 最大匹配 把这个问题用网络流的形式表现出来,建立一个源点,射出容量为1的弧给A的元素,建立一个汇点,B中的元素射出容量为1的弧。另外,如果A中某个元素可以和B中某个元素匹配,从A的这个元素向B的那个元素射出一条容量为1的弧。用网络流算法确定哪些A元素到B元素的弧被用到。 最小的权和就是两个节点之间的流。 要确定路径,按照权递增的顺序尝试删除每条边,看它是否减少了网络流,减少量为边的容量。第一个这样的边就是最小割的元素,去掉这条边继续在图上操作。 用相同的技巧,把节点用容量限制,这能够扩展到求节点的割。有向图也是一样。然而,它不能够解决所谓的“最佳匹配”问题,每一对都有一个“佳值”,而且您想要得到最高“佳值”和的匹配。 例题 这就是最小割问题。 牛的电话联系(USACO 锦标赛 1996) 这相当于最少节点割的问题。两台给出的电脑标上源点和汇点。电缆是双向的。把每个点拆成流入点和流出点,这样我们就能够用1限制任何一台电脑。现在,网络里的最大流就相当于节点最小割了。 为了具体确定割,反复删除节点,直到您找到一个能降低网络流量的节点。 这是一个很类似最大匹配的问题,除了每个学科需要可能多于一个裁判。解决这个问题的最简单的方法是把从科目到汇点的弧的容量赋予需要裁判数的值。 要解决这个问题,对于距离10英里以内的每一对交点,添加一条管道,再计算从朱诺到费尔班柯斯的流量增加值。每一个子问题都是最大流。
2月1日 USACO Chapter4Chapter 4 4.1 cryptcow Cryptcowgraphy 4.1 ariprog Arithmetic Progressions 4.2 ditch Drainage Ditches 4.2 stall4 The Perfect Stall 4.2 buylow Buy Low, Buy Lower 4.2 job Job Processing 4.2 frameup Frame Up 4.3 prime3 the Primes 4.3 prefix Longest Prefix 4.3 cowcycle Cowcycles 4.3 shopping Shopping Offers 4.3 race3 Street Race 4.4 spin Spinning Wheels 4.4 shuttle Shuttle Puzzle 4.4 milk6 Pollutant Control Splay Tree{
A little bug: It always destroys the balanced Tree..... } Type
SplayTree = ^Node; Node = Record Value: Longint; Lc, Rc, P: SplayTree; End; Var
Root: SplayTree; Procedure Init(tmp: Longint);
Begin
New(Root); Root^.Value := tmp; Root^.Lc := Nil; Root^.Rc := Nil; Root^.P := Nil; End; Function Find(S: Longint; T: SplayTree): SplayTree;
// Try to Find the node whose Value equals S Begin
If T = Nil Then Exit(Nil); If T^.Value < S Then
Exit(Find(S, T^.Rc)); If T^.Value > S Then Exit(Find(S, T^.Lc)); Exit(T);
End; Procedure Zig(T: SplayTree);
//Sift Up the First Left Child Begin
Root^.Lc := T^.Rc; If Root^.Lc <> Nil Then Root^.Lc^.P := Root; T^.Rc := Root; T^.Rc^.P := T; T^.P := Nil; Root := T; End; Procedure Zag(T: SplayTree);
//Sift Up the First Right Child Begin
Root^.Rc := T^.Lc; If Root^.Rc <> Nil Then Root^.Rc^.P := Root; T^.Lc := Root; T^.Lc^.P := T; T^.P := Nil; Root := T; End; Procedure ZigZig(T: SplayTree);
//Sift Up the Second Left Child Var
Y, Z: SplayTree; Begin
Y := T^.P; Z := T^.P^.P; If Z = Root Then Root := T Else If Z^.P^.Lc = Z Then Z^.P^.Lc := T ELse Z^.P^.Rc := T; T^.P := Z^.P; Y^.P := T; Z^.P := Y; Y^.Lc := T^.Rc; If Y^.Lc <> Nil Then Y^.Lc^.P := Y; T^.Rc := Y; Z^.Lc := Y^.Rc; If Z^.Lc <> Nil Then Z^.Lc^.P := Z; Y^.Rc := Z; End; Procedure ZagZag(T: SplayTree);
//Sift Up the Second Right Child Var
Y, Z: SplayTree; Begin
Y := T^.P; Z := T^.P^.P; If Z = Root Then Root := T Else If Z^.P^.Lc = Z Then Z^.P^.Lc := T ELse Z^.P^.Rc := T; T^.P := Z^.P; Y^.P := T; Z^.P := Y; Y^.Rc := T^.Lc; If Y^.Rc <> Nil Then Y^.Rc^.P := Y; T^.Lc := Y; Z^.Rc := Y^.Lc; If Z^.Rc <> Nil Then Z^.Rc^.P := Z; Y^.Lc := Z; End; Procedure ZigZag(T: SplayTree);
//Sift Up the Right Child's Left Child Var
Y, Z: SplayTree; Begin
Y := T^.P; Z := Y^.P; If Z = Root Then Root := T Else If Z^.P^.Lc = Z Then Z^.P^.Lc := T Else Z^.P^.Rc := T; T^.P := Z^.P; Y^.P := T; Z^.P := T; Z^.Rc := T^.Lc; If Z^.Rc <> Nil Then Z^.Rc^.P := Z; Y^.Lc := T^.Rc; If Y^.Lc <> Nil Then Y^.Lc^.P := Y; T^.Lc := Z; T^.Rc := Y; End; Procedure ZagZig(T: SplayTree);
//Sift Up the Left Child's Right Child Var
Y, Z: SplayTree; Begin
Y := T^.P; Z := Y^.P; If Z = Root Then Root := T Else If Z^.P^.Lc = Z Then Z^.P^.Lc := T Else Z^.P^.Rc := T; T^.P := Z^.P; Y^.P := T; Z^.P := T; Z^.Lc := T^.Rc; If Z^.Lc <> Nil Then Z^.Lc^.P := Z; Y^.Rc := T^.Lc; If Y^.Rc <> Nil Then Y^.Rc^.P := Y; T^.Rc := Z; T^.Lc := Y; End; Procedure Splay(T: SplayTree);
//Splay.... Ouch.... Begin
If T = Nil Then Exit; While T <> Root Do Begin If T^.P = Root Then If Root^.Lc = T Then Zig(T) Else Zag(T) Else If T^.P^.Lc = T Then If T^.P^.P^.Lc = T^.P Then ZigZig(T) Else ZigZag(T) Else If T^.P^.P^.Rc = T^.P Then ZagZag(T) Else ZagZig(T); End; End; Procedure Ins(S: Longint);
//Insert a Node whose Value equals S Var
T: SplayTree; Begin
If Root = Nil Then Begin Init(S); Exit; End; T := Root;
While true Do
Begin If T = nil Then Break; If T^.Value <= S Then
If T^.Rc <> nil Then T := T^.Rc Else Begin New(T^.Rc); T^.Rc^.Value := S; T^.Rc^.P := T; T^.Rc^.Lc := nil; T^.Rc^.Rc := nil; Splay(T^.Rc); Break; End Else
If T^.Lc <> nil Then T := T^.Lc Else Begin New(T^.Lc); T^.Lc^.Value := S; T^.Lc^.P := T; T^.Lc^.Lc := nil; T^.Lc^.Rc := nil; Splay(T^.Lc); Break; End; End; End; Function Max(T: SplayTree): SplayTree;
//get the maximum node in the tree whose root is T Begin While T^.Rc <> Nil Do T := T^.Rc; Exit(T); End; Procedure Del(S: Longint);
//Delete a Node whose Value equals S Var
T, tmp: SplayTree; Begin
T := Find(S, Root); If T = Nil Then Exit; If (T^.Lc = Nil) Then
// no left child If (T^.Rc = Nil) Then
// it's the leaf If T^.P = Nil Then
Root := Nil Else Begin If T^.P^.Lc = T Then T^.P^.Lc := Nil Else T^.P^.Rc := Nil; End Else
//only right child If T^.P = Nil Then Begin Root := T^.Rc; T^.Rc^.P := Nil; End Else If T^.P^.Lc = T Then Begin T^.P^.Lc := T^.Rc; T^.Rc^.P := T^.P; End Else Begin T^.P^.Rc := T^.Rc; T^.Rc^.P := T^.P; End // have left child
Else If (T^.Rc = Nil) Then //only left child If T^.P = Nil Then Begin Root := T^.Lc; T^.Lc^.P := Nil; End Else If T^.P^.Lc = T Then Begin T^.P^.Lc := T^.Lc; T^.Lc^.P := T^.P; End Else Begin T^.P^.Rc := T^.Lc; T^.Lc^.P := T^.P; End Else // both left and right child Begin tmp := Max(T^.Lc); If Root = T Then
Begin Root := T^.Lc; Root^.P := Nil; End Else Begin T^.Lc^.P := T^.P; If T^.P^.Lc = T Then T^.P^.Lc := T^.Lc Else T^.P^.Rc := T^.Lc; End; tmp^.Rc := T^.Rc;
T^.Rc^.P := tmp; Splay(tmp); End; End;
Procedure Mid_Visit(T: SplayTree);
Begin
If T = Nil Then Exit; If T^.Lc <> Nil Then Mid_Visit(T^.Lc); write(T^.Value,' '); If T^.Rc <> Nil Then Mid_visit(T^.Rc); End; Procedure Main; //Do whatever you wanna do Var i, tmp, n, m: Longint; Begin
assign(input,'data.in'); reset(input); read(n); For i := 1 To n Do Begin Read(tmp); Ins(tmp); End; Read(m);
For i := 1 To m Do Begin Read(tmp); Del(tmp); End; assign(output,'data.out');
rewrite(output); Mid_Visit(Root); close(output); End; Begin Main; End. 写了一个TreapType Function Random_Rank: longint; Begin Procedure Init(tmp: longint); Begin Procedure Rotation_Left(T: Treap); Var Begin Procedure Rotation_Right(T: Treap); Var Begin Procedure Turn(T: Treap); Begin Procedure Ins(S: longint); Var Begin tmp := Root; While true Do If tmp^.Value <= S Then Else Function Find(S: longint; T: Treap): Treap; Begin If T^.Value > S Then Exit(T); Procedure Del(S: longint); Var Begin tmp^.Rank := MaxLongint; While (tmp^.Lc <> Nil) Or (tmp^.Rc <> Nil) Do If tmp^.P = Nil Then Procedure Mid_Visit(T: Treap); Begin Procedure Main; Var Begin For i := 1 To n Do read(m); assign(output,'data.out'); Begin 1月29日 俺又回来啦看左边和右边
是不是多了两个列表
hoho 可以自己直接找文件了
自己写的code没公布 因为.... 越看越垃圾...................................... |
||||
|
|