_tree_collect.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:12k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _tree_collect.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. // dyna_trees.c
  12. #include <LEDA/tree_collection.h>
  13. #define BIG MAXFLOAT
  14. void dyna_trees::splay(d_vertex x) {
  15.      d_vertex y, z, zz, a, b, c, d;
  16.      double   mincost_a,
  17.       mincost_b,
  18.       mincost_c,
  19.       mincost_d,
  20.       mincost_x,
  21.       mincost_y,
  22.       mincost_z,
  23.       
  24.       cost_x,
  25.       cost_y,
  26.       cost_z;
  27.      
  28.      while (x->parent) {
  29.   // splay-step : 
  30.   y=x->parent; // Vater von x
  31.   z=y->parent; // Grossvater von x (oder 0)
  32.   zz = (z==0) ? 0 : z->parent; // Urgrossvater von z (oder 0)
  33.   // 1.Fall: x hat Vater, aber keinen Grossvater
  34.   if (z==0){ 
  35. if (y->left==x) { 
  36.     // x wurzel des linken unterbaums  (1)
  37.     a=x->left;
  38.     b=x->right;
  39.     c=y->right;
  40.     x->parent=0;
  41.     x->right=y;
  42.     y->parent=x;
  43.     y->left=b;
  44.     if (b) b->parent=y;
  45.     x->successor=y->successor;
  46.     y->successor=0;
  47.     mincost_a = (a) ? a->dmin + x->dmin + y->dmin : BIG;
  48.     mincost_b = (b) ? b->dmin + x->dmin + y->dmin : BIG;
  49.     mincost_c = (c) ? c->dmin + y->dmin : BIG;
  50.     mincost_x = x->dmin + y->dmin;
  51.     mincost_y = y->dmin;
  52.     cost_x = x->dcost + mincost_x;
  53.     cost_y = y->dcost + mincost_y;
  54.     
  55.     mincost_x = mincost_y;
  56.     mincost_y = (mincost_b <= mincost_c) ? mincost_b : mincost_c;
  57.     if (cost_y <= mincost_y) mincost_y = cost_y;
  58.     x->dcost = cost_x - mincost_x;
  59.     y->dcost = cost_y - mincost_y;
  60.     x->dmin  = mincost_x;
  61.     y->dmin  = mincost_y - mincost_x;
  62.     if (a) a->dmin  = mincost_a - mincost_x;
  63.     if (b) b->dmin  = mincost_b - mincost_y;
  64.     if (c) c->dmin  = mincost_c - mincost_y;
  65. }
  66. else {
  67.     // x wurzel des rechten unterbaums (2)
  68.     a=y->left;
  69.     b=x->left;
  70.     c=x->right;
  71.     x->parent=0;
  72.     x->left=y;
  73.     y->parent=x;
  74.     y->right=b;
  75.     if (b) b->parent=y;
  76.     
  77.     x->successor=y->successor;
  78.     y->successor=0;
  79.     
  80.     mincost_a = (a) ? a->dmin + y->dmin : BIG;
  81.     mincost_b = (b) ? b->dmin + x->dmin + y->dmin : BIG;
  82.     mincost_c = (c) ? c->dmin + x->dmin + y->dmin : BIG;
  83.     mincost_x = x->dmin + y->dmin;
  84.     mincost_y = y->dmin;
  85.     cost_x = x->dcost + mincost_x;
  86.     cost_y = y->dcost + mincost_y;
  87.     
  88.     mincost_x = mincost_y;
  89.     mincost_y = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  90.     if (cost_y <= mincost_y) mincost_y = cost_y;
  91.     x->dcost = cost_x - mincost_x;
  92.     y->dcost = cost_y - mincost_y;
  93.     x->dmin  = mincost_x;
  94.     y->dmin  = mincost_y - mincost_x;
  95.     if (a) a->dmin  = mincost_a - mincost_y;
  96.     if (b) b->dmin  = mincost_b - mincost_y;
  97.     if (c) c->dmin  = mincost_c - mincost_x;        
  98. }
  99. continue;
  100.   }
  101.   
  102.   // 2.Fall: x hat also Grossvater, x und parGenPtr(x) linke (rechte)
  103.   //    Soehne.
  104.   // Linke Soehne:
  105.   if ((z->left==y)&&(y->left==x)){   //  (3)
  106. a=x->left;
  107. b=x->right;
  108. c=y->right;
  109. d=z->right;
  110. y->left=b;
  111. if (b) b->parent=y;
  112. z->left=c;
  113. if (c) c->parent=z;
  114. x->right=y;
  115. y->parent=x;
  116. y->right=z;
  117. z->parent=y;
  118. if (zz) {
  119.     if (zz->left==z){
  120.  zz->left=x;
  121.     }
  122.     else{
  123.  zz->right=x;
  124.     }
  125. }
  126. else {  //  z is solid-tree-root
  127.     x->successor=z->successor;
  128.     z->successor=0;
  129. x->parent=zz;
  130. mincost_a = (a) ? a->dmin + x->dmin + y->dmin + z->dmin : BIG;
  131. mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  132. mincost_c = (c) ? c->dmin + y->dmin + z->dmin : BIG;
  133. mincost_d = (d) ? d->dmin + z->dmin : BIG;
  134. mincost_x =  x->dmin + y->dmin + z->dmin;
  135. mincost_y =  y->dmin + z->dmin;
  136. mincost_z =  z->dmin;
  137. cost_x  = mincost_x + x->dcost;
  138. cost_y  = mincost_y + y->dcost;
  139. cost_z  = mincost_z + z->dcost;
  140. mincost_x = mincost_z;
  141. mincost_z = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  142. if (cost_z <= mincost_z) mincost_z = cost_z;
  143. mincost_y = (mincost_b <= mincost_z) ? mincost_b : mincost_z;
  144. if (cost_y <= mincost_y) mincost_y = cost_y;
  145. x->dcost = cost_x - mincost_x;
  146. y->dcost = cost_y - mincost_y;
  147. z->dcost = cost_z - mincost_z;
  148. x->dmin = mincost_x;
  149. y->dmin = mincost_y - mincost_x;
  150. z->dmin = mincost_z - mincost_y;
  151. if (a) a->dmin = mincost_a - mincost_x;
  152. if (b) b->dmin = mincost_b - mincost_y;
  153. if (c) c->dmin = mincost_c - mincost_z;
  154. if (d) d->dmin = mincost_d - mincost_z;
  155. continue;
  156.   }
  157.   
  158.   // Rechte Soehne:   (4)
  159.   
  160.   if ((z->right==y)&&(y->right==x)){
  161. a=z->left;
  162. b=y->left;
  163. c=x->left;
  164. d=x->right;
  165. z->right=b;
  166. if (b) b->parent=z;
  167. z->parent=y;
  168. y->left=z;
  169. y->right=c;
  170. if (c) c->parent=y;
  171. y->parent=x;
  172. x->left=y;
  173. if (zz) {
  174.     if (zz->left==z){
  175.  zz->left=x;
  176.     }
  177.     else{
  178.  zz->right=x;
  179.     }
  180. }
  181. else { 
  182.     x->successor=z->successor;
  183.     z->successor=0;
  184. }
  185. x->parent=zz;
  186. mincost_a = (a) ? a->dmin + z->dmin : BIG;
  187. mincost_b = (b) ? b->dmin + y->dmin + z->dmin : BIG;
  188. mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  189. mincost_d = (d) ? d->dmin + x->dmin + y->dmin + z->dmin : BIG;
  190. mincost_x =  x->dmin + y->dmin + z->dmin;
  191. mincost_y =  y->dmin + z->dmin;
  192. mincost_z =  z->dmin;
  193. cost_x  = mincost_x + x->dcost;
  194. cost_y  = mincost_y + y->dcost;
  195. cost_z  = mincost_z + z->dcost;
  196. mincost_x = mincost_z;
  197. mincost_z = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  198. if (cost_z <= mincost_z) mincost_z = cost_z;
  199. mincost_y = (mincost_c <= mincost_z) ? mincost_c : mincost_z;
  200. if (cost_y <= mincost_y) mincost_y = cost_y;
  201. x->dcost = cost_x - mincost_x;
  202. y->dcost = cost_y - mincost_y;
  203. z->dcost = cost_z - mincost_z;
  204. x->dmin = mincost_x;
  205. y->dmin = mincost_y - mincost_x;
  206. z->dmin = mincost_z - mincost_y;
  207. if (a) a->dmin = mincost_a - mincost_z;
  208. if (b) b->dmin = mincost_b - mincost_z;
  209. if (c) c->dmin = mincost_c - mincost_y;
  210. if (d) d->dmin = mincost_d - mincost_x;
  211. continue;
  212.   }
  213.   
  214.   // 3.Fall: x linkes, p(x) rechtes Kind (oder umgekehrt)
  215.   // Zuerst x links, p(x) rechts:
  216.   
  217.   if ((z->right==y)&&(y->left==x)){   // (5)
  218. a=z->left;
  219. b=x->left;
  220. c=x->right;
  221. d=y->right;
  222. z->right=b;
  223. if (b) b->parent=z;
  224. z->parent=x;
  225. x->left=z;
  226. y->left=c;
  227. if (c) c->parent=y;
  228. y->parent=x;
  229. x->right=y;
  230. if (zz) {
  231.     if (zz->left==z){
  232.  zz->left=x;
  233.     }
  234.     else{
  235.  zz->right=x;
  236.     }
  237. else {
  238.     x->successor=z->successor;
  239.     z->successor=0;
  240. }
  241. x->parent=zz;
  242. mincost_a = (a) ? a->dmin + z->dmin : BIG;
  243. mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  244. mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  245. mincost_d = (d) ? d->dmin + y->dmin + z->dmin : BIG;
  246. mincost_x =  x->dmin + y->dmin + z->dmin;
  247. mincost_y =  y->dmin + z->dmin;
  248. mincost_z =  z->dmin;
  249. cost_x  = mincost_x + x->dcost;
  250. cost_y  = mincost_y + y->dcost;
  251. cost_z  = mincost_z + z->dcost;
  252. mincost_x = mincost_z;
  253. mincost_z = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  254. if (cost_z <= mincost_z) mincost_z = cost_z;
  255. mincost_y = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  256. if (cost_y <= mincost_y) mincost_y = cost_y;
  257. x->dcost = cost_x - mincost_x;
  258. y->dcost = cost_y - mincost_y;
  259. z->dcost = cost_z - mincost_z;
  260. x->dmin = mincost_x;
  261. y->dmin = mincost_y - mincost_x;
  262. z->dmin = mincost_z - mincost_x;
  263. if (a) a->dmin = mincost_a - mincost_z;
  264. if (b) b->dmin = mincost_b - mincost_z;
  265. if (c) c->dmin = mincost_c - mincost_y;
  266. if (d) d->dmin = mincost_d - mincost_y;
  267. continue;
  268.   }
  269.   
  270.   // Nun x rechts, p(x) links:
  271.   
  272.   if ((z->left==y)&&(y->right==x)){ // (6)
  273. a=y->left;
  274. b=x->left;
  275. c=x->right;
  276. d=z->right;
  277. y->right=b;
  278. if (b) b->parent=y;
  279. y->parent=x;
  280. x->left=y;
  281. z->left=c;
  282. if (c) c->parent=z;
  283. z->parent=x;
  284. x->right=z;
  285. if (zz) {
  286.     if (zz->left==z){
  287.  zz->left=x;
  288.     }
  289.     else{
  290.  zz->right=x;
  291.     }
  292. }
  293. else {
  294.     x->successor=z->successor;
  295.     z->successor=0;
  296. }
  297. x->parent=zz;
  298. mincost_a = (a) ? a->dmin + y->dmin + z->dmin : BIG;
  299. mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  300. mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  301. mincost_d = (d) ? d->dmin + z->dmin : BIG;
  302. mincost_x =  x->dmin + y->dmin + z->dmin;
  303. mincost_y =  y->dmin + z->dmin;
  304. mincost_z =  z->dmin;
  305. cost_x  = mincost_x + x->dcost;
  306. cost_y  = mincost_y + y->dcost;
  307. cost_z  = mincost_z + z->dcost;
  308. mincost_x = mincost_z;
  309. mincost_z = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  310. if (cost_z <= mincost_z) mincost_z = cost_z;
  311. mincost_y = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  312. if (cost_y <= mincost_y) mincost_y = cost_y;
  313. x->dcost = cost_x - mincost_x;
  314. y->dcost = cost_y - mincost_y;
  315. z->dcost = cost_z - mincost_z;
  316. x->dmin = mincost_x;
  317. y->dmin = mincost_y - mincost_x;
  318. z->dmin = mincost_z - mincost_x;
  319. if (a) a->dmin = mincost_a - mincost_y;
  320. if (b) b->dmin = mincost_b - mincost_y;
  321. if (c) c->dmin = mincost_c - mincost_z;
  322. if (d) d->dmin = mincost_d - mincost_z;
  323.   }
  324.      }
  325. }
  326. d_vertex dyna_trees::assemble(d_vertex u, d_vertex v, d_vertex w)
  327. {
  328.      double mincost_u,
  329.     mincost_v,
  330.     mincost_w,
  331.     cost_v;
  332.      v->left=u;
  333.      v->right=w;
  334.      if (u) u->parent=v;
  335.      if (w) w->parent=v;
  336.      
  337.      mincost_u = (u) ? u->dmin : BIG;
  338.      mincost_v =       v->dmin;
  339.      mincost_w = (w) ? w->dmin : BIG;
  340.      cost_v = mincost_v + v->dcost;
  341.      
  342.      mincost_v = (mincost_u <= mincost_w) ? mincost_u : mincost_w;
  343.      if (cost_v < mincost_v) mincost_v = cost_v;
  344.      v->dcost = cost_v - mincost_v;
  345.      v->dmin = mincost_v;
  346.      if (u) u->dmin = mincost_u - mincost_v;
  347.      if (w) w->dmin = mincost_w - mincost_v;
  348.      return v;
  349. }
  350. void   dyna_trees::disassemble(d_vertex v, d_vertex& v1, d_vertex& v2) {
  351.      double mincost_v1,
  352.     mincost_v2;
  353.      v1=v->left;
  354.      v2=v->right;
  355.      if (v1) v1->parent=0;
  356.      if (v2) v2->parent=0;
  357.      v->left=0;
  358.      v->right=0;
  359.      mincost_v1 = (v1) ? v1->dmin + v->dmin : BIG;
  360.      mincost_v2 = (v2) ? v2->dmin + v->dmin : BIG;
  361.      if (v1) v1->dmin = mincost_v1;
  362.      if (v2) v2->dmin = mincost_v2;
  363.      
  364.      v->dmin += v->dcost;
  365.      v->dcost = 0;
  366. }
  367. d_vertex dyna_trees::makepath(void* i)
  368. {
  369.      if (first==0) {
  370.   first=last=new d_node(i);
  371.      }
  372.      else {
  373.   last->next=new d_node(i);
  374.   last=last->next;
  375.      }
  376.      return last;
  377. }
  378. d_vertex dyna_trees::findpath(d_vertex v)
  379. {
  380.      splay(v);
  381.      return v;
  382. }
  383. d_vertex dyna_trees::findpathcost(d_path p, double& d)
  384. {
  385.      d_vertex w;
  386.      w=p;
  387.      
  388.      while( !( (w->dcost==0) && ( (w->right==0)||(w->right->dmin>0) ) ) ) {
  389.   if (w->right) {
  390. if (w->right->dmin == 0) {
  391.      w=w->right;
  392. } else {
  393.      if (w->dcost>0) w=w->left;
  394. }  
  395.   }
  396.   else {
  397. if (w->dcost>0) w=w->left;
  398.   }
  399.      }
  400.      splay(w);
  401.      d=w->dmin;
  402.      return w;
  403. }
  404. d_vertex dyna_trees::findtail(d_path p)
  405. {
  406.      d_vertex w;
  407.      w=p;
  408.      
  409.      while(w->right) {
  410.   w=w->right;
  411.      }
  412.      splay(w);
  413.      return w;
  414. }
  415. void dyna_trees::addpathcost(d_path p, double x)
  416. {
  417.      p->dmin += x;
  418. }
  419. d_vertex dyna_trees::join(d_path p, d_path v, d_path q)
  420. {
  421.      return assemble(p, v, q);
  422. }
  423. void dyna_trees::split(d_vertex v, d_vertex& v1, d_vertex& v2)
  424. {
  425.      splay(v);
  426.      disassemble(v, v1, v2);
  427. }
  428. d_path dyna_trees::expose(d_vertex v)
  429. {
  430.      d_path   p,
  431.       q,
  432.       r;
  433.      d_vertex w;
  434.      
  435.      p=0;
  436.      while (v) {
  437.   w=findpath(v)->successor;
  438.   split(v,q,r);
  439.   if (q) q->successor=v;
  440.   p=join(p, v, r);
  441.   v=w;
  442.      }
  443.      p->successor=0;
  444.      return p;
  445. }
  446. d_vertex dyna_trees::maketree(void* i)
  447. {
  448.      copy_inf(i);
  449.      d_vertex v;
  450.      v=makepath(i);
  451.      v->successor=0;
  452.      return v;
  453. }
  454. d_vertex dyna_trees::findroot(d_vertex v)
  455. {
  456.      return findtail(expose(v));
  457. }
  458. d_vertex dyna_trees::findcost(d_vertex v, double& d)
  459. {
  460.      return findpathcost(expose(v),d);
  461. }
  462. void dyna_trees::addcost(d_vertex v, double x)
  463. {
  464.      addpathcost(expose(v),x);
  465. }
  466. void dyna_trees::link(d_vertex v, d_vertex w)
  467. {
  468.      join( (d_vertex) 0, expose(v), expose(w) )->successor=0;
  469. }
  470. void dyna_trees::cut(d_vertex v) 
  471. {
  472.      d_path p,q;
  473.      
  474.      expose(v);
  475.      split(v,p,q);
  476.      v->successor=q->successor=0;
  477. }
  478. dyna_trees::~dyna_trees()
  479. {
  480.      d_node *x, 
  481.     *y;
  482.   
  483.      x=first;
  484.      while(x) {
  485.   y=x->next;
  486.   delete x;
  487.   x=y;
  488.      }
  489. }
  490.