diff --git a/CMakeLists.txt b/CMakeLists.txt
index a19e3edc920a431faf41d6ab4fcd48bdbd705a4e..2d3b4b8351fa74dc163c0eb4c9d7ea141f1954d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,7 @@ option(ENABLE_ANN "Enable ANN to compute Approximate Nearest Neighbors" ON)
 option(ENABLE_BAMG "Enable Bamg mesh generator" ON)
 option(ENABLE_BFGS "Enable BFGS" ON)
 option(ENABLE_BLAS_LAPACK "Use BLAS/Lapack for basic linear algebra" ON)
+option(ENABLE_BLOSSOM "Enable Blossom algo (based on MATCH and concorde97)" ON)
 option(ENABLE_CGNS "Enable CGNS mesh export" OFF)
 option(ENABLE_CHACO "Enable Chaco mesh partitioner" ON)
 option(ENABLE_DINTEGRATION "Enable discrete integration and levelsets" ON)
@@ -30,7 +31,6 @@ option(ENABLE_FOURIER_MODEL "Enable Fourier geometrical models" OFF)
 option(ENABLE_GMM "Enable GMM linear algebra solvers" ON)
 option(ENABLE_GRAPHICS "Compile-in OpenGL graphics even if there is no GUI" OFF)
 option(ENABLE_KBIPACK "Enable Kbipack for homology solver" ON)
-option(ENABLE_MATCH "Enable Minimum cost perfect matching algo" ON)
 option(ENABLE_MATHEX "Enable MathEx expression parser" ON)
 option(ENABLE_MED "Enable MED mesh and post-processing file formats" ON)
 option(ENABLE_MESH "Build the mesh module" ON)
@@ -445,6 +445,12 @@ if(ENABLE_ANN)
   set_config_option(HAVE_ANN "Ann")
 endif(ENABLE_ANN)
 
+if(ENABLE_BLOSSOM)
+  add_subdirectory(contrib/blossom)
+  include_directories(contrib/blossom/MATCH contrib/blossom/concorde97
+                      contrib/blossom/concorde97/INCLUDE)
+  set_config_option(HAVE_BLOSSOM "Blossom")
+endif(ENABLE_BLOSSOM)
 
 if(ENABLE_CHACO)
   add_subdirectory(contrib/Chaco)
@@ -752,20 +758,6 @@ if(ENABLE_ACIS)
   endif(ACIS_LIB)
 endif(ENABLE_ACIS)
 
-if(ENABLE_MATCH)
-  find_library(MATCH_LIB blossom PATH_SUFFIXES lib)
-  find_library(CONCORDE_LIB concorde PATH_SUFFIXES lib)
-  if(MATCH_LIB AND CONCORDE_LIB)
-    find_path(CONCORDE_INC "concorde.h" PATH_SUFFIXES concorde97)
-    find_path(MATCH_INC "match.h" PATH_SUFFIXES MATCH)
-    if(MATCH_INC AND CONCORDE_INC)	     
-      set_config_option(HAVE_MATCH "Match")
-      list(APPEND EXTERNAL_LIBRARIES ${MATCH_LIB} ${CONCORDE_LIB})
-      list(APPEND EXTERNAL_INCLUDES ${MATCH_INC} ${CONCORDE_INC})
-    endif(MATCH_INC AND CONCORDE_INC)
-  endif(MATCH_LIB AND CONCORDE_LIB)
-endif(ENABLE_MATCH)
-
 if(ENABLE_OSMESA)
   find_library(OSMESA_LIB OSMesa)
   if(OSMESA_LIB)
diff --git a/Common/GmshConfig.h.in b/Common/GmshConfig.h.in
index e1a831ea8d0ff3f10f022be8c2795dc8a5ed260f..30771075fba98347d1ae18c1e9db43bca4e53ec5 100644
--- a/Common/GmshConfig.h.in
+++ b/Common/GmshConfig.h.in
@@ -12,6 +12,7 @@
 #cmakedefine HAVE_BAMG
 #cmakedefine HAVE_BFGS
 #cmakedefine HAVE_BLAS
+#cmakedefine HAVE_BLOSSOM
 #cmakedefine HAVE_CHACO
 #cmakedefine HAVE_DLOPEN
 #cmakedefine HAVE_DINTEGRATION
@@ -26,7 +27,6 @@
 #cmakedefine HAVE_LIBJPEG
 #cmakedefine HAVE_LIBPNG
 #cmakedefine HAVE_LIBZ
-#cmakedefine HAVE_MATCH
 #cmakedefine HAVE_MATHEX
 #cmakedefine HAVE_MED
 #cmakedefine HAVE_MESH
diff --git a/Fltk/statisticsWindow.cpp b/Fltk/statisticsWindow.cpp
index f24de26489f03bfae754657e3f2912366021c592..91800deeadef74ab628ae67f6b3e3f2325c953f4 100644
--- a/Fltk/statisticsWindow.cpp
+++ b/Fltk/statisticsWindow.cpp
@@ -206,6 +206,7 @@ void statisticsWindow::compute(bool elementQuality)
   printf("Angles = min=%g av=%g \n", minAngle, meanAngle);*/
   //hack emi
   //Emi hack - MESH DEGREE VERTICES
+#if 0
   std::vector<GEntity*> entities;
   std::set<MEdge, Less_Edge> edges;
   GModel::current()->getEntities(entities);
@@ -280,6 +281,7 @@ void statisticsWindow::compute(bool elementQuality)
 	}
   }
   fclose(fp);
+#endif
   //emi end hack
 
   int num = 0;
diff --git a/Mesh/meshGFaceOptimize.cpp b/Mesh/meshGFaceOptimize.cpp
index 2ce231bbfbe443527c8b91515c0e8b1d348b6c4b..9a4f7d7ceb7f0010a5de48c7274efbebf851e6af 100644
--- a/Mesh/meshGFaceOptimize.cpp
+++ b/Mesh/meshGFaceOptimize.cpp
@@ -28,7 +28,7 @@
 #include "PViewData.h"
 #endif
 
-#if defined(HAVE_MATCH)
+#if defined(HAVE_BLOSSOM)
 extern "C" int FAILED_NODE;
 extern "C" struct CCdatagroup;
 extern "C" int perfect_match
@@ -1640,7 +1640,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
   std::set<MElement*> touched;
 
   if(CTX::instance()->mesh.algoRecombine == 1){
-#ifdef HAVE_MATCH
+#if defined(HAVE_BLOSSOM)
     int ncount = gf->triangles.size();
     if (ncount % 2 == 0) {
       int ecount =  cubicGraph ? pairs.size() + makeGraphPeriodic.size() : pairs.size();
diff --git a/contrib/blossom/CMakeLists.txt b/contrib/blossom/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c7fe702c323618320ee73a21b479c53e2b68578a
--- /dev/null
+++ b/contrib/blossom/CMakeLists.txt
@@ -0,0 +1,117 @@
+# Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+# concorde97/BIGGUY/bg_test.c
+  concorde97/BIGGUY/bigguy.c
+  concorde97/CUT/connect.c
+  concorde97/CUT/cut_st.c
+# concorde97/CUT/mc_main.c
+  concorde97/CUT/mincut.c
+  concorde97/CUT/segments.c
+  concorde97/CUT/shrink.c
+  concorde97/EDGEGEN/edgegen.c
+# concorde97/EDGEGEN/eg_main.c
+  concorde97/EDGEGEN/xnear.c
+# concorde97/FMATCH/fm_main.c
+  concorde97/FMATCH/fmatch.c
+# concorde97/KDTREE/kd_main.c
+  concorde97/KDTREE/kdbuild.c
+  concorde97/KDTREE/kdnear.c
+  concorde97/KDTREE/kdspan.c
+  concorde97/KDTREE/kdtwoopt.c
+# concorde97/LINKERN/flip_ary.c
+# concorde97/LINKERN/flip_bt0.c
+# concorde97/LINKERN/flip_bt1.c
+# concorde97/LINKERN/flip_bt2.c
+# concorde97/LINKERN/flip_bt3.c
+# concorde97/LINKERN/flip_bt4.c
+# concorde97/LINKERN/flip_bt5.c
+# concorde97/LINKERN/flip_btc.c
+# concorde97/LINKERN/flip_btd.c
+# concorde97/LINKERN/flip_btr.c
+# concorde97/LINKERN/flip_ll0.c
+# concorde97/LINKERN/flip_ll1.c
+# concorde97/LINKERN/flip_ll2.c
+# concorde97/LINKERN/flip_ll3.c
+# concorde97/LINKERN/flip_ll4.c
+# concorde97/LINKERN/flip_ll5.c
+# concorde97/LINKERN/flip_ll6.c
+# concorde97/LINKERN/flip_ll7.c
+  concorde97/LINKERN/flip_ll8.c
+# concorde97/LINKERN/flip_ll9.c
+# concorde97/LINKERN/flip_llA.c
+# concorde97/LINKERN/flip_llB.c
+# concorde97/LINKERN/flip_llC.c
+# concorde97/LINKERN/flip_llD.c
+# concorde97/LINKERN/flip_sg1.c
+# concorde97/LINKERN/flip_sg2.c
+# concorde97/LINKERN/flip_sg3.c
+# concorde97/LINKERN/flip_sp1.c
+# concorde97/LINKERN/flip_sp2.c
+# concorde97/LINKERN/flip_try.c
+# concorde97/LINKERN/flip_tw2.c
+# concorde97/LINKERN/flip_two.c
+  concorde97/LINKERN/linkern.c
+# concorde97/LINKERN/lk_main.c
+# concorde97/LP/lpcplex.c
+  concorde97/LP/lpsolve.c
+  concorde97/TSP/bcontrol.c
+  concorde97/TSP/branch.c
+  concorde97/TSP/cliqhash.c
+  concorde97/TSP/cliqwork.c
+#concorde97/TSP/concorde.c
+  concorde97/TSP/control.c
+  concorde97/TSP/cutcall.c
+  concorde97/TSP/cutpool.c
+  concorde97/TSP/edgemap.c
+  concorde97/TSP/ex_price.c
+  concorde97/TSP/generate.c
+# concorde97/TSP/poolcat.c
+  concorde97/TSP/prob_io.c
+  concorde97/TSP/qsparse.c
+  concorde97/TSP/teething.c
+  concorde97/TSP/tighten.c
+  concorde97/TSP/tsp_lp.c
+  concorde97/TSP/xtour.c
+  concorde97/UTIL/allocrus.c
+  concorde97/UTIL/bgetopt.c
+  concorde97/UTIL/dheaps_i.c
+  concorde97/UTIL/edg2cyc.c
+  concorde97/UTIL/edgelen.c
+  concorde97/UTIL/fastread.c
+  concorde97/UTIL/genhash.c
+  concorde97/UTIL/getdata.c
+  concorde97/UTIL/priority.c
+  concorde97/UTIL/safe_io.c
+  concorde97/UTIL/sortrus.c
+  concorde97/UTIL/urandom.c
+  concorde97/UTIL/util.c
+  concorde97/UTIL/zeit.c
+  concorde97/XSTUFF/Xallcuts.c
+  concorde97/XSTUFF/Xblobs.c
+  concorde97/XSTUFF/Xblock.c
+  concorde97/XSTUFF/Xblossom.c
+  concorde97/XSTUFF/Xcclean.c
+  concorde97/XSTUFF/Xclique.c
+  concorde97/XSTUFF/Xcuthash.c
+  concorde97/XSTUFF/Xcutload.c
+  concorde97/XSTUFF/Xcuts.c
+  concorde97/XSTUFF/Xcututil.c
+  concorde97/XSTUFF/Xflow.c
+  concorde97/XSTUFF/Xgomhu.c
+  concorde97/XSTUFF/Xgraph.c
+  concorde97/XSTUFF/Xnecklac.c
+  concorde97/XSTUFF/Xnewkids.c
+  concorde97/XSTUFF/Xourallo.c
+  concorde97/XSTUFF/Xpqnew.c
+  concorde97/XSTUFF/Xshrink.c
+  concorde97/XSTUFF/Xstuff.c
+# concorde97/XSTUFF/Xtest.c
+  MATCH/match.c MATCH/matprice.c
+)
+
+file(GLOB_RECURSE HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
+append_gmsh_src(contrib/blossom "${SRC};${HDR}")
diff --git a/contrib/blossom/MATCH/00_README b/contrib/blossom/MATCH/00_README
new file mode 100644
index 0000000000000000000000000000000000000000..4cbe57f37537ec09a7ba86e5d833010e03c0c390
--- /dev/null
+++ b/contrib/blossom/MATCH/00_README
@@ -0,0 +1,81 @@
+The file match.tar should consist of the following files:
+
+./MATCH/00_README       this file
+./MATCH/100.dat         example x-y file
+./MATCH/100.edge        example edge-file
+./MATCH/Makefile        gmake Makefile
+./MATCH/mat_main.c      main program for blossom4 code
+./MATCH/match.[ch]      matching routines
+./MATCH/matprice.[ch]   pricing routines
+./MATCH/mp_main.c       main program for price4 code
+./MATCH/tri_call.c      program to call the triangle package
+
+------------------------------------------------------------
+
+Installation:
+
+This package is an add-up to the concorde package written
+by Applegate, Bixby, Chvatal and Cook and which can be 
+found at <http://www.concorde.com/>.
+
+Type 'tar xvf match.tar', the MATCH directory will be created.
+Type 'cd MATCH' to get to the MATCH directory.
+
+To built the programs, first look at the Makefile and insert 
+the right compiler, compiling options and the concorde 
+directory (this is the directory with the concorde.a and the
+concorde.h file).
+
+After that just type 'make' or e.g. 'make blossom4', if you
+just want to get the blossom4 program. Other possibilities
+are 'make price4' or 'make tri_call'.
+
+------------------------------------------------------------
+
+Usage:
+
+After the programs are built, you can use them in the 
+following way:
+
+- blossom4
+    Type blossom4 to see different options.
+    Here some standard calls:
+
+    blossom4 -k 1000 
+        Calculate matching for 1000 random points.
+
+    blossom4 -k 1000 -s 1 
+        Calculate matching for 1000 random points
+        with random seed 1.
+
+    blossom4 -x 100.dat 
+        Calculate matching with the points from the file
+        100.dat.
+
+    blossom4 -b -x 12345.bin  -e 12345.del -5 
+        Calculate matching with the points from the binary
+        file 12345.bin, starting with the edge-set 12345.del 
+        and working with the ATT norm.
+
+    blossom4 -e 12345.del -B 12345.price
+        Calculate matching for the graph 12345.del and write 
+        the data necessary for the pricing program to the file
+        12345.price.
+
+- price4
+
+    Type price4 to see different options.
+    Here is a standard call:
+
+    price4 -b -n 12345.bin -d 12345.price -o 12345.bad.edges
+        Calculate the bad edges for the pricing file generated
+        with the blossom4 call above.
+
+- tri_call
+    All the necessary information about tri_call can be found
+    in the header of the tri_call.c file.
+ 
+For further information about options and file-formats
+see the concorde README file.
+
+------------------------------------------------------------
diff --git a/contrib/blossom/MATCH/100.dat b/contrib/blossom/MATCH/100.dat
new file mode 100644
index 0000000000000000000000000000000000000000..64196c13ecad33aa0eea4401848b65e11704ef03
--- /dev/null
+++ b/contrib/blossom/MATCH/100.dat
@@ -0,0 +1,101 @@
+100 
+620.000000 360.000000 
+810.000000 980.000000 
+850.000000 400.000000 
+300.000000 730.000000 
+410.000000 370.000000 
+560.000000 900.000000 
+250.000000 250.000000 
+800.000000 850.000000 
+250.000000 450.000000 
+900.000000 100.000000 
+550.000000 850.000000 
+800.000000 580.000000 
+90.000000 730.000000 
+900.000000 560.000000 
+480.000000 520.000000 
+180.000000 140.000000 
+420.000000 400.000000 
+420.000000 190.000000 
+230.000000 830.000000 
+980.000000 890.000000 
+530.000000 110.000000 
+930.000000 180.000000 
+130.000000 310.000000 
+850.000000 510.000000 
+160.000000 690.000000 
+490.000000 760.000000 
+340.000000 880.000000 
+240.000000 480.000000 
+940.000000 410.000000 
+560.000000 660.000000 
+170.000000 470.000000 
+750.000000 520.000000 
+840.000000 450.000000 
+970.000000 70.000000 
+120.000000 490.000000 
+0.000000 740.000000 
+290.000000 210.000000 
+610.000000 790.000000 
+510.000000 920.000000 
+340.000000 610.000000 
+790.000000 490.000000 
+0.000000 820.000000 
+350.000000 710.000000 
+390.000000 900.000000 
+560.000000 970.000000 
+220.000000 160.000000 
+710.000000 490.000000 
+890.000000 790.000000 
+820.000000 720.000000 
+570.000000 340.000000 
+800.000000 930.000000 
+170.000000 550.000000 
+900.000000 0.000000 
+760.000000 520.000000 
+530.000000 530.000000 
+90.000000 40.000000 
+850.000000 590.000000 
+440.000000 10.000000 
+760.000000 260.000000 
+630.000000 50.000000 
+630.000000 250.000000 
+500.000000 780.000000 
+690.000000 70.000000 
+570.000000 740.000000 
+310.000000 610.000000 
+30.000000 990.000000 
+390.000000 810.000000 
+520.000000 750.000000 
+640.000000 410.000000 
+380.000000 340.000000 
+950.000000 130.000000 
+270.000000 510.000000 
+340.000000 970.000000 
+660.000000 930.000000 
+800.000000 820.000000 
+220.000000 80.000000 
+410.000000 960.000000 
+310.000000 810.000000 
+540.000000 360.000000 
+30.000000 150.000000 
+360.000000 350.000000 
+140.000000 190.000000 
+580.000000 960.000000 
+770.000000 340.000000 
+250.000000 470.000000 
+350.000000 830.000000 
+460.000000 810.000000 
+830.000000 550.000000 
+840.000000 540.000000 
+470.000000 880.000000 
+530.000000 210.000000 
+710.000000 160.000000 
+250.000000 680.000000 
+850.000000 200.000000 
+230.000000 560.000000 
+980.000000 300.000000 
+160.000000 910.000000 
+990.000000 120.000000 
+670.000000 460.000000 
+680.000000 790.000000 
diff --git a/contrib/blossom/MATCH/100.edge b/contrib/blossom/MATCH/100.edge
new file mode 100644
index 0000000000000000000000000000000000000000..dbd3a0d0b63a57e2018625b19a765ac8c4490880
--- /dev/null
+++ b/contrib/blossom/MATCH/100.edge
@@ -0,0 +1,287 @@
+100 286
+81 79 117
+79 15 150
+15 81 64
+79 55 125
+55 15 135
+81 22 120
+22 79 189
+15 75 72
+75 45 80
+45 15 45
+55 75 136
+45 6 95
+6 81 125
+81 45 85
+55 57 351
+57 75 231
+6 22 134
+34 22 180
+22 30 165
+30 34 54
+34 79 352
+27 30 71
+30 8 82
+8 27 32
+30 51 80
+51 34 78
+51 27 99
+27 94 81
+94 51 61
+27 71 42
+71 94 64
+94 24 148
+24 51 140
+22 8 184
+51 12 197
+12 34 242
+75 36 148
+36 45 86
+34 35 277
+35 79 591
+80 6 149
+6 36 57
+36 80 157
+69 36 158
+36 17 132
+17 69 155
+69 80 22
+17 57 181
+57 20 135
+20 17 136
+75 17 228
+57 59 194
+59 20 117
+4 69 42
+69 90 198
+90 4 200
+17 90 112
+8 71 63
+71 84 45
+84 8 20
+8 16 177
+16 71 186
+27 84 14
+80 4 54
+4 16 32
+16 80 78
+14 71 210
+16 14 134
+78 16 126
+4 78 130
+78 14 171
+8 80 149
+8 6 200
+71 64 108
+64 94 94
+29 39 226
+39 14 166
+14 29 161
+39 71 122
+24 18 157
+18 12 172
+12 24 81
+12 35 91
+94 92 122
+92 24 91
+92 18 151
+64 42 108
+42 92 104
+92 64 92
+42 3 54
+3 92 71
+39 64 30
+77 3 81
+42 77 108
+3 18 122
+41 96 184
+96 65 153
+65 41 173
+41 35 80
+12 41 127
+26 96 182
+96 18 106
+18 26 121
+12 96 193
+18 77 82
+77 26 76
+96 72 190
+72 65 311
+39 42 100
+66 25 112
+25 86 58
+86 66 70
+66 42 108
+42 25 149
+86 89 71
+89 66 106
+66 85 45
+85 77 45
+77 66 80
+25 67 32
+67 61 36
+61 25 22
+29 25 122
+42 29 216
+61 10 86
+10 86 98
+86 61 50
+10 89 85
+72 26 90
+26 43 54
+43 72 86
+85 26 51
+85 43 81
+43 89 82
+89 76 100
+76 43 63
+66 43 90
+76 38 108
+38 44 71
+44 76 150
+89 38 57
+10 38 81
+76 72 71
+44 72 220
+67 10 104
+29 67 98
+44 65 530
+20 90 100
+20 60 172
+60 90 108
+91 20 187
+59 91 136
+91 60 120
+60 49 108
+49 90 136
+91 93 146
+93 58 108
+58 91 112
+9 91 199
+91 62 92
+62 9 212
+58 60 130
+59 62 63
+59 52 275
+52 62 221
+0 60 110
+60 83 166
+83 0 151
+78 49 36
+49 0 54
+0 78 80
+78 90 150
+0 68 54
+68 78 112
+68 83 148
+83 98 156
+98 68 58
+98 46 50
+46 54 184
+54 98 157
+68 54 163
+54 78 170
+83 46 162
+58 83 81
+54 14 51
+9 70 58
+70 21 54
+21 9 85
+33 9 76
+9 52 100
+52 33 99
+21 93 82
+93 9 112
+70 33 63
+33 97 54
+97 70 41
+97 21 85
+97 95 180
+95 21 130
+83 32 130
+32 40 64
+40 83 151
+83 2 100
+2 32 51
+23 40 63
+32 23 61
+40 46 80
+93 95 164
+95 2 164
+2 93 200
+2 28 91
+28 32 108
+95 28 117
+95 19 590
+19 28 482
+83 93 161
+28 23 135
+97 19 770
+57 52 460
+40 31 50
+31 46 50
+29 63 81
+63 67 51
+46 29 227
+29 54 133
+37 63 64
+63 99 121
+99 37 70
+37 67 98
+29 11 253
+11 99 242
+99 29 177
+40 53 42
+53 31 10
+31 11 78
+29 31 236
+37 10 85
+5 44 70
+38 5 54
+37 5 121
+5 10 51
+5 82 63
+82 44 22
+5 73 104
+73 82 85
+37 73 149
+7 73 161
+73 99 141
+99 7 134
+82 1 231
+1 44 250
+73 1 158
+53 11 72
+11 87 42
+87 56 45
+56 11 51
+53 87 76
+40 87 72
+87 88 14
+88 56 51
+13 56 58
+88 13 63
+13 23 71
+28 13 155
+13 47 230
+47 56 204
+88 23 32
+40 88 71
+56 48 133
+48 11 141
+74 7 30
+99 74 124
+74 47 95
+47 7 108
+50 7 80
+7 19 184
+19 50 184
+50 73 140
+47 19 135
+47 48 99
+1 50 51
+19 1 192
+13 19 340
+74 48 102
+99 48 157
+1 65 780
diff --git a/contrib/blossom/MATCH/Makefile b/contrib/blossom/MATCH/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..47877f57efe64243996d9087bc5dea5c18b4f85d
--- /dev/null
+++ b/contrib/blossom/MATCH/Makefile
@@ -0,0 +1,41 @@
+# Change these parameters how you want them to be
+     CON_PATH = ${HOME}/src/concorde97
+           CC = gcc -m32
+       CFLAGS =  -g 
+
+# From here nothing needs to be changed
+      INCDIRS =  -I$(CON_PATH)
+
+           LD = $(CC)
+
+         LIBS = -lm 
+
+      BLOSSOM = mat_main.c match.c matprice.c 
+        PRICE = mp_main.c matprice.c 
+     TRI_CALL = tri_call.c           
+
+  BLOSSOMOBJS = $(BLOSSOM:.c=.o)
+    PRICEOBJS = $(PRICE:.c=.o)
+ TRI_CALLOBJS = $(TRI_CALL:.c=.o)
+
+all    : blossom4 price4 tri_call
+
+blossom4 : $(BLOSSOMOBJS)
+	$(LD) -o $@  $(BLOSSOMOBJS) $(CON_PATH)/libconcorde.a -lm 
+price4 : $(PRICEOBJS)
+	$(LD) -o $@  $(PRICEOBJS) $(CON_PATH)/libconcorde.a -lm
+tri_call : $(TRI_CALLOBJS)
+	$(LD) -o $@  $(TRI_CALLOBJS) -lm
+
+install : all
+
+clean  :
+	rm -f *.o blossom4 price4 tri_call
+
+depend :
+	makedepend $(INCDIRS) $(SEQU)
+
+.c.o :
+	$(CC) $(CFLAGS) $(INCDIRS) -c $*.c
+
+
diff --git a/contrib/blossom/MATCH/mat_main.c b/contrib/blossom/MATCH/mat_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..30eb3870629003e45070f113fd8fef12f600205f
--- /dev/null
+++ b/contrib/blossom/MATCH/mat_main.c
@@ -0,0 +1,301 @@
+/************************************************************************/
+/*                                                                      */
+/*             ROUTINE FOR WEIGHTED PERFECT MATCHING PROBLEMS           */
+/*                                                                      */
+/*  Written by:  A. Rohe                                                */
+/*  Date:  November 7, 1995  (rohe)                                     */
+/*         November 12, 1995 (rohe)                                     */
+/*         February 7, 1996  (rohe - short look at program)             */
+/*         July, 1996        (rohe - change from tree to forest)        */
+/*         October, 1996     (bico - change to concorde format)         */
+/*                                                                      */
+/************************************************************************/
+
+#include "concorde.h"
+#include "match.h" 
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    usage (char *name);
+static int
+    parseargs (int ac, char **av);
+
+#else
+
+static void
+    usage ();
+static int
+    parseargs ();
+
+#endif
+
+static int seed = 0;
+static char *blossom_file = (char *) NULL;
+static char *match_file = (char *) NULL;
+static char *datfilename = (char *) NULL;
+static char *edgefilename = (char *) NULL;
+static char *edgegenfname = (char *) NULL;
+static int no_frac = 0;
+static int just_frac = 0;
+static int use_all_trees = 0;
+static int binary_in = 0;
+static int tsplib_in = 0;
+static int nnodes_want = 0;
+static int partialprice = 0;
+static int norm = CC_EUCLIDEAN;
+static int no_price = 0;
+
+#ifdef CC_PROTOTYPE_ANSI
+int  main (int ac, char **av)
+#else
+int  main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    double zero_zeit = CCutil_zeit ();
+    double matzeit = 0.0;
+    double genzeit = 0.0;
+    int ncount, ecount;
+    int *elist = (int *) NULL;
+    int *elen = (int *) NULL;
+    long l;
+    CCdatagroup dat, *mydat = (CCdatagroup *) NULL;
+
+    seed = time (&l);
+    if (parseargs (ac, av))
+        return 0;
+    CCutil_sprand (seed);
+
+    if (edgefilename == (char *) NULL && datfilename == (char *) NULL &&
+                                         nnodes_want == 0) {
+        usage (av[0]);
+        return 0;
+    }
+    ncount = nnodes_want;
+
+    if (tsplib_in && datfilename != (char *) NULL) {
+        if (CCutil_gettsplib (datfilename, &ncount, &dat)) {
+            fprintf (stderr, "could not read the TSPLIB file\n");
+            goto CLEANUP;
+        }
+        mydat = &dat;
+        norm = dat.norm;
+    } else if (datfilename != (char *) NULL || nnodes_want != 0) {
+        if (CCutil_getdata (datfilename, binary_in, norm, &ncount, &dat)) {
+            fprintf (stderr, "Could not create data set\n");
+            goto CLEANUP;
+        }
+        mydat = &dat;
+    } else {
+        mydat = (CCdatagroup *) NULL;
+    }
+
+    if (mydat) {
+        if (CCutil_init_dat_edgelen (mydat)) {
+            fprintf (stderr, "init_dat_edgelen failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (edgefilename) {
+        if (CCutil_getedgelist_n (&ncount, edgefilename, &ecount, &elist, &elen)) {
+            fprintf (stderr, "getedgelist_n failed\n");
+            goto CLEANUP;
+         }
+    } else {
+        CCedgegengroup plan;
+        int i;
+
+        if (edgegenfname) {
+            if (CCedgegen_read (edgegenfname, &plan)) {
+                fprintf (stderr, "CCedgegen_read failed\n");
+                goto CLEANUP;
+            }
+        } else {
+            CCedgegen_init_edgegengroup (&plan);
+            if ((norm & CC_NORM_BITS) != CC_KD_NORM_TYPE) {
+                plan.nearest = 5;
+            } else {
+                plan.quadnearest = 2;  
+                plan.tour.nearest_count = 1; 
+            }
+        }
+        genzeit = CCutil_zeit ();
+        if (CCedgegen_edges (&plan, ncount, mydat, (double *) NULL, &ecount,
+                     &elist)) {
+            fprintf (stderr, "CCedgegen_edges failed\n");
+            goto CLEANUP;
+        }
+        elen = CC_SAFE_MALLOC (ecount, int);
+        if (!elen) {
+            fprintf (stderr, "out of memory in main\n");
+            CC_FREE (elist, int);
+            goto CLEANUP;
+        }
+        for (i = 0; i < ecount; i++) {
+            elen[i] = CCutil_dat_edgelen (elist[2*i], elist[2*i+1], mydat);
+        }
+        genzeit = CCutil_zeit () - genzeit;
+    }
+
+    if (mydat != (CCdatagroup *) NULL && no_price) {
+        CCutil_freedatagroup (ncount, mydat);
+        mydat = (CCdatagroup *) NULL;
+    }
+
+    printf ("ZZ nnodes: %d  seed: %d\n", ncount, seed); fflush (stdout);
+
+    if (perfect_match (ncount, mydat, ecount, &elist, &elen,
+                       blossom_file, match_file, just_frac, no_frac, 
+                       use_all_trees, partialprice, &matzeit)) {
+        fprintf (stderr, "perfect_match failed\n");
+        goto CLEANUP;
+    }
+
+CLEANUP:
+
+    if (mydat != (CCdatagroup *) NULL) {
+        CCutil_freedatagroup (ncount, mydat);
+    }
+
+    printf ("\nZZ Running Time: %.2f seconds (Edgegen %.2f, Matching %.2f)\n",
+                    genzeit + matzeit, genzeit, matzeit);
+    printf ("ZZ Total Time: %.2f Seconds (includes IO and checking)\n",
+                    CCutil_zeit () - zero_zeit);
+    fflush (stdout);
+
+   return 0;
+}
+
+#ifdef  CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "bB:dD:e:fjk:lp:Ps:tTx:w:0123456789")) != EOF)
+        switch (c) {
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'B':
+            blossom_file = CCutil_bix_optarg;
+            break;
+        case 'd':
+            use_all_trees = 2;
+            break;
+        case 'D':
+            edgegenfname = CCutil_bix_optarg;
+            break;
+        case 'e':
+            edgefilename = CCutil_bix_optarg;
+            break;
+        case 'f':
+            just_frac = 1;
+            break;
+        case 'j':
+            no_frac = 1;
+            break;
+        case 'k':
+            nnodes_want = atoi (CCutil_bix_optarg);
+            break;
+        case 'p':
+            partialprice = atoi (CCutil_bix_optarg);
+            break;
+        case 'P':
+            no_price = 1;
+            break;
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 't':
+            use_all_trees = 1;
+            break;
+        case 'T':
+            tsplib_in = 1;
+            break;
+        case 'w':
+            match_file = CCutil_bix_optarg;
+            break;
+        case 'x':
+            datfilename = CCutil_bix_optarg;
+            break;
+        case '0':
+            norm = CC_MAXNORM;
+            break;
+        case '1':
+            norm = CC_EUCLIDEAN_CEIL;
+            break;
+        case '2':
+            norm = CC_EUCLIDEAN;
+            break;
+        case '3':
+            norm = CC_EUCLIDEAN_3D;
+            break;
+        case '4':
+            norm = CC_IBM;
+            break;
+        case '5':
+            norm = CC_ATT;
+            break;
+        case '6':
+            norm = CC_GEOGRAPHIC;
+            break;
+        case '7':
+            norm = CC_MATRIXNORM;
+            break;
+        case '8':
+            norm = CC_DSJRANDNORM;
+            break;
+        case '9':
+            norm = CC_CRYSTAL;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+        default:
+            usage (av[0]);
+            return 1;
+        }
+
+    if (CCutil_bix_optind != ac) {
+        usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *name)
+#else
+static void usage (name)
+char *name;
+#endif
+{
+    fprintf (stderr, "Usage: %s [-see below-]\n", name);
+    fprintf (stderr, "   -b    datfile in integer binary format\n");
+    fprintf (stderr, "   -B f  blossom-tree-file (for writing)\n");
+    fprintf (stderr, "   -d    grow a single tree\n");
+    fprintf (stderr, "   -D f  edgegen description file (initial edges)\n");
+    fprintf (stderr, "   -e f  edge_file\n");
+    fprintf (stderr, "   -f    just fractional\n");
+    fprintf (stderr, "   -j    no fractional jumpstart\n");
+    fprintf (stderr, "   -k #  number of nodes for random problem\n");
+    fprintf (stderr, "   -p #  number of neighbors in partial pricing\n");
+    fprintf (stderr, "   -P    do not do pricing (just solve initial set)\n");
+    fprintf (stderr, "   -s #  random seed\n");
+    fprintf (stderr, "   -t    make same dual change to all trees\n");
+    fprintf (stderr, "   -T    the dat file is a TSPLIB file\n");
+    fprintf (stderr, "   -w f  match_file (for writing)\n");
+    fprintf (stderr, "   -x f  datfile for pricing\n");
+    fprintf (stderr, "   -0    Max norm for edge lengths\n");
+    fprintf (stderr, "   -1    Ceiling Euclidean norm - from DSJ\n");
+    fprintf (stderr, "   -2    Rounded Euclidean norm (default)\n");
+    fprintf (stderr, "   -3    Rounded Euclidean 3D norm\n");
+    fprintf (stderr, "   -(4 5 6 7 8 9) IBM ATT GEO MATRIX DSJRAND CRYSTAL norm\n");
+}
diff --git a/contrib/blossom/MATCH/match.c b/contrib/blossom/MATCH/match.c
new file mode 100644
index 0000000000000000000000000000000000000000..4ff66a2f2d0df47fdb7c16cfea3e56c2c814b658
--- /dev/null
+++ b/contrib/blossom/MATCH/match.c
@@ -0,0 +1,3885 @@
+/************************************************************************/
+/*                                                                      */
+/*             ROUTINE FOR WEIGHTED PERFECT MATCHING PROBLEMS           */
+/*                                                                      */
+/*  Written by:  A. Rohe                                                */
+/*  Date:  November 7, 1995  (rohe)                                     */
+/*         November 12, 1995 (rohe)                                     */
+/*         February 7, 1996  (rohe - short look at program)             */
+/*         July, 1996        (rohe - change from tree to forest)        */
+/*         October, 1996     (bico - change to concorde format)         */
+/*                                                                      */
+/*                                                                      */
+/* EXPORTED FUNCTION:                                                   */
+/*   int perfect_match (int ncount, CCdatagroup *dat, int ecount,       */
+/*          int **elist, int **elen, char *blo_filename,                */
+/*          char *mat_filename, int just_fractional, int no_fractional, */
+/*          int use_all_trees, int use_tree, int partialprice,          */
+/*          double *totalzeit)                                          */
+/*     COMPUTES a minumum weight perfect matching.                      */
+/*         -ncount is the number of nodes in the graph                  */
+/*         -dat gives the data to generate edge lengths (if the         */
+/*            matching is over the complete graph), it can be NULL      */
+/*         -ecount is the number of edges in the initial edge set       */
+/*         -elist is a pointer to an array of edges in end end format,  */
+/*            this array will be freed by perfect_match to save on      */
+/*            memory                                                    */
+/*         -elen is a pointer to an array of edge lengths for the edges */
+/*            in elist, it will be freed by the perfect_match           */
+/*         -blo_filename is the name of a file (it can be NULL), if it  */
+/*            is not NULL then the blossoms and weights will be written */
+/*            to it                                                     */
+/*         -mat_filename is the name of a file (it can be NULL), if it  */
+/*            is not null, then the matching will be writtien to it     */
+/*         -just_fractional should be 0 to compute a matching, and 1    */
+/*            to only compute a fractional matching                     */
+/*         -if no_fractional is nonzero, then a fractional jumpstart    */
+/*            will not be used                                          */
+/*         -if use_all_trees is 1, then a common delta is               */
+/*            computed for all trees in the forest; if it is 2, then    */
+/*            a single tree is grown                                    */
+/*         -if partialprice is > 0, then the pricing routine will first */
+/*            price the partialprice nearest neighbors before moving to */
+/*            the complete edge set                                     */
+/*         -totalzeit will return the time used by the matching routine */
+/*            (excluding the time needed for a final check that the     */
+/*            matching is indeed optimal, if this checking is turned    */
+/*            on)                                                       */
+/*                                                                      */
+/*  NOTES:                                                              */
+/*                                                                      */
+/*    Returns 0 if it worked and 1 otherwise (for example, when one     */
+/*    of the mallocs failed). The nodes in the graph should be named    */
+/*    0 through #nodes - 1.                                             */
+/*                                                                      */
+/************************************************************************/
+#include "concorde.h"
+#include "match.h"
+#define NDEBUG   /* remove this to turn assertions on */
+#include <assert.h>
+
+#define CARELESS_REPAIRS 
+/* #define BALL_DERIGS_REPAIRS */
+#define GREEDY_DUAL_CHANGE 
+#define SWITCH_LEVEL 32
+#define MAX_BAD_PORTION 0.25
+
+#define PRINT_LEVEL 0
+#define SHRINKS_SIZE 1000
+/* infinity */
+#define INTEGER_MIN -999999999
+#define INTEGER_MAX  999999999
+/* for labels */
+#define NIX 0
+#define PLUS 1
+#define MINUS 2
+/* for status */
+#define UNMATCHED 0
+#define HALVES 1
+#define MATCHED 2
+/* for x */
+#define HALF 2
+
+int FAILED_NODE;
+
+/*
+#define OTHEREND(e,n,list)  ((list) + (e)->nod1 + (e)->nod2 - ((n) - (list)))
+*/
+#define OTHEREND(e,n,list) (((e)->nod1 + (list)) == (n) ?                \
+                             (e)->nod2 + (list) : (e)->nod1 + (list))
+#define OTHEREND_INT(e,n) ((e)->nod1 + (e)->nod2 - (n))
+
+#define FIND_SURFACE(n) {                                                \
+            while((n)->blossom_parent != -1) {                           \
+                (n)=G->nodelist+(n)->blossom_parent;                     \
+            }                                                            \
+        }
+
+#define SHRINK_SORT_CONST 3
+#define BADCOUNT_CONST 10000
+#define PNODE(n) (G->nodelist + (n))
+#define PEDGE(e) (G->edgelist + (e))
+
+#define INODE(n) ((n) - G->nodelist)
+#define IEDGE(e) ((e) - G->edgelist)
+
+typedef struct edge {
+    int   slack;
+    char  mark;  
+    char  x; 
+    int   ptrs[2];
+    int   nod1;
+    int   nod2;
+    int   orig_nod1;
+    int   orig_nod2;
+} edge;
+
+typedef struct node {
+    int   edg_list;
+    int   matched_edge;
+
+    /* These are for the augmenting path tree */
+    int   child;
+    int   sibling;
+    int   parent;
+    int   parent_edge;
+
+    /* These are for the blossom_tree */
+    int   blossom_next;
+    int   blossom_parent;
+    int   blossom_root;
+    int   blossom_next_edge;
+    int   penultimate;
+
+    int   pi;
+    int   mark;      /* unused pseudo nodes are linked by mark */
+    int   tree_root;
+
+    char  status;
+    char  label;
+    char  hit;
+
+    int   dummy;    /* just to pad to multiple of 8 bytes */
+} node;
+
+typedef struct nodeptr {
+    int next;
+    int surf;
+    int delta;
+    int dad;
+    int sum;
+    int status;
+#ifdef GREEDY_DUAL_CHANGE
+    char tree_processed;
+    int gnext;      /* used to pad to multiple of 8 bytes and in reordering */
+#endif
+} nodeptr;
+
+typedef struct shrink_ary_T {
+    int node_i;
+    int node_j;
+    int node_k;
+    int edge;
+    int size;
+    int next;
+} shrink_ary_T;
+
+typedef struct shrink_T {
+    shrink_ary_T *ary;
+    int length;
+} shrink_T;
+
+typedef struct expand_T {
+    int *node;
+    int length;
+} expand_T;
+
+typedef struct stats {
+    int expand_count;
+    int shrink_count;
+    int dualchange_count;
+    int dualzero_count;
+} stats;
+
+typedef struct graph {
+    edge *edgelist;
+    node *nodelist;
+    int nnodes;
+    int nedges;
+    int max_nedges;
+    int unused;
+    int unmatched;
+    nodeptr *roots;
+    int unmatched_count;
+}graph;
+
+typedef struct srkstuff {
+    expand_T expands;
+    shrink_T shrinks;
+    int shrinks_max;
+    int expands_max;
+    int shrinks_[SHRINKS_SIZE];
+} srkstuff;
+
+typedef struct stack {
+    int*             ary;
+    int              count;
+} stack;
+
+#ifdef  CC_PROTOTYPE_ANSI
+
+static void
+    adjust_match (graph *G),
+    print_node (graph *G, node *n),
+    print_edges (graph *G),
+    init_tree (graph *G, node *n),
+    clear_tree (graph *G, node *n),
+    make_cycle_halves (graph *G, node *node_i, node *node_j, node *node_k,
+        edge *e),
+    shrink_tree (graph *G, node *newnode),
+    label_penultimate (graph *G, node *n, int label),
+    fix_matching (graph *G, node *oldnode, node *x),
+    fix_tree (graph *G, node *oldnode, node *x, node *y),
+    flip_cycle (graph *G, node *node_i),
+    augment_path (graph *G, node *node_i, int fractional),
+    vereinigung (graph *G, int x, int y),
+    set_vereinigung (graph *G, node *n),
+    unmatch_edge (graph *G, edge *e),
+    dual_match_len (graph *G, int fractional, double *val),
+    fix_match (graph *G, int blossom);
+
+static int 
+    build_graph (graph *G, int ncount, int ecount, int *elist, int *elen),
+    init (graph *G, srkstuff *srk),
+    match_main_frac (graph *G, stats *scount, srkstuff *srk),
+    match_main (graph *G, stats *scount, srkstuff *srk, int use_all),
+    augment_blossom (graph *G, edge *, int fractional, srkstuff *srk),
+    lower_edges (graph *G, node *old),
+    expand_blossom (graph *G, node *oldnode, stats *scount),
+    lift_edges (graph *G, node *newnode),
+    add_to_tree (graph *G, edge *e, node *node_i, node *node_j, int fractional),
+    checkout_node (graph *G, node *n, int fractional, srkstuff *srk),
+    grow_tree_no_shrink (graph *G, node *n, int fractional, srkstuff *srk),
+    grow_tree (graph *G, node *n, int fractional, stats *scount, srkstuff *srk,
+               int *found_aug),
+    apply_dual_change (graph *G, node *n, int delta),
+    find_parity_sum (graph *G, int n),
+    parity_correction (graph *G, stats *scount),
+    find_single_dual_change (graph *G, node *n),
+    find_dual_change_forest (graph *G, node *n),
+    make_dual_change_forest (graph *G, stats *scount),
+    match_main_more_in_forest (graph *G, stats *scount, srkstuff *srk),
+    match_main_forest (graph *G, stats *scount, srkstuff *srk),
+    match_main_tree (graph *G, stats *scount, srkstuff *srk),
+    make_match (graph *G),
+    test_matching (graph *G, CCdatagroup *dat, int *elen, int fractional,
+                   int *bad),
+    price_repair (graph *G, int *finished, CCdatagroup *dat, stats *scount,
+       srkstuff *srk, int partialprice),
+    pricing (graph *G, CCdatagroup *dat, stats *scount, srkstuff *srk, 
+       int *badcount, int **badlist, int **badlen, CCtsp_edgegenerator *eg,
+       int usehit),
+    bring_to_surface (graph *G, node *p, stats *scount, srkstuff *srk),
+    add_repair_edge (graph *G, int n1, int n2, int len, stats *scount,
+       srkstuff *srk),
+    run_repair (graph *G, int badcount,int* badlist,int* badlen, stats *scount,
+       srkstuff *srk),
+    add_edges (graph *G, CCdatagroup *dat, int badcount,int* badlist,int* badlen),
+  write_match (graph *G, CCdatagroup *dat, int *elen, char* match_file, int *outp),
+    write_blossom_tree (graph *G, char* blossom_tree_file);
+
+static node
+    *shrink_blossom (graph *G, node *node_i, node *node_j, node *node_k,
+        edge *e, stats *scount),
+    *common_parent (graph *G, node *node_i, node *node_j, int *size),
+    *find_below (graph *G, node *n, int blossom);
+
+#else
+
+static void
+    adjust_match (),
+    print_node (),
+    print_edges (),
+    init_tree (),
+    clear_tree (),
+    make_cycle_halves (),
+    shrink_tree (),
+    label_penultimate (),
+    fix_matching (),
+    fix_tree (),
+    flip_cycle (),
+    augment_path (),
+    vereinigung (),
+    set_vereinigung (),
+    unmatch_edge (),
+    dual_match_len (),
+    fix_match ();
+
+static int
+    build_graph (),
+    init (),
+    match_main_frac (),
+    match_main (),
+    augment_blossom (),
+    lower_edges (),
+    expand_blossom (),
+    lift_edges (),
+    add_to_tree (),
+    checkout_node (),
+    grow_tree_no_shrink (),
+    grow_tree (),
+    apply_dual_change (),
+    find_parity_sum (),
+    parity_correction (),
+    find_single_dual_change (),
+    find_dual_change_forest (),
+    make_dual_change_forest (),
+    make_match (),
+    match_main_more_in_forest (),
+    match_main_forest (),
+    match_main_tree (),
+    test_matching (),
+    price_repair (),
+    pricing (),
+    add_repair_edge (),
+    bring_to_surface (),
+    run_repair (),
+    add_edges (),
+    write_match (),
+    write_blossom_tree ();
+
+static node
+    *shrink_blossom (),
+    *common_parent (),
+    *find_below ();
+
+#endif
+
+#if PRINT_LEVEL
+static graph *PG = (graph *) NULL;
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int perfect_match (int ncount, CCdatagroup *dat, int ecount, int **elist,
+                   int **elen, char *blo_filename, char *mat_filename,
+                   int just_fractional, int no_fractional,
+                   int use_all_trees, int partialprice, double *totalzeit)
+#else
+int perfect_match (ncount, dat, ecount, elist, elen, blo_filename,
+                   mat_filename, just_fractional, no_fractional,
+                   use_all_trees, partialprice, totalzeit)
+int ncount;
+CCdatagroup *dat;
+int ecount;
+int **elist, **elen;
+char *blo_filename, *mat_filename;
+int use_all_trees;
+int partialprice;
+double *totalzeit;
+#endif
+{
+    graph G;
+    srkstuff srk;
+    stats scount;
+    double val, startzeit;
+    int finished = 1;
+    int bad;
+    int sedges = 0;
+    double zero_zeit = CCutil_zeit ();
+
+#if PRINT_LEVEL
+    PG = &G;
+#endif
+
+    int status = 0;
+
+    *totalzeit = 0.0;
+
+    G.edgelist = (edge *) NULL;
+    G.nodelist = (node *) NULL;
+    G.unused = -1;
+    G.unmatched = -1;
+    G.roots = (nodeptr *) NULL;
+
+    srk.expands.node = (int *) NULL;
+    srk.shrinks.ary = (shrink_ary_T *) NULL;
+
+    if (build_graph (&G, ncount, ecount, *elist, *elen)) {
+      //        fprintf (stderr, "build_graph failed\n");
+        CC_FREE (*elist, int);
+        CC_FREE (*elen, int);
+	status = 1;
+        goto CLEANUP;
+    }
+    CC_FREE (*elist, int);
+    if (dat) {
+        CC_FREE (*elen, int);
+    }
+    sedges = G.nedges;
+  
+    do {
+      //	printf (" Starting Init...");
+	fflush (stdout);
+	startzeit = CCutil_zeit ();
+	if (init (&G, &srk)) {
+	  //            fprintf (stderr, "init failed\n");
+	    status = 1;
+            goto CLEANUP;
+        }
+	//	printf (" ... ready in %.2f sec !! \n", CCutil_zeit () - startzeit);
+        fflush (stdout);
+
+	if (no_fractional == 0) {
+	  //	    printf (" Matching with %i nodes and %i edges ...\n",
+	  //                    G.nnodes, G.nedges);
+	  //	    fflush (stdout);
+	    //	    printf (" Make a fractional Matching...\n");
+	    fflush (stdout);
+	    startzeit = CCutil_zeit ();
+            scount.expand_count = 0;
+            scount.shrink_count = 0;
+            scount.dualchange_count = 0;
+            scount.dualzero_count = 0;
+	    if (match_main_frac (&G, &scount, &srk)) {
+	      //                fprintf (stderr, "match_main_frac failed\n");
+		status = 1;
+                goto CLEANUP;
+            }
+	    //	    printf (" ... ready in %.2f sec !! \n", CCutil_zeit () - startzeit);
+	    //            fflush (stdout);
+	}
+
+	if (just_fractional == 0) {
+	  //	    printf (" Make an integral Matching ...\n");
+	  //	    fflush (stdout);
+	    startzeit = CCutil_zeit ();
+	    if (make_match (&G)) {
+	      //                fprintf (stderr, "make_match failed\n");
+	      //                fflush (stdout);
+            }
+	    //	    printf (" ... ready in %.2f sec !! \n", CCutil_zeit () - startzeit);
+	    //            fflush (stdout);
+
+	    //	    printf (" Starting Integral Matching-Code...\n");
+	    //	    fflush (stdout);
+	    startzeit = CCutil_zeit ();
+            scount.expand_count = 0;
+            scount.shrink_count = 0;
+            scount.dualchange_count = 0;
+            scount.dualzero_count = 0;
+	    if (match_main (&G, &scount, &srk, use_all_trees)) {
+	      //                fprintf (stderr, "match_main failed\n");
+	      status = 1;
+	      goto CLEANUP;
+            }
+	    //	    printf (" ... ready in %.2f sec !! \n", CCutil_zeit () - startzeit);
+	    //            fflush (stdout);
+            dual_match_len (&G, 0, &val);
+	    //            printf ("     Dual Matching Length: %.1f\n", val);
+	    //            fflush (stdout);
+	    if (dat) {
+	      //		printf ("Start Price-Repair Phase ...\n");
+	      //		fflush (stdout);
+		startzeit = CCutil_zeit ();
+                if (price_repair (&G, &finished, dat, &scount, &srk,
+                                  partialprice)) {
+		  //                    fprintf (stderr, "pricing failed\n");
+                    return 1;
+                }
+                if (finished && partialprice > 0) {
+		  //                    printf ("Nearest %d are correct, now try complete graph\n",
+		  //                             partialprice);
+		  //                    fflush (stdout);
+                    if (price_repair (&G, &finished, dat, &scount, &srk, 0)) {
+		      //                        fprintf (stderr, "pricing failed\n");
+                        return 1;
+                    }
+                }
+		//		printf (" ... ready in %.2f sec !! \n", CCutil_zeit () - startzeit);
+		//                fflush (stdout);
+	    }
+            CC_IFFREE (G.roots, nodeptr);
+	}
+	if (blo_filename != (char *) NULL) {
+	    if (write_blossom_tree (&G, blo_filename)) {
+	      //                fprintf (stderr, "write_blossom_tree failed\n");
+		status = 1;
+                goto CLEANUP;
+            }
+	}
+        CC_IFFREE (srk.expands.node, int);
+        CC_IFFREE (srk.shrinks.ary, shrink_ary_T); 
+    } while (!finished);
+
+    //    printf (" Adjust found Matching...\n");
+    //    fflush (stdout);
+    startzeit = CCutil_zeit ();
+    adjust_match (&G);
+    //    printf (" ... ready in %.2f sec !! \n", CCutil_zeit () - startzeit);
+    //    fflush (stdout);
+
+    *totalzeit = CCutil_zeit () - zero_zeit;
+    //    printf ("Matching Time: %.2f Seconds\n", *totalzeit);
+    //    fflush (stdout);
+
+    if (dat) {
+      //        printf ("Testing the solution...\n");
+      //        fflush (stdout);
+        startzeit = CCutil_zeit ();
+        if (test_matching (&G, dat, *elen, just_fractional, &bad)) {
+	  //            fprintf (stderr, "test matching failed\n");
+	  status = 1;
+	  goto CLEANUP;
+        }
+        if (bad) {
+	  //            printf ("ERROR: A problem was detected in the matching\n");
+	  status = 1;
+	  goto CLEANUP;
+        }
+	//        printf ("Testing Time: %.2f sec\n", CCutil_zeit () - startzeit);
+	//        fflush (stdout);
+    }
+
+    //    printf ("ZZ Edges:  %d (starting)   %d (total)\n", sedges, G.nedges);
+
+    if (mat_filename !=  (char *) NULL) {
+      *elist = (int*)malloc((3*ncount+1)*sizeof(int));// over allocated
+      if (write_match (&G, dat, *elen, mat_filename,*elist)) {
+	status = 1;
+	//            fprintf (stderr, "write_match failed\n");
+	goto CLEANUP;
+      }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (G.nodelist, node);
+    CC_IFFREE (G.edgelist, edge);
+    CC_IFFREE (G.roots, nodeptr);
+    CC_IFFREE (srk.expands.node, int);
+    CC_IFFREE (srk.shrinks.ary, shrink_ary_T); 
+    if (!dat) {
+       CC_FREE (*elen, int);
+    }
+
+    return status;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void print_node (graph *G, node *n)
+#else
+static void print_node (G, n)
+graph *G;
+node *n;
+#endif
+{
+    edge *e;
+    int ei;
+    int c;
+    node *nodelist = G->nodelist;
+    edge *edgelist = G->edgelist;
+
+    printf ("Node %d, Pi %d", (int) INODE(n), n->pi);
+    if (n->label == PLUS) printf (" label +");
+    if (n->label == MINUS) printf (" label -");
+    if (n->label == NIX) printf (" label 0");
+    if (n->status == MATCHED)
+	printf (" MATCHED (%d,%d)\n",
+            edgelist[n->matched_edge].nod1,
+            edgelist[n->matched_edge].nod2);
+    if (n->status == UNMATCHED) printf (" UNMATCHED\n");
+    if (n->status == HALVES)
+	printf (" HALVES (%i,%i)\n",
+            edgelist[n->matched_edge].nod1, edgelist[n->matched_edge].nod2);
+    fflush (stdout);
+    if (n->label != NIX) {
+	printf ("TreeRoot %d ", n->tree_root);
+	if (n->parent)
+	    printf ("TreeParent = %d ", n->parent);
+	printf ("Children: ");
+	for (c = n->child; c != -1; c = nodelist[c].sibling)
+	    printf ("%d ", c);
+	printf ("\n");
+    }
+    if (n->blossom_parent != -1) {
+	printf ("BlossomNode %i, Parent %i, Next %i\n", (int) INODE(n),
+            n->blossom_parent, n->blossom_next);
+    }
+    if (n->blossom_root != -1) {
+	printf ("BlossomParent %i, Root %i\n", (int) INODE(n), n->blossom_root);
+    }
+    for (ei = n->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+        e = PEDGE(ei/2);
+	printf ("| Edge (%i,%i)", e->nod1, e->nod2);
+	printf ("| %4i is ", e->nod1);
+	if (nodelist[e->nod1].label == PLUS) printf ("+");
+	if (nodelist[e->nod1].label == MINUS) printf ("-");
+	if (nodelist[e->nod1].label == NIX) printf ("0");
+	printf ("| %4i is ", e->nod2);
+	if (nodelist[e->nod2].label == PLUS) printf ("+");
+	if (nodelist[e->nod2].label == MINUS) printf ("-");
+	if (nodelist[e->nod2].label == NIX) printf ("0");
+	printf ("| edg Slack %d, x=%d\n", e->slack, (int) e->x);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void print_edges (graph *G)
+#else
+static void print_edges (G)
+graph *G;
+#endif
+{
+    int i;
+
+    printf (" %i nodes, %i edges\n", G->nnodes, G->nedges);
+    for (i = 0; i <= 3 * G->nnodes / 2 && i >= 0; i++) {
+	if (G->nodelist[i].edg_list != -1)
+	    print_node (G, PNODE(i));
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int init (graph *G, srkstuff *srk)
+#else
+static int init (G, srk)
+graph *G;
+srkstuff *srk;
+#endif
+{
+    int i, count;
+    node *n;
+    edge *e;
+    int ei;
+    int delta;
+    node *nodelist = G->nodelist;
+    int   ncount = G->nnodes;
+    int   ecount = G->nedges;
+
+    /* set all the pi s */
+    for (i = 0; i < ncount; i++)
+	nodelist[i].pi = INTEGER_MAX;
+    for (i = ncount; i <= 3 * ncount / 2; i++)
+	nodelist[i].pi = 0;
+
+    for (i = 0, e = G->edgelist; i < ecount; i++, e++) {
+	if (nodelist[e->nod1].pi > e->slack) {
+	    nodelist[e->nod1].pi = e->slack;
+	}
+	if (nodelist[e->nod2].pi > e->slack) {
+	    nodelist[e->nod2].pi = e->slack;
+	}
+    }
+
+    for (i = 0; i < ncount; i++)
+	nodelist[i].pi /= 2;
+
+    /* calculate the slacks with the pi's and set rest to zero/nothing */
+
+    for (i = 0, e = G->edgelist; i < ecount; i++, e++) {
+	e->slack = e->slack - nodelist[e->nod1].pi - nodelist[e->nod2].pi;
+	e->x = 0;
+    }
+
+    for (i = 0, n = nodelist; i <= 3 * ncount / 2; i++, n++) {
+	n->child = -1;
+	n->sibling = -1;
+	n->parent = -1;
+	n->label = NIX;
+	n->parent_edge = -1;
+	n->matched_edge = -1;
+	n->status = UNMATCHED;
+	n->blossom_root = -1;
+	n->blossom_next = -1;
+	n->blossom_next_edge = -1;
+	n->blossom_parent = -1;
+	n->tree_root = -1;
+        n->hit = 0;
+    }
+#if 0
+    /* Take all 0-slack edges directly, old version */
+    count = 0;
+    for (i = 0, e = G->edgelist; i < ecount; i++, e++) {
+	if (e->slack == 0) {
+	    if ((nodelist[e->nod1].status == UNMATCHED) &&
+                (nodelist[e->nod2].status == UNMATCHED)) {
+		e->x = 1;
+		nodelist[e->nod1].matched_edge = i;
+		nodelist[e->nod2].matched_edge = i;
+		nodelist[e->nod1].status = MATCHED;
+		nodelist[e->nod2].status = MATCHED;
+		count += 2;
+	    }
+	}
+    }
+#else
+    /* Take all 0-slack edges directly & make better pi, new version */
+    count = 0;
+    for (i = 0, n = nodelist; i < ncount; i++, n++) {
+	delta = INTEGER_MAX;
+	if (n->status == UNMATCHED) {
+            for (ei = n->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+                e = PEDGE(ei/2); 
+		if (e->slack <= delta) {
+		    if (e->slack == 0) {
+			if ((nodelist[e->nod1].status == UNMATCHED) && 
+                            (nodelist[e->nod2].status == UNMATCHED)) {
+			    e->x = 1;
+			    nodelist[e->nod1].matched_edge = IEDGE(e);
+			    nodelist[e->nod2].matched_edge = IEDGE(e);
+			    nodelist[e->nod1].status = MATCHED;
+			    nodelist[e->nod2].status = MATCHED;
+			    count += 2;
+			}
+		    }
+		    delta = e->slack;
+		}
+	    }
+	    if (delta != 0) {
+		n->pi += delta;
+                for (ei = n->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+                    e = PEDGE(ei/2);
+                    e->slack -= delta;
+		}
+	    }
+	}
+    }
+#endif
+    //    printf (" %i nodes ", count); fflush (stdout);
+
+    G->unmatched_count = ncount - count;
+
+    srk->shrinks_max = ncount / 10 + 10;  /* was just ncount */
+    srk->shrinks.ary = CC_SAFE_MALLOC (srk->shrinks_max, shrink_ary_T);
+    srk->expands_max = ncount / 10 + 10;
+    srk->expands.node = CC_SAFE_MALLOC (srk->expands_max, int);
+
+    if (!srk->shrinks.ary || !srk->expands.node) {
+        fprintf (stderr, "out of memory in init\n");
+        CC_IFFREE (srk->shrinks.ary, shrink_ary_T);
+        CC_IFFREE (srk->expands.node, int);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void init_tree (graph *G, node *n)
+#else
+static void init_tree (G, n)
+graph *G;
+node *n;
+#endif
+{
+#if PRINT_LEVEL
+    printf ("  init_tree %i\n", (int) (n - PG->nodelist)); fflush (stdout);
+#endif
+    n->child = -1;
+    n->sibling = -1;
+    n->parent = -1;
+    n->parent_edge = -1;
+    n->label = PLUS;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clear_tree (graph *G, node *n)
+#else
+static void clear_tree (G, n)
+graph *G;
+node *n;
+#endif
+{
+    node *c = n;
+    node *stop = G->nodelist -1;
+
+    while (1) {
+	c->mark = 0;
+	c->label = NIX;
+	c->tree_root = -1;	/* ??? */
+
+	/* go to next c */
+	if (c->child!=-1) {
+	    c=PNODE(c->child);
+	}
+	else {
+	    while (PNODE(c->sibling)==stop) {
+		if (c==n) return ; /* this if is for an n without childs */
+		c=PNODE(c->parent);
+		if (c==n) return ;
+	    }
+	    c=PNODE(c->sibling);
+	}
+    }
+}
+
+/* make_cycle_halves - edge from i to j, k is the "root" */
+#ifdef CC_PROTOTYPE_ANSI
+static void make_cycle_halves (graph *G, node *node_i, node *node_j,
+                               node *node_k, edge *e)
+#else
+static void make_cycle_halves (G, node_i, node_j, node_k, e)
+graph *G;
+node *node_i, *node_j, *node_k;
+edge *e;
+#endif
+{
+    edge *edgelist = G->edgelist;
+    node *parent;
+
+#if PRINT_LEVEL
+    printf ("    Make cycle halves: root %i ends %i and %i:",
+	  (int) (node_k - PG->nodelist), (int) (node_i - PG->nodelist),
+          (int) (node_j - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    /* set matched_edge for node_j */
+    node_j->status = HALVES;
+    node_j->matched_edge = e - edgelist;
+    e->x = HALF;
+
+    /* path from i to k : matched_edges are the parent_edges */
+    for (; node_i != node_k; node_i = PNODE(node_i->parent)) {
+        edgelist[node_i->parent_edge].x = HALF;
+	node_i->matched_edge = node_i->parent_edge;
+	node_i->status = HALVES;
+    }
+
+    /* path from j to k : matched_edges are the "child_edges" */
+    for (; node_j != node_k; node_j = parent) {
+        parent = PNODE(node_j->parent);
+	edgelist[node_j->parent_edge].x = HALF;
+	parent->matched_edge = node_j->parent_edge;
+	parent->status = HALVES;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lift_edges (graph *G, node *newnode)
+#else
+static int lift_edges (G, newnode)
+graph *G;
+node *newnode;
+#endif
+{
+    node *n, *node_k;
+    node *nodelist = G->nodelist;
+    int nn = INODE(newnode);
+    edge *e;
+    int ei, einext;
+
+#if PRINT_LEVEL
+    printf ("Lift edges %i\n", nn); fflush (stdout);
+#endif
+
+    n = node_k = PNODE(newnode->blossom_root);
+    do {
+        ei = n->edg_list;
+        n->edg_list = -1;
+        for (; ei != -1; ei = einext) {
+            e = PEDGE(ei/2);
+            einext = e->ptrs[ei % 2];
+	    if ((nodelist[e->nod1].blossom_parent == nn) &&
+                (nodelist[e->nod2].blossom_parent == nn)) {
+                e->ptrs[ei % 2] = n->edg_list;
+                n->edg_list = ei;
+            } else {
+		if (e->nod1 == INODE(n)) {    /* nod1 is in new blossom */
+		    e->nod1 = nn;
+		} else {                      /* nod2 is in new blossom */
+		    e->nod2 = nn;
+                }
+                e->ptrs[ei % 2] = newnode->edg_list;
+                newnode->edg_list = ei;
+	    } 
+	}
+	n = PNODE(n->blossom_next);
+    } while (n != node_k);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void shrink_tree (graph *G, node *newnode)
+#else
+static void shrink_tree (G, newnode)
+graph *G;
+node *newnode;
+#endif
+{
+    node *n, *node_k, *cnode;
+    int c, csibling, p;
+
+#if PRINT_LEVEL
+    printf ("   Shrink-Tree %i\n", (int) (newnode - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    n = node_k = PNODE(newnode->blossom_root);
+    do {
+	for (c = n->child; c != -1; c = csibling) {
+            cnode = PNODE(c);
+	    csibling = cnode->sibling;
+	    if (cnode->blossom_parent != INODE(newnode)) {
+		cnode->parent = INODE(newnode);
+		cnode->sibling = newnode->child;
+		newnode->child = c;
+	    }
+	}
+	n = PNODE(n->blossom_next);
+    } while (n != node_k);
+
+    /* set other items for newnode */
+    p = node_k->parent;
+
+    newnode->sibling = -1;    /* Plus node, has no siblings */
+    newnode->parent = p;
+    newnode->parent_edge = node_k->parent_edge;
+    newnode->matched_edge = node_k->matched_edge;
+    newnode->label = PLUS;
+
+    if (p != -1)		/* _p has just one child, so this is ok */
+	G->nodelist[p].child = INODE(newnode);
+}
+
+/* shrink blossom - edge from i to j, k is the "root" */
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *shrink_blossom (graph *G, node *node_i, node *node_j,
+                             node *node_k, edge *e, stats *scount)
+#else
+static node *shrink_blossom (G, node_i, node_j, node_k, e, scount)
+graph *G;
+node *node_i, *node_j, *node_k;
+edge *e;
+stats *scount;
+#endif
+{
+    node *newnode;
+    node *parent;
+
+#if PRINT_LEVEL
+    printf ("    Shrink blossom: root %i ends %i and %i:\n",
+       (int) (node_k - PG->nodelist), (int) (node_i - PG->nodelist),
+       (int) (node_j - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    scount->shrink_count++;
+
+    newnode = PNODE(G->unused);
+    G->unused = newnode->mark;
+    newnode->mark = 0;
+    newnode->edg_list = -1;
+
+    if (node_k->status == UNMATCHED) {
+        G->roots[node_k->tree_root].surf = INODE(newnode);
+    }
+
+    /* set blossom_next,next_edge,parent for node_j */
+    /* blossom_root has to stay the same */
+
+    node_j->blossom_next = INODE(node_i);
+    node_j->blossom_next_edge = IEDGE(e);
+    node_j->blossom_parent = INODE(newnode);
+
+    /* path from i to k : blossom_next_edges are the parent_edges */
+
+    for (; node_i != node_k; node_i = PNODE(node_i->parent)) {
+	node_i->blossom_next_edge = node_i->parent_edge;
+	node_i->blossom_next = node_i->parent;
+	node_i->blossom_parent = INODE(newnode);
+    }
+
+    /* path from j to k : blossom_next_edges are the "child_edges" */
+
+    for (; node_j != node_k; node_j = parent) {
+        parent = PNODE(node_j->parent);
+	parent->blossom_next_edge = node_j->parent_edge;
+	parent->blossom_next = INODE(node_j);
+	parent->blossom_parent = INODE(newnode);
+    }
+
+    newnode->blossom_root = INODE(node_k);
+    newnode->blossom_next = -1;
+    newnode->blossom_next_edge = -1;
+    newnode->blossom_parent = -1;
+
+    newnode->mark = 0;
+    newnode->pi = 0;
+    newnode->status = node_k->status;
+    newnode->tree_root = node_k->tree_root;
+
+    shrink_tree (G, newnode);
+    if (lift_edges (G, newnode)) {   
+        fprintf (stderr, "lift_edges failed\n");
+        return (node *) NULL;
+    } 
+
+    return newnode;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void label_penultimate (graph *G, node *n, int label)
+#else
+static void label_penultimate (G, n, label)
+graph *G;
+node *n;
+int label;
+#endif
+{
+    /* all the leafs of the blossom_tree under n get the penultimate label */
+    node *n2;
+
+    if (n->blossom_root == -1) {
+	n->penultimate = label;
+	return;
+    }
+
+    n2 = n;
+    while (1) {
+	if (n2->blossom_root != -1) { 
+	    n2 = PNODE(n2->blossom_root);
+	} else {
+	    n2->penultimate = label;
+	    while (n2->blossom_next == 
+                   PNODE(n2->blossom_parent)->blossom_root) {
+		n2 = PNODE(n2->blossom_parent);
+		if (n2 == n) return;
+	    }
+	    n2 = PNODE(n2->blossom_next);
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lower_edges (graph *G, node *old)
+#else
+static int lower_edges (G, old)
+graph *G;
+node *old;
+#endif
+{
+    edge *e;
+    int ei, einext;
+    node *x;
+
+#if PRINT_LEVEL
+    printf ("Lower edges %i !\n", (int) (old - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    for (ei = old->edg_list; ei != -1; ei = einext) {
+        e = PEDGE(ei/2);
+        einext = e->ptrs[ei % 2];
+	if (e->nod1 == INODE(old)) {
+	    x = PNODE(e->orig_nod1);
+	    e->nod1 = x->penultimate;
+	} else {
+	    x = PNODE(e->orig_nod2);
+	    e->nod2 = x->penultimate;
+	}
+        e->ptrs[ei % 2] = PNODE(x->penultimate)->edg_list;
+        PNODE(x->penultimate)->edg_list = ei;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fix_matching (graph *G, node *oldnode, node *x)
+#else
+static void fix_matching (G, oldnode, x)
+graph *G;
+node *oldnode, *x;
+#endif
+{
+    node *n, *memo;
+    node *nodelist = G->nodelist;
+    edge *e;
+
+#if PRINT_LEVEL
+    printf ("    Fix Matching %i; x = %i\n",
+                (int) (oldnode - PG->nodelist), (int) (x - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    if (x->blossom_next_edge == x->matched_edge) {
+        n = x;
+        memo = PNODE(oldnode->blossom_root);
+    } else {
+        n = PNODE(oldnode->blossom_root);
+        memo = x;
+    }
+
+    for (; n != memo; n = PNODE(n->blossom_next)) {
+        e = PEDGE(n->blossom_next_edge);
+        e->x = 1 - e->x;
+        if (e->x == 1) {
+            nodelist[e->nod1].status = MATCHED;
+	    nodelist[e->nod2].status = MATCHED;
+	    nodelist[e->nod1].matched_edge = IEDGE(e);
+	    nodelist[e->nod2].matched_edge = IEDGE(e);
+        }
+    }
+
+    oldnode->blossom_root = INODE(x);
+    x->matched_edge = oldnode->matched_edge;
+    x->status = MATCHED;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fix_tree (graph *G, node *oldnode, node *x, node *y)
+#else
+static void fix_tree (G, oldnode, x, y)
+graph *G;
+node *oldnode, *x, *y;
+#endif
+{
+    node *p, *n, *cnode;
+    int c, label_help;
+
+    p = PNODE(oldnode->parent);
+
+#if PRINT_LEVEL
+    printf ("    Fix Tree %i; x = %i; y = %i\n",
+        (int) (oldnode - PG->nodelist), (int) (x - PG->nodelist),
+        (int) (y - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    /* Restore child-sibling list for p */
+
+    if (p->child == INODE(oldnode)) {
+	y->sibling = oldnode->sibling;
+	p->child = INODE(y);
+    } else {
+	for (c = p->child; c != -1; c = cnode->sibling) {
+            cnode = PNODE(c);
+	    if (cnode->sibling == INODE(oldnode)) {
+		cnode->sibling = INODE(y);
+		y->sibling = oldnode->sibling;
+		break;
+	    }
+	}
+        assert (c != -1);
+    }
+
+    y->parent = INODE(p);
+    y->parent_edge = oldnode->parent_edge;
+    G->nodelist[oldnode->child].parent = INODE(x);
+    x->child = oldnode->child;
+
+    label_help = MINUS;
+    if (y->blossom_next_edge == y->matched_edge) {
+        /* From y to x */
+	for (n = y; n != x; n = PNODE(n->blossom_next)) {
+	    n->child = n->blossom_next;
+	    G->nodelist[n->blossom_next].parent = INODE(n);
+	    G->nodelist[n->blossom_next].parent_edge = n->blossom_next_edge;
+	    n->label = label_help;
+	    if (label_help == MINUS) {
+		label_help = PLUS;
+	    } else {
+		label_help = MINUS;
+	    }
+	}
+	x->label = MINUS;	/* This is not set in for-loop */
+    } else {
+	for (n = x; n != y; n = PNODE(n->blossom_next)) {
+            /* From x to y */
+	    n->parent = n->blossom_next;
+	    n->parent_edge = n->blossom_next_edge;
+	    G->nodelist[n->blossom_next].child = INODE(n);
+	    n->label = label_help;
+	    if (label_help == MINUS) {
+		label_help = PLUS;
+	    } else {
+		label_help = MINUS;
+	    }
+	}
+	y->label = MINUS;	/* This is not set in for-loop */
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int expand_blossom (graph *G, node *oldnode, stats *scount)
+#else
+static int expand_blossom (G, oldnode, scount)
+graph *G;
+node *oldnode;
+stats *scount;
+#endif
+{
+    node *memo, *x, *y, *n;
+    int child, parent;
+
+    scount->expand_count++;
+
+#if PRINT_LEVEL
+    printf ("    Expand blossom %i \n", (int) (oldnode - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    child = oldnode->child;
+    parent = oldnode->parent;
+
+    n = memo = PNODE(oldnode->blossom_root);
+    do {
+	label_penultimate (G, n, INODE(n));
+	n = PNODE(n->blossom_next);
+    } while (n != memo);
+
+    if (G->edgelist[oldnode->matched_edge].nod1 == INODE(oldnode))
+	x = PNODE(G->edgelist[oldnode->matched_edge].orig_nod1);
+    else
+	x = PNODE(G->edgelist[oldnode->matched_edge].orig_nod2);
+
+    if (G->edgelist[oldnode->parent_edge].nod1 == INODE(oldnode))
+	y = PNODE(G->edgelist[oldnode->parent_edge].orig_nod1);
+    else
+	y = PNODE(G->edgelist[oldnode->parent_edge].orig_nod2);
+
+    if (lower_edges (G, oldnode)) {
+        fprintf (stderr, "lower_edges failed\n");
+        return 1;
+    }
+    fix_matching (G, oldnode, PNODE(x->penultimate));
+
+    n = memo;
+    do {
+	/* Clear tree structure of nodes in oldnodes blossom */
+	n->blossom_parent = -1;
+	n->child = -1;
+	n->parent = -1;
+	n->sibling = -1;
+	n->parent_edge = -1;
+	n->label = NIX;
+
+	n = PNODE(n->blossom_next);
+        n->hit = n->hit | oldnode->hit;
+    } while (n != memo);
+
+    fix_tree (G, oldnode, PNODE(x->penultimate), PNODE(y->penultimate));
+
+    /* update tree roots */
+
+    for (child = G->nodelist[child].parent; child != parent;
+                                            child = G->nodelist[child].parent) {
+	G->nodelist[child].tree_root = G->nodelist[parent].tree_root;
+    }
+
+    /* clear oldnode */
+
+    oldnode->edg_list = -1;
+    oldnode->pi = 0;
+    oldnode->status = UNMATCHED;
+    oldnode->matched_edge = -1;
+    oldnode->child = -1;
+    oldnode->sibling = -1;
+    oldnode->parent = -1;
+    oldnode->parent_edge = -1;
+    oldnode->label = NIX;
+    oldnode->blossom_root = -1;
+    oldnode->blossom_next = -1;
+    oldnode->blossom_next_edge = -1;
+    oldnode->blossom_parent = -1;
+    oldnode->penultimate = -1;
+    oldnode->tree_root = -1;
+    oldnode->hit = 0;
+
+    /* put oldnode on unused list */
+
+    oldnode->mark = G->unused;
+    G->unused = oldnode - G->nodelist;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *common_parent (graph *G, node *p, node *q, int *size)
+#else
+static node *common_parent (G, p, q, size)
+graph *G;
+node *p, *q;
+int *size;
+#endif
+{
+    int count;
+    node *n;
+    node *stop = G->nodelist - 1;
+
+#if PRINT_LEVEL
+    printf ("     Common-parent from %i and %i is ",
+          (int) (p - PG->nodelist), (int) (q - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    for (count = 0, n = p; n != stop; n = PNODE(n->parent)) {
+	count++;
+	n->mark = count;
+    }
+
+    for (count = 0; q != stop; q = PNODE(q->parent)) {
+	if (q->mark) {
+            *size = (count + q->mark);
+	    for (n = p; n != stop; n = PNODE(n->parent)) 
+		n->mark = 0;
+	    return q;
+	}
+	count++;
+    }
+    for (n = p; n != stop; n = PNODE(n->parent))
+	n->mark = 0;		
+
+    *size = 0;
+    return (node *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flip_cycle (graph *G, node *node_i)
+#else
+static void flip_cycle (G, node_i)
+graph *G;
+node *node_i;
+#endif
+{
+    int count = 0, ok = 1;
+    node *node_j, *node_k;
+    edge *e, *memo;
+
+#if PRINT_LEVEL
+    printf ("     Flip cycle with root %i: ", (int) (node_i - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    /* init start (node_j, node_k, e) */
+
+    e = PEDGE(node_i->matched_edge);
+    node_j = node_i;
+    node_k = OTHEREND (e, node_i, G->nodelist);
+
+    while (ok) {
+	/* test if last edge */
+	if (node_k == node_i)
+	    ok = 0;
+
+	e->x = (count % 2);
+	memo = PEDGE(node_k->matched_edge);
+
+	if (count % 2) {
+	    node_j->matched_edge = node_k->matched_edge = IEDGE(e);
+	    node_j->status = MATCHED;
+	    node_k->status = MATCHED;
+	}
+
+	e = memo;
+	node_j = node_k;
+        node_k = OTHEREND (e, node_j, G->nodelist);
+	count++;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void augment_path (graph *G, node *n, int fractional)
+#else
+static void augment_path (G, n, fractional)
+graph *G;
+node *n;
+int fractional;
+#endif
+{
+    edge *edgelist = G->edgelist;
+    node *nodelist = G->nodelist;
+
+#if PRINT_LEVEL
+    printf ("      Augment path %i", (int) (n - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    if (n->parent != -1) {
+	for (; n->parent_edge != -1; n = PNODE(n->parent)) {
+	    edgelist[n->parent_edge].x = 1 - edgelist[n->parent_edge].x;
+	    if (edgelist[n->parent_edge].x == 1) {
+		nodelist[edgelist[n->parent_edge].nod1].matched_edge =
+                             n->parent_edge;
+		nodelist[edgelist[n->parent_edge].nod2].matched_edge =
+                             n->parent_edge;
+	    }
+	}
+    }
+    n->status = MATCHED;  /* This will be corrected in HALVES case */
+    if (!fractional) 
+        G->roots[n->tree_root].status = MATCHED;
+    clear_tree (G, n);   /* n is the root */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int augment_blossom (graph *G, edge *e, int fractional, srkstuff *srk)
+#else
+static int augment_blossom (G, e, fractional, srk)
+graph *G;
+edge *e;
+int fractional;
+srkstuff *srk;
+#endif
+{
+    node *node_i = PNODE(e->nod1);
+    node *node_j = PNODE(e->nod2);
+    node *node_k;
+    int size;
+    shrink_ary_T *ary = srk->shrinks.ary;
+
+#if PRINT_LEVEL
+    printf ("    Augment blossom with ends %i & %i \n", e->nod1, e->nod2);
+    fflush (stdout);
+#endif
+
+    node_k = common_parent (G, node_i, node_j, &size);
+    if (node_k == (node *) NULL) {    /* more then one tree */
+	e->x = 1;
+	node_i->matched_edge = e -G->edgelist;
+	node_j->matched_edge = e -G->edgelist;
+	G->unmatched_count -= 2;
+	augment_path (G, node_i, fractional);
+	augment_path (G, node_j, fractional);
+	return 1;
+    } else {
+	if (fractional) {
+	    make_cycle_halves (G, node_i, node_j, node_k, e);
+	    augment_path (G, node_k, fractional);
+            node_k->status = HALVES;
+	    G->unmatched_count--;
+	    return 1;
+	} else {
+	    if (srk->shrinks.length < srk->shrinks_max) {
+		ary[srk->shrinks.length].node_i = node_i - G->nodelist;
+		ary[srk->shrinks.length].node_j = node_j - G->nodelist;
+		ary[srk->shrinks.length].node_k = node_k - G->nodelist;
+		ary[srk->shrinks.length].edge = e - G->edgelist;
+		ary[srk->shrinks.length].size = size;
+		srk->shrinks.length++;
+                if (srk->shrinks.length == srk->shrinks_max) {
+		    printf ("   WARNING: shrinks.length==shrinks_max=%i\n",
+                               srk->shrinks_max);
+		    fflush (stdout);
+                }
+	    }
+            return 0;
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_to_tree (graph *G, edge *e, node *node_i, node *node_j,
+                        int fractional)
+#else
+static int add_to_tree (G, e, node_i, node_j, fractional)
+graph *G;
+edge *e;
+node *node_i, *node_j;
+int fractional;
+#endif
+{
+    node *node_k;
+    edge *f;
+
+#if PRINT_LEVEL
+    printf ("    Add (%i,%i)=(%i,%i) to tree \n", e->nod1,
+       e->nod2, (int) (node_i - PG->nodelist), (int) (node_j - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    if (node_j->status == UNMATCHED) {
+	e->x = 1;
+	node_j->status = MATCHED;
+	node_i->matched_edge = e - G->edgelist;
+	node_j->matched_edge = e - G->edgelist;
+	G->unmatched_count -= 2;
+        if (!fractional) 
+            G->roots[node_j->tree_root].status = MATCHED;
+	augment_path (G, node_i, fractional);
+	return 1;
+    } else if (node_j->status == HALVES) {
+	flip_cycle (G, node_j);
+	e->x = 1;
+	node_i->status = MATCHED;
+	node_j->status = MATCHED;
+	node_i->matched_edge = e - G->edgelist;
+	node_j->matched_edge = e - G->edgelist;
+	augment_path (G, node_i, fractional);
+	G->unmatched_count--;
+	return 1;
+    } else {
+	/* set node_j in tree */
+	node_j->sibling = node_i->child;
+	node_j->parent = INODE(node_i);
+	node_j->tree_root = node_i->tree_root;
+	node_j->parent_edge = IEDGE(e);
+	node_j->label = MINUS;
+
+	/* set child for node_i */
+	node_i->child = INODE(node_j);
+
+	/* set child for node_j */
+	f = PEDGE(node_j->matched_edge);
+        node_k = OTHEREND (f, node_j, G->nodelist);
+	node_j->child = INODE(node_k);
+
+	/* set node_k in tree */
+	node_k->child = -1;
+	node_k->sibling = -1;
+	node_k->parent = INODE(node_j);
+	node_k->parent_edge = IEDGE(f);
+	node_k->label = PLUS;
+	node_k->tree_root = node_j->tree_root;
+
+	return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkout_node (graph *G, node *n, int fractional, srkstuff *srk)
+#else
+static int checkout_node (G, n, fractional, srk)
+graph *G;
+node *n;
+int fractional;
+srkstuff *srk;
+#endif
+{
+    node *m;
+    int augmented;
+    edge *e;
+    int ei;
+
+#if PRINT_LEVEL
+    printf ("   Checkout node %i ...\n", (int) (n - PG->nodelist));
+    fflush (stdout);
+#endif
+ 
+    for (ei = n->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+        e = PEDGE(ei/2);
+        if (e->slack == 0) {
+            m = OTHEREND (e, n, G->nodelist);
+	    if (m->label == PLUS) {
+		return augment_blossom (G, e, fractional, srk);
+	    }
+	    if (m->label == NIX) {
+		if ((augmented = add_to_tree (G, e, n, m, fractional)) != 0) {
+		    return augmented;
+		}
+            }
+	}
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grow_tree_no_shrink (graph *G, node *n, int fractional,
+           srkstuff *srk)
+#else
+static int grow_tree_no_shrink (G, n, fractional, srk)
+graph *G;
+node *n;
+int fractional;
+srkstuff *srk;
+#endif
+{
+    int augmented;
+    expand_T *expands = &(srk->expands);
+    int expands_max = srk->expands_max;
+    node *c=n;
+    node *stop = G->nodelist - 1;
+
+#if PRINT_LEVEL
+    printf ("   growtree no shrink %i\n", (int) (c - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    while (1) {
+	if (c->label == PLUS) {
+	    if ((augmented = checkout_node (G, c, fractional, srk)) > 0) {
+		return augmented;
+	    }
+	} else {			/* MINUS node */
+	    if (c->blossom_root != -1 && c->pi == 0) {
+		if (expands->length < expands_max) {
+		    expands->node[expands->length] = c - G->nodelist;
+		    expands->length++;
+		    if (expands->length == expands_max) {
+			printf ("   WARNING: expands = expands_max = %i\n",
+				expands_max);
+			fflush (stdout);
+		    }
+		}
+	    }
+	}
+	/* go to next c */
+	if (c->child!=-1) {
+	    c=PNODE(c->child);
+	} else {
+	    while (PNODE(c->sibling) == stop) {
+		if (c == n) return 0; /* this if is for childless n */
+		c = PNODE(c->parent);
+		if (c == n) return 0;
+	    }
+	    c = PNODE(c->sibling);
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grow_tree (graph *G, node *n, int fractional, stats *scount,
+                      srkstuff *srk, int *found_aug)
+#else
+static int grow_tree (G, n, fractional, scount, srk, found_aug)
+graph *G;
+node *n;
+int fractional;
+stats *scount;
+srkstuff *srk;
+int *found_aug;
+#endif
+{
+    int i, size;
+    node *node_i, *node_j, *node_k, *newnode;
+    edge *e;
+    shrink_ary_T *ary = srk->shrinks.ary;
+    expand_T *expands = &(srk->expands);
+    int *shrinks_ = srk->shrinks_;
+    shrink_T *shrinks = &(srk->shrinks);
+    int old_shrinks_len;
+
+    *found_aug = 0;
+
+    do {
+        FIND_SURFACE (n);
+	shrinks->length = 0;
+	expands->length = 0;
+
+	if (grow_tree_no_shrink (G, n, fractional, srk)) {
+            *found_aug = 1;
+	    return 0;         
+        }
+
+        /* found no new match edge, so do shrinks */
+
+        while (shrinks->length) {
+            old_shrinks_len = shrinks->length;
+            if (shrinks->length > 4) {   
+                /* build buckets for all different sizes */
+                for (i = 0; i < SHRINKS_SIZE; i++)
+                    shrinks_[i] = -1;
+                for (i = 0; i < shrinks->length; i++) {
+                    size = ary[i].size;
+                    if (size >= SHRINKS_SIZE)
+                        size = SHRINKS_SIZE - 1;
+                    if (shrinks_[size] == -1) {
+                        shrinks_[size] = i;
+                        ary[i].next = -1;
+                    } else {
+                        ary[i].next = shrinks_[size];
+                        shrinks_[size] = i;
+                    }
+                }
+                for (size = SHRINKS_SIZE - 1; size >= 3; size -= 2) {
+                    for (i = shrinks_[size]; i != -1; i = ary[i].next) {
+                        node_i = PNODE(ary[i].node_i);
+                        node_j = PNODE(ary[i].node_j);
+                        node_k = PNODE(ary[i].node_k);
+                        e = PEDGE(ary[i].edge);
+                        FIND_SURFACE (node_i);
+                        FIND_SURFACE (node_j);
+                        FIND_SURFACE (node_k);
+                        if (node_i != node_j) {
+                            newnode = shrink_blossom (G, node_i, node_j,
+                                                      node_k, e, scount);
+                            if ((checkout_node(G,newnode,fractional,srk)) >0) {
+                                *found_aug = 1;
+                                return 0;
+                            }
+                        }
+                    }
+                }
+            } else {      /* just do all of the stupid shrinks */
+                for (i = 0; i < shrinks->length; i++) {
+                    node_i = PNODE(ary[i].node_i);
+                    node_j = PNODE(ary[i].node_j);
+                    node_k = PNODE(ary[i].node_k);
+                    e = PEDGE(ary[i].edge);
+                    FIND_SURFACE (node_i);
+                    FIND_SURFACE (node_j);
+                    FIND_SURFACE (node_k);
+                    if (node_i != node_j) {
+                        newnode = shrink_blossom (G, node_i, node_j,
+                                                  node_k, e, scount);
+                        if ((checkout_node (G, newnode, fractional, srk)) > 0) {
+                            *found_aug = 1;
+                            return 0;
+                        }
+                    }
+                }
+            }
+            if (shrinks->length > old_shrinks_len) {
+                size = shrinks->length - old_shrinks_len;
+                for (i = 0; i < size; i++) {
+                    ary[i].node_i = ary[i + old_shrinks_len].node_i;
+                    ary[i].node_j = ary[i + old_shrinks_len].node_j;
+                    ary[i].node_k = ary[i + old_shrinks_len].node_k;
+                    ary[i].edge = ary[i + old_shrinks_len].edge;
+                    ary[i].size = ary[i + old_shrinks_len].size;
+                }
+                shrinks->length = size;
+            } else {
+                shrinks->length = 0; 
+            }
+        }
+	for (i = 0; i < expands->length; i++) {
+	    /* blossom_root != -1 is necessary because expand
+	     * of this node might have happened here before */
+	    /* blossom_parent == -1 is necessary because
+	     * this node might be shrunk already */
+	    if (G->nodelist[expands->node[i]].blossom_root != -1 &&
+                G->nodelist[expands->node[i]].blossom_parent == -1) {
+		if (expand_blossom (G, G->nodelist+expands->node[i], scount)) {
+                    fprintf (stderr, "expand_blossom failed\n");
+                    return 1;
+                }
+	    }
+	}
+    } while (expands->length > 0);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int apply_dual_change (graph *G, node *n, int delta)
+#else
+static int apply_dual_change (G, n, delta)
+graph *G;
+node *n;
+int delta;
+#endif
+{
+    int ei;
+    edge *e;
+    node *c=n;
+    node *stop = G->nodelist - 1;
+
+    if (delta == INTEGER_MAX) {
+      //      	fprintf (stderr, "\ndelta=Infinity, node=%i\n", (int) (n-G->nodelist));
+      //      	fprintf (stderr, "There seems to be no perfect matching\n");
+      //	FAILED_NODE = (int)INODE(n);
+      //      	print_node (G, n);
+      return 1;
+    }
+
+    while (1) {
+	if (c->label == PLUS) {
+            c->hit = 1;
+	    c->pi += delta;
+	    for (ei = c->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+		e = PEDGE(ei/2);
+		e->slack -= delta;
+	    }
+	} else if (c->label == MINUS) {
+	    c->pi -= delta;
+	    for (ei = c->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+		e = PEDGE(ei/2);
+		e->slack += delta;
+	    }
+	}
+
+	/* go to next c */
+
+	if (c->child != -1) {
+	    c = PNODE(c->child);
+	} else {
+	    while (PNODE(c->sibling) == stop) {
+		if (c == n) return 0; /* this if is for childless n */
+		c = PNODE(c->parent);
+		if (c == n) return 0;
+	    }
+	    c = PNODE(c->sibling);
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_single_dual_change (graph *G, node *n)
+#else
+static int find_single_dual_change (G, n)
+graph *G;
+node *n;
+#endif
+{
+    edge *e;
+    int ei;
+    int lab;
+    int delta;
+    node *c = n;
+    node *stop = G->nodelist - 1;
+
+#if PRINT_LEVEL
+    printf (" %i", (int) (n - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    delta = INTEGER_MAX;
+
+    while (1) {
+	if (c->label == PLUS) {
+	    for (ei = c->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+		e = PEDGE(ei/2);
+		if (e->slack < 2 * delta) {
+		    lab = OTHEREND (e, c, G->nodelist)->label;
+		    if (lab == PLUS) {
+			delta = e->slack / 2;
+		    } else if (lab == NIX) {
+			if (e->slack < delta) {
+			    delta = e->slack;
+			}
+		    }
+		}
+	    }
+	} else if (c->label == MINUS) {
+	    if (c->blossom_root != -1 && c->pi < delta) {
+		delta = c->pi;
+	    }
+	}
+
+	/* go to next c */
+
+	if (c->child != -1) {
+	    c = PNODE(c->child);
+	} else {
+	    while (PNODE(c->sibling) == stop) {
+		if (c == n) return delta ; /* this if is for childless n */
+		c = PNODE(c->parent);
+		if (c == n) return delta;
+	    }
+	    c = PNODE(c->sibling);
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_dual_change_forest (graph *G, node *n)
+#else
+static int find_dual_change_forest (G, n)
+graph *G;
+node *n;
+#endif
+{
+    edge *e;
+    int ei;
+    int delta;
+    nodeptr *roots = G->roots;
+    node *c = n, *o;
+    node *stop = G->nodelist - 1;
+
+#if PRINT_LEVEL
+    printf (" %i", (int) (c - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    delta = INTEGER_MAX;
+
+    while (1) {
+	if (c->label == PLUS) {
+	    for (ei = c->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+		e = PEDGE(ei/2);
+		o = OTHEREND (e, c, G->nodelist);
+		switch (o->label) {
+#ifdef GREEDY_DUAL_CHANGE
+                case PLUS:
+                    if (roots[c->tree_root].dad != roots[o->tree_root].dad ) {
+                        /* two trees, not connected with vereinigung */
+                        if (roots[o->tree_root].tree_processed) {
+                            if (delta > e->slack -
+                                        roots[roots[o->tree_root].dad].delta) {
+                                delta = e->slack -
+                                        roots[roots[o->tree_root].dad].delta;
+                            }
+                        } else {
+                            if (e->slack < delta) {
+                                delta = e->slack;
+                            }
+                        }
+                    } else {
+                        if (e->slack < 2 * delta) {
+                            delta = e->slack / 2;
+                        }
+                    }
+                    break;
+                case NIX:
+                    if (e->slack < delta) {
+                        delta = e->slack;
+                    }
+                    break;
+                case MINUS:
+                    if (roots[c->tree_root].dad != roots[o->tree_root].dad) {
+                        /* two trees, not connected with vereinigung */
+                        if (roots[o->tree_root].tree_processed) { 
+                            if (delta > e->slack +
+                                        roots[roots[o->tree_root].dad].delta) {
+                                delta = e->slack +
+                                        roots[roots[o->tree_root].dad].delta;
+                            }
+                        } else {
+                            if (e->slack < delta ) {
+                                delta = e->slack;
+                            }
+                        }
+                    }
+                }
+#else /* GREEDY_DUAL_CHANGE */
+		case PLUS:
+		    if (e->slack < 2 * delta) {
+		        delta = e->slack / 2;
+		    }
+		    break;
+		case NIX:
+		    if (e->slack < delta) {
+			delta = e->slack;
+		    }
+		    break;
+		case MINUS:
+		    if (roots[c->tree_root].dad != roots[o->tree_root].dad) { 
+		        if (e->slack < delta ) {
+			    delta = e->slack;
+			}
+		    }
+		}
+#endif /* GREEDY_DUAL_CHANGE */
+	    }
+	} else if (c->label == MINUS) {
+	    if (c->blossom_root != -1 && c->pi <= delta) {
+		delta = c->pi;
+	    }
+	}
+	
+	/* go to next c */
+
+	if (c->child != -1) {
+	    c = PNODE(c->child);
+	} else {
+	    while (PNODE(c->sibling) == stop) {
+		if (c == n) return delta ; /* this is for childless n */
+		c = PNODE(c->parent);
+		if (c == n) return delta;
+	    }
+	    c = PNODE(c->sibling);
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void vereinigung (graph *G, int x, int y)
+#else
+static void vereinigung (G, x, y)
+graph *G;
+int x, y;
+#endif
+{
+    int xroot, yroot, dad;
+    nodeptr *roots = G->roots;
+
+#if PRINT_LEVEL
+    printf (" vereinigung (%i,%i)", x, y); fflush (stdout);
+#endif
+
+    xroot = x;
+    while (roots[xroot].dad >= 0)
+	xroot = roots[xroot].dad;
+    while (roots[x].dad >= 0) {
+        dad = roots[x].dad;
+        roots[x].dad = xroot;
+        x = dad;
+    }
+
+    yroot = y;
+    while (roots[yroot].dad >= 0)
+	yroot = roots[yroot].dad;
+    while (roots[y].dad >= 0) {
+        dad = roots[y].dad;
+        roots[y].dad = yroot;
+        y = dad;
+    }
+
+    if (xroot != yroot) {
+	if (roots[yroot].dad < roots[xroot].dad) {
+            roots[yroot].dad += roots[xroot].dad; 
+            roots[xroot].dad = yroot;
+	} else {
+	    roots[xroot].dad += roots[yroot].dad; 
+	    roots[yroot].dad = xroot;
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void set_vereinigung (graph *G, node *n)
+#else
+static void set_vereinigung (G, n)
+graph *G;
+node *n;
+#endif
+{
+    edge *e;
+    int ei;
+    node *nod = G->nodelist;
+    node *c = n;
+    node *stop = G->nodelist - 1;
+
+#if PRINT_LEVEL
+    printf (" set_vereinigung (%i)", (int) (n - PG->nodelist));
+    fflush (stdout);
+#endif
+
+    /* this is called only for PLUS nodes */
+
+    while (1) {
+	for (ei = c->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+	    e = PEDGE(ei/2);
+	    if (nod[e->nod1].tree_root != nod[e->nod2].tree_root) {  
+		if (e->slack == 0) {	
+		    if (OTHEREND (e, c, nod)->label == MINUS) {
+			vereinigung (G, nod[e->nod1].tree_root,
+				        nod[e->nod2].tree_root);
+		    }
+		}
+	    }
+	}
+	
+	/* now check the chilren of c's children (these are PLUS nodes) */
+
+	if (c->child != -1) {
+	    c = PNODE(PNODE(c->child)->child);
+	} else {
+	    if (c == n) return; /* this if is for childless n */
+	    c = PNODE(c->parent);
+	    while (PNODE(c->sibling) == stop) {
+		c = PNODE(c->parent);
+		if (c == n) return;
+		c = PNODE(c->parent);
+	    }
+	    c = PNODE(PNODE(c->sibling)->child);
+	}
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_parity_sum (graph *G, int n)
+#else
+static int find_parity_sum (G, n)
+graph *G;
+int n;
+#endif
+{
+    node *v;
+    int sum, ei;
+    edge *e;
+
+    ei = PNODE(n)->edg_list;
+    e = PEDGE(ei/2);
+
+    if (e->nod1 == n) {
+        v = PNODE(e->orig_nod1); 
+    } else {
+        v = PNODE(e->orig_nod2);
+    }
+
+    sum = v->pi;
+    while (v->blossom_parent != -1) {
+        v = PNODE(v->blossom_parent);
+        sum += v->pi;
+    }
+
+    return sum;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parity_correction (graph *G, stats *scount)
+#else
+static int parity_correction (G, scount)
+graph *G;
+stats *scount;
+#endif
+{
+    nodeptr *np, *npprev = (nodeptr *) NULL;
+    int hitme = 0;
+    nodeptr *roots = G->roots;
+    nodeptr *rstop = G->roots - 1;
+
+#if PRINT_LEVEL
+    printf ("   parity_correction ...\n"); 
+    fflush (stdout);
+#endif
+
+    np = roots + G->unmatched;
+    while (np->status != UNMATCHED)  
+        np = roots + np->next;
+    G->unmatched = np - roots;
+
+    while (np != rstop) {
+        if (np->status != UNMATCHED) {
+            npprev->next = np->next;
+        } else {
+            if (np->sum % 2) {
+                hitme = 1;
+                scount->dualchange_count++;
+                if (apply_dual_change (G, PNODE(np->surf), 1)) {
+		  //                    fprintf (stderr, "apply_dual_change failed\n");
+                    return -1;
+                }
+                np->sum += 1; 
+            }
+            npprev = np;
+        }
+        np = roots + np->next;
+    }
+    return hitme;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int make_dual_change_forest (graph *G, stats *scount)
+#else
+static int make_dual_change_forest (G, scount)
+graph *G;
+stats *scount;
+#endif
+{
+    nodeptr *np;
+    int t;
+    int delta;
+    nodeptr *roots = G->roots;
+    nodeptr *rstop = G->roots - 1;
+
+#if PRINT_LEVEL
+    printf ("\n   make_dual_change_forest ...\n");
+    fflush (stdout);
+#endif
+
+    if (parity_correction (G, scount) == -1) {
+        fprintf (stderr, "parity_correction failed\n");
+        return -1;
+    }
+
+    for (np = roots + G->unmatched; np != rstop; np = roots + np->next) 
+        np->dad = -1;     /*  Set dad for all trees to -1 */
+
+    for (np = roots + G->unmatched; np != rstop; np = roots + np->next) 
+        set_vereinigung (G, PNODE(np->surf));
+
+    /* Set roots to point to theirselves */
+    for (np = roots + G->unmatched; np != rstop; np = roots + np->next) {
+        if (np->dad < 0) {
+            np->dad = np - roots;
+            np->delta = INTEGER_MAX; 
+        }
+    }
+
+    /* Set others to point to root */
+    for (np = roots + G->unmatched; np != rstop; np = roots + np->next) {
+        t = np - roots;
+        while (roots[t].dad != t)
+            t = roots[t].dad;
+        np->dad = t;
+    }
+
+#ifdef GREEDY_DUAL_CHANGE
+    {
+        int npnext;
+        int glist = -1;
+
+        /* order the unmatched nodes so that each union appears consecutively */
+
+        for (np = roots + G->unmatched; np != rstop; np = roots + np->next) {
+            np->tree_processed = 0;
+            if (np->dad == np - roots) {
+                np->gnext = glist;
+                glist = np - roots;
+            }
+        }
+
+        for (np = roots + G->unmatched; np != rstop; np = roots + np->next) {
+            if (np->dad != np - roots) {
+                np->gnext = roots[np->dad].gnext;
+                roots[np->dad].gnext = np - roots;
+            }
+        }
+
+        for (np = roots + G->unmatched; np != rstop; np = roots + npnext) {
+            npnext = np->next;
+            np->next = np->gnext;
+        }
+        G->unmatched = glist;
+    }
+#endif
+
+    /* Set delta for all vereinigung trees */
+    for (np = roots + G->unmatched; np != rstop; np = roots + np->next) {
+	delta = find_dual_change_forest (G, PNODE(np->surf));
+	if (delta < roots[np->dad].delta)
+	    roots[np->dad].delta = delta;
+#ifdef GREEDY_DUAL_CHANGE
+        np->tree_processed = 1;
+#endif
+    } 
+
+    /* Apply_dual_change for all vereinigung trees */
+    for (np = roots + G->unmatched; np != rstop; np = roots + np->next) {
+	delta = roots[np->dad].delta;
+        scount->dualchange_count++;
+        if (delta == 0) {
+            scount->dualzero_count++;
+        } else {
+            if (apply_dual_change (G, PNODE(np->surf), delta)) {
+	      //                fprintf (stderr, "apply_dual_change failed\n");
+                return -1;
+            }
+        }
+        np->sum += delta; 
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int match_main_frac (graph *G, stats *scount, srkstuff *srk)
+#else
+static int match_main_frac (G, scount, srk)
+graph *G;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    node *n;
+    int i, delta;
+    int found_aug = 0;
+
+    /* Just work with one tree   */
+
+    for (i = 0, n = G->nodelist; i < G->nnodes; i++, n++) {
+        if (n->status == UNMATCHED) {
+	    init_tree (G, n);
+            if (grow_tree (G, n, 1, scount, srk, &found_aug)) {
+                fprintf (stderr, "grow_tree failed\n");
+                return 1;
+            }
+            while (!found_aug) {
+                scount->dualchange_count++;
+                delta = find_single_dual_change (G, n);
+                if (delta != 0) {
+                    if (apply_dual_change (G, n, delta)) {
+		      //                        fprintf (stderr, "apply_dual_change failed\n");
+                        return 1;
+                    }
+                } else {
+                    scount->dualzero_count++;
+                }
+                if (grow_tree (G, n, 1, scount, srk, &found_aug)) {
+                    fprintf (stderr, "grow_tree failed\n");
+                    return 1;
+                }
+	    }
+#if PRINT_LEVEL
+            printf ("."); fflush (stdout);
+#endif
+        }
+    }
+    //    printf (" %i Dual Changes, %i with delta=0 ",
+    //             scount->dualchange_count, scount->dualzero_count);
+    //    fflush (stdout);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int match_main_more_in_forest (graph *G, stats *scount, srkstuff *srk)
+#else
+static int match_main_more_in_forest (G, scount, srk)
+graph *G;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    nodeptr *np;
+    node *n;
+    int i, ni, ninext;
+    int grow_status_forest;
+    int found_aug = 0;
+    nodeptr *roots, *rstop;
+
+    /* The unmatched surface nodes should be linked using the mark  */
+    /* fields, with G->unmatched pointing to the start of the list. */
+    /* G->umatched is assumed to be accurate.                       */
+
+    if (G->unmatched_count == 0) 
+	return 0;
+
+    /* ********************************* */
+    /* First init all forests            */
+    /* ********************************* */
+
+    G->roots = CC_SAFE_MALLOC (G->unmatched_count, nodeptr);
+    if (!G->roots) {
+      //        fprintf (stderr, "out of memory in match_main_more_in_forest\n");
+        return 1;
+    }
+    roots = G->roots;
+    rstop = G->roots - 1;
+
+    for (i = 0, ni = G->unmatched; ni != -1; ni = ninext, i++) {
+        n = PNODE(ni);
+        ninext = n->mark;
+        n->mark = 0;
+        roots[i].status = UNMATCHED;
+        roots[i].surf = ni;
+        roots[i].sum = find_parity_sum (G, ni);
+        roots[i].next = i+1;
+        init_tree (G, n);
+        n->tree_root = i;
+    }
+    roots[i - 1].next = -1;
+    G->unmatched = 0;
+
+    //    printf ("\nTry to grow the trees in the forest directly\n");
+    //    fflush (stdout);
+
+    /* ************************************ */
+    /* Try to grow all forests directly     */
+    /* ************************************ */
+
+    for (np = roots + G->unmatched; np != rstop; np = roots + np->next) {
+        n = PNODE(np->surf);
+        if (np->status == UNMATCHED) {
+            if (grow_tree (G, n, 0, scount, srk, &found_aug)) {
+	      //                fprintf (stderr, "grow_tree failed\n");
+                return 1;
+            }
+            if (found_aug) {	 
+	      //                printf ("."); fflush (stdout);
+                if (G->unmatched_count == 0) {
+                    return 0;
+                }
+	    }
+        }
+    }
+
+    /* *************************** */
+    /* Work with tree-vereinigung  */
+    /* *************************** */
+
+    //    printf ("\nNow work on tree-vereinigung in a forest (%i points)\n",
+    //                        G->unmatched_count / 2);
+    //    fflush (stdout);
+
+    /* first make sure that all trees have the correct parity */
+
+    if (parity_correction (G, scount) == -1) {
+      //        fprintf (stderr, "parity_correction failed\n");
+        return 1;
+    }
+
+    while (G->unmatched_count > 0) {
+        if (make_dual_change_forest (G, scount) == -1) {
+	  //            fprintf (stderr, "make_dual_change_forest failed\n");
+            return 1;
+        }
+        do {
+	    grow_status_forest = 0;
+            for (np = roots + G->unmatched; np != rstop; np = roots+np->next) {
+		n = PNODE(np->surf);
+                if (np->status == UNMATCHED) {
+		    if (grow_tree (G, n, 0, scount, srk, &found_aug)) {
+		      //                        fprintf (stderr, "grow_tree failed\n");
+                        return 1;
+                    }
+		    if (found_aug) { 
+		      //		        printf ("."); fflush (stdout);
+		        if (G->unmatched_count == 0) {
+                            goto DONE;
+		        }
+		        grow_status_forest = 1;
+		    }
+	        }
+            }
+	} while (grow_status_forest);
+    }
+
+DONE:
+
+    G->unmatched = -1;
+    CC_IFFREE (G->roots, nodeptr);
+
+    //    printf ("\n %i Dual Changes, %i with delta=0 ",
+    //	       scount->dualchange_count, scount->dualzero_count);
+    //    printf ("| %i Expands ", scount->expand_count);
+    //    printf ("| %i Shrinks ", scount->shrink_count);
+    //    fflush (stdout);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int match_main_forest (graph *G, stats *scount, srkstuff *srk)
+#else
+static int match_main_forest (G, scount, srk)
+graph *G;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    nodeptr *np;
+    node *n;
+    int i, ni, ninext;
+    int grow_status_forest;
+    int found_aug = 0;
+    int delta, delta2;
+    int do_parity = 1;
+    nodeptr *roots, *rstop;
+
+    //    printf ("match_main_forest (%d points)\n", G->unmatched_count / 2);
+    //    fflush (stdout);
+
+    if (G->unmatched_count == 0) {
+	return 0;
+    }
+
+    /* ********************************* */
+    /* First init all forests            */
+    /* ********************************* */
+
+    G->roots = CC_SAFE_MALLOC (G->unmatched_count, nodeptr);
+    if (!G->roots) {
+        fprintf (stderr, "out of memory in match_main_more_in_forest\n");
+        return 1;
+    }
+    roots = G->roots;
+    rstop = G->roots - 1;
+
+    for (i = 0, ni = G->unmatched; ni != -1; ni = ninext, i++) {
+        n = PNODE(ni);
+        ninext = n->mark;
+        n->mark = 0;
+        roots[i].status = UNMATCHED;
+        roots[i].surf = ni;
+        roots[i].sum = find_parity_sum (G, ni);
+        roots[i].next = i+1;
+        init_tree (G, n);
+        n->tree_root = i;
+    }
+    roots[i - 1].next = -1;
+    G->unmatched = 0;
+
+    /* ********************************* */
+    /* Work with a forest                */
+    /* ********************************* */
+
+    while (G->unmatched_count > 0) {
+        do {
+	    grow_status_forest = 0;
+            for (np = roots + G->unmatched; np != rstop; np = roots+np->next) {
+		n = PNODE(np->surf);
+                if (np->status == UNMATCHED) {
+		    if (grow_tree (G, n, 0, scount, srk, &found_aug)) {
+		      //                        fprintf (stderr, "grow_tree failed\n");
+                        return 1;
+                    }
+		    if (found_aug) {
+		        printf ("."); fflush (stdout);
+		        if (G->unmatched_count == 0) {
+                            goto DONE;
+                        }
+		        grow_status_forest = 1;
+                    }
+		}
+	    }
+	} while (grow_status_forest);
+
+        if (G->unmatched_count > 0 && do_parity) {
+            if (parity_correction (G, scount) == -1) {
+	      //                fprintf (stderr, "parity_correction failed\n");
+                return 1;
+            }
+            do_parity = 0;
+        }
+    
+	if (G->unmatched_count > 0 && !do_parity) {
+	    delta = INTEGER_MAX;
+	    scount->dualchange_count++;
+            for (np = roots + G->unmatched; np != rstop; np = roots+np->next) {
+		n = PNODE(np->surf);
+                if (np->status == UNMATCHED) {
+		    delta2 = find_single_dual_change (G, n);
+		    if (delta2 < delta) {
+		        delta = delta2;
+                    }
+                }
+	    } 
+
+	    if (delta == 0) {
+		scount->dualzero_count++;
+            } else {
+                for (np = roots+G->unmatched; np!=rstop; np = roots+np->next) {
+		    n = PNODE(np->surf);
+                    if (np->status == UNMATCHED) {
+		        if (apply_dual_change (G, n, delta)) {
+			  //                            fprintf (stderr, "apply_dual_change failed\n");
+                            return 1;
+                        }
+                        np->sum += delta; 
+                    }
+		}
+	    }
+	}
+    }
+
+DONE:
+
+    G->unmatched = -1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int match_main_tree (graph *G, stats *scount, srkstuff *srk)
+#else
+static int match_main_tree (G, scount, srk)
+graph *G;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    nodeptr *np;
+    node *n;
+    int i, ni, ninext;
+    int found_aug = 0;
+    int delta;
+    nodeptr *roots, *rstop;
+
+    //    printf ("match_main_tree (%d points)\n", G->unmatched_count / 2);
+    //    fflush (stdout);
+
+    if (G->unmatched_count == 0) {
+	return 0;
+    }
+
+    /* ********************************* */
+    /* First init all forests            */
+    /* ********************************* */
+
+    G->roots = CC_SAFE_MALLOC (G->unmatched_count, nodeptr);
+    if (!G->roots) {
+      //        fprintf (stderr, "out of memory in match_main_more_in_forest\n");
+        return 1;
+    }
+    roots = G->roots;
+    rstop = G->roots - 1;
+
+    for (i = 0, ni = G->unmatched; ni != -1; ni = ninext, i++) {
+        n = PNODE(ni);
+        ninext = n->mark;
+        n->mark = 0;
+        roots[i].status = UNMATCHED;
+        roots[i].surf = ni;
+        roots[i].sum = find_parity_sum (G, ni);
+        roots[i].next = i+1;
+        /* init_tree (G, n); */
+        n->tree_root = i;
+    }
+    roots[i - 1].next = -1;
+    G->unmatched = 0;
+
+    /* ********************************* */
+    /* Work with a tree                  */
+    /* ********************************* */
+
+    while (G->unmatched_count > 0) {
+        np = roots + G->unmatched; 
+        while (np->status != UNMATCHED) {
+            np = roots + np->next;
+        }
+        G->unmatched = np - roots;
+        np = roots + G->unmatched; 
+        n = PNODE(np->surf);
+        init_tree (G, n);
+        do {
+            if (grow_tree (G, n, 0, scount, srk, &found_aug)) {
+	      //                fprintf (stderr, "grow_tree failed\n");
+                return 1;
+            }
+            if (found_aug) {
+                printf ("."); fflush (stdout);
+	        if (G->unmatched_count == 0) {
+                    goto DONE;
+                }
+            } else {
+                scount->dualchange_count++;
+                n = PNODE(np->surf);
+	        delta = find_single_dual_change (G, n);
+
+	        if (delta == 0) {
+	            scount->dualzero_count++;
+                } else {
+	            if (apply_dual_change (G, n, delta)) {
+		      //                        fprintf (stderr, "apply_dual_change failed\n");
+                        return 1;
+                    }
+                }
+	    }
+        } while (!found_aug);
+    }
+
+DONE:
+
+    G->unmatched = -1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int match_main (graph *G, stats *scount, srkstuff *srk, int use_all)
+#else
+static int match_main (G, scount, srk, use_all)
+graph *G;
+stats *scount;
+srkstuff *srk;
+int use_all;
+#endif
+{
+    double szeit;
+
+    szeit = CCutil_zeit ();
+    //    printf (" Need to find %i edges ...\n", G->unmatched_count / 2);
+    //    fflush (stdout);
+
+    if (!G->unmatched_count) 
+        return 0;
+
+    if (use_all == 2) {
+        if (match_main_tree (G, scount, srk)) {
+	  //            fprintf (stderr, "match_main_tree failed\n");
+            return 1;
+        }
+    } else if (use_all == 1) {
+        if (match_main_forest (G, scount, srk)) {
+	  //            fprintf (stderr, "match_main_forest failed\n");
+            return 1;
+        }
+    } else {
+        if (match_main_more_in_forest (G, scount, srk)) {
+	  //            fprintf (stderr, "match_main_more_in_forest failed\n");
+            return 1;
+        }
+    }
+    //    printf ("\n %i Dual Changes, %i with delta=0 \n",
+    //               scount->dualchange_count, scount->dualzero_count);
+    //    printf (" %i Expands \n", scount->expand_count);
+    //    printf (" %i Shrinks \n", scount->shrink_count);
+    //    printf (" Running Time in match_main: %.2f\n", CCutil_zeit () - szeit);
+    //    fflush (stdout);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *find_below (graph *G, node *n, int blossom)
+#else
+static node *find_below (G, n, blossom)
+graph *G;
+node *n;
+int blossom;
+#endif
+{
+    if (!n)
+        return (node *) NULL;
+
+    for (; n->blossom_parent != blossom; n = PNODE(n->blossom_parent)) {
+        if (n->blossom_parent == -1)
+            return (node *) NULL;
+    }
+    return n;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fix_match (graph *G, int blossom)
+#else
+static void fix_match (G, blossom)
+graph *G;
+int blossom;
+#endif
+{
+    node *x, *n;
+    node *b = blossom + G->nodelist;
+  
+#if PRINT_LEVEL
+    printf ("   Fixing blossom %i ", blossom);
+    fflush (stdout);
+#endif
+
+    x = find_below (G, PNODE(G->edgelist[b->matched_edge].orig_nod1),
+               blossom);
+    if (x == (node *) NULL) {
+	x = find_below (G, PNODE(G->edgelist[b->matched_edge].orig_nod2),
+               blossom);
+    }
+    /* x is now something like the match_edge->nod(1 or 2)->penultimate */
+    fix_matching (G, b, x);
+    b->mark = 1;
+
+    n = PNODE(b->blossom_root);
+    do {
+	if (n->blossom_root != -1)          /* if n is a real blossom */
+	    fix_match (G, INODE(n));        /* call fix match again */
+	n = PNODE(n->blossom_next);
+    } while (n != PNODE(b->blossom_root));
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void adjust_match (graph *G)
+#else
+static void adjust_match (G)
+graph *G;
+#endif
+{
+    node *n, *b;
+    int i;
+    int ncount = G->nnodes;
+    node *nodelist = G->nodelist;
+
+    for (i = 0; i < ncount; i++) {
+	n = PNODE(i);
+	if (n->blossom_parent != -1 && nodelist[n->blossom_parent].mark == 0) {
+	    for (b = n; b->blossom_parent != -1 &&
+               nodelist[b->blossom_parent].mark == 0;
+               b = PNODE(b->blossom_parent));
+	    fix_match (G, INODE(b));
+	}
+    }
+}
+
+#ifdef CARELESS_REPAIRS
+#ifdef CC_PROTOTYPE_ANSI
+static int bring_to_surface (graph *G, node *p, stats *scount, srkstuff *srk)
+#else
+static int bring_to_surface (G, p, scount, srk)
+graph *G;
+node *p;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    node *psurf, *n, *memo, *x;
+    edge *e;
+    int ei;
+
+    if (p->blossom_parent == -1) 
+        return 0;
+
+    psurf = p;
+    while (psurf->blossom_parent != -1) {
+        psurf = PNODE(psurf->blossom_parent);
+    }
+
+    while (p != psurf) {
+        scount->expand_count++;
+
+        /* Mark edge to be unmatched later */
+        G->edgelist[psurf->matched_edge].mark = 1;
+
+        for (ei = psurf->edg_list; ei != -1; ei = e->ptrs[ei % 2]) {
+            e = PEDGE(ei/2);
+            e->slack += psurf->pi;
+        }
+
+        n = memo = PNODE(psurf->blossom_root);
+        do {
+            label_penultimate (G, n, INODE(n));
+            n = PNODE(n->blossom_next);
+        } while (n != memo);
+
+        if (G->edgelist[psurf->matched_edge].nod1 == (psurf - G->nodelist))
+            x = PNODE(G->edgelist[psurf->matched_edge].orig_nod1);
+        else
+	    x = PNODE(G->edgelist[psurf->matched_edge].orig_nod2);
+
+        if (lower_edges (G, psurf)) {
+            fprintf (stderr, "lower_edges failed\n");
+            return 1;
+        }
+        fix_matching (G, psurf, PNODE(x->penultimate));
+
+        n = memo;
+        do {
+	    /* Clear tree structure of nodes in psurf's blossom */
+            n->blossom_parent = -1;
+            n->child = -1;
+            n->parent = -1;
+            n->sibling = -1;
+            n->parent_edge = -1;
+            n->label = NIX;
+	    n = PNODE(n->blossom_next);
+            n->hit = n->hit | psurf->hit;
+        } while (n != memo);
+
+        /* clear oldnode */
+
+        psurf->edg_list = -1;
+        psurf->pi = 0;
+        psurf->status = UNMATCHED;
+        psurf->matched_edge = -1;
+        psurf->child = -1;
+        psurf->sibling = -1;
+        psurf->parent = -1;
+        psurf->parent_edge = -1;
+        psurf->label = NIX;
+        psurf->blossom_root = -1;
+        psurf->blossom_next = -1;
+        psurf->blossom_next_edge = -1;
+        psurf->blossom_parent = -1;
+        psurf->penultimate = -1;
+        psurf->tree_root = -1;
+        psurf->hit = 0;
+    
+        /* add psurf to unused list */
+
+        psurf->mark = G->unused;
+        G->unused = psurf - G->nodelist;
+
+        psurf = PNODE(p->penultimate);
+    }
+
+    return 0;
+}
+#endif  /* CARELESS_REPAIRS */
+
+#ifdef BALL_DERIGS_REPAIRS
+#ifdef CC_PROTOTYPE_ANSI
+static int bring_to_surface (graph *G, node *p, stats *scount, srkstuff *srk)
+#else
+static int bring_to_surface (G, p, scount, srk)
+graph *G;
+node *p;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    node *n, *newnode;
+    node *stop = G->nodelist - 1;
+    edge *e, *f;
+    int sum, delta;
+    int found_aug = 0;
+
+    printf ("bring to surface (%d) ...\n", p - G->nodelist);
+    fflush (stdout);
+
+    if (p->blossom_parent == -1) {
+        return 0;
+    }
+
+    /* Take newnode from unused list */
+
+    newnode = PNODE(G->unused);
+    G->unused = newnode->mark;
+    newnode->mark = 0;
+
+    /* Initialize newnode */ 
+
+    sum = 0;
+    for (n = p; n != stop; n = PNODE(n->blossom_parent))
+        sum += n->pi;
+
+    newnode->matched_edge = -1;
+    newnode->status = UNMATCHED;
+    newnode->pi = sum % 2;
+
+    /* Add the edge (newnode, p) */
+
+    if (G->nedges >= G->max_nedges) {
+        fprintf (stderr, "number of edges exceeds max_nedges\n");
+        return 1;
+    }
+    e = PEDGE(G->nedges);
+    e->slack = 0;
+    e->x = 0;
+    e->orig_nod1 = e->nod1 = newnode - G->nodelist;
+    e->orig_nod2 = p - G->nodelist;
+    n = p;
+    while (n->blossom_parent != -1)
+        n = PNODE(n->blossom_parent);
+    e->nod2 = INODE(n); 
+
+    /* Attach the new edge to the edg_lists of newnode and n */
+
+    e->ptrs[0] = n->edg_list;
+    n->edg_list = 2*G->nedges;
+    e->ptrs[1] = -1;
+    newnode->edg_list = 2*G->nedges + 1;
+
+    G->nedges++;
+
+    init_tree (G, newnode);
+    newnode->tree_root = INODE(newnode);
+
+    if (grow_tree (G, newnode, 0, scount, srk, &found_aug)) {
+        fprintf (stderr, "grow_tree failed\n");
+        return 1;
+    }
+    if (found_aug) {
+        fprintf (stderr, "found an augmentation in bring_to_surface\n");
+        return 1;
+    }
+
+    while (p->blossom_parent != -1) {
+        delta = find_single_dual_change (G, newnode);
+        fflush (stdout);
+        if (delta == 0) {
+            printf ("O"); fflush (stdout);
+        }
+        if (apply_dual_change (G, newnode, delta)) {
+	  //            fprintf (stderr, "apply_dual_change failed\n");
+            return 1;
+        }
+        if (grow_tree (G, newnode, 0, scount, srk, &found_aug)) {
+            fprintf (stderr, "grow_tree failed\n");
+            return 1;
+        }
+        if (found_aug) {
+            fprintf (stderr, "found an augmentation in bring_to_surface\n");
+            return 1;
+        }
+    }
+
+    clear_tree (G, newnode);
+
+    /* reset newnode */
+
+    newnode->edg_list = -1;
+    newnode->pi = 0;
+    newnode->status = UNMATCHED;
+    newnode->matched_edge = -1;
+    newnode->child = -1;
+    newnode->sibling = -1;
+    newnode->parent = -1;
+    newnode->parent_edge = -1;
+    newnode->label = NIX;
+    newnode->blossom_root = -1;
+    newnode->blossom_next = -1;
+    newnode->blossom_next_edge = -1;
+    newnode->blossom_parent = -1;
+    newnode->penultimate = -1;
+    newnode->tree_root = -1;
+    newnode->hit = 0;
+
+    /* Delete the added edge */
+
+    f = PEDGE (p->edg_list/2);
+    if (f == e) {
+        p->edg_list = e->ptrs[p->edg_list % 2];
+    } else {
+        int ei, eiprev = p->edg_list;
+
+        for (ei = f->ptrs[p->edg_list % 2]; ei != -1; ei = f->ptrs[ei % 2]) {
+            f = PEDGE(ei/2);
+            if (f == e) {
+                G->edgelist[eiprev/2].ptrs[eiprev % 2] = f->ptrs[ei % 2];
+                break;
+            }
+            eiprev = ei;
+        }
+        if (ei == -1) {
+            fprintf (stderr, "Screw up in bring_to_surface\n");
+            return 1;
+        }
+    }
+    G->nedges--;
+
+    /* Return newnode from unused list */
+
+    newnode->mark = G->unused;
+    G->unused = newnode - G->nodelist;
+
+    return 0;
+}
+#endif  /* BALL_DERIGS_REPAIRS */
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_repair_edge (graph *G, int n1, int n2, int len,
+                            stats *scount, srkstuff *srk)
+#else
+static int add_repair_edge (G, n1, n2, len, scount, srk)
+graph *G;
+int n1, n2, len;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    edge *e, *f = (edge *) NULL;
+    node *n1surf, *n2surf;
+    int ei, eiprev = -1, sum2;
+
+    n1surf = PNODE(n1);
+    n2surf = PNODE(n2);
+    sum2 = n2surf->pi;
+    while (n2surf->blossom_parent != -1) {
+        n2surf = PNODE(n2surf->blossom_parent);
+        sum2 += n2surf->pi;
+    }
+
+    if (G->nedges >= G->max_nedges) {
+        fprintf (stderr, "number of edges exceeds max_nedges\n");
+        return 1;
+    }
+    e = PEDGE(G->nedges);
+    e->slack = len - n1surf->pi - sum2;
+    e->mark = 0;
+    e->x = 0;
+    e->orig_nod1 = n1;
+    e->orig_nod2 = n2;
+    e->nod1 = n1surf - G->nodelist;
+    e->nod2 = n2surf - G->nodelist; 
+
+    for (ei = n1surf->edg_list; ei != -1; ei = f->ptrs[ei % 2]) {
+        f = PEDGE(ei/2);
+        eiprev = ei;
+    }
+    f->ptrs[eiprev % 2] = 2*G->nedges;
+    e->ptrs[0] = -1;
+
+    for (ei = n2surf->edg_list; ei != -1; ei = f->ptrs[ei % 2]) {
+        f = PEDGE(ei/2);
+        eiprev = ei;
+    }
+    f->ptrs[eiprev % 2] = 2*G->nedges + 1;
+    e->ptrs[1] = -1;
+    
+    G->nedges++;
+
+    if (e->slack < 0) {
+        n1surf->pi += e->slack;
+        for (ei = n1surf->edg_list; ei != -1; ei = f->ptrs[ei % 2]) {
+            f = PEDGE(ei/2);
+            f->slack -= e->slack;
+        }
+    }
+
+#ifdef BALL_DERIGS_REPAIRS
+    if (n1surf->matched_edge != -1) {
+        unmatch_edge (G, PEDGE(n1surf->matched_edge)); 
+        if (match_main_more_in_forest (G, scount, srk)) {
+        /* if (match_main_forest (G, scount, srk)) { */
+            fprintf (stderr, "match_main_more_in_forest failed\n");
+            return 1;
+        }
+    }
+#endif
+#ifdef CARELESS_REPAIRS
+    if (n1surf->matched_edge != -1) {
+        /* mark edges to be unmatched later */
+        G->edgelist[n1surf->matched_edge].mark = 1;
+    }
+#endif
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void unmatch_edge (graph *G, edge *e)
+#else
+static void unmatch_edge (G, e)
+graph *G;
+edge *e;
+#endif
+{
+    G->nodelist[e->nod1].status = UNMATCHED;
+    G->nodelist[e->nod2].status = UNMATCHED;
+    e->x = 0;
+    G->nodelist[e->nod1].matched_edge = -1;
+    G->nodelist[e->nod2].matched_edge = -1;
+    G->unmatched_count += 2;
+
+    G->nodelist[e->nod1].mark = G->unmatched;
+    G->nodelist[e->nod2].mark = e->nod1;
+    G->unmatched = e->nod2;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int run_repair (graph *G, int badcount, int *badlist, int *badlen,
+                       stats *scount, srkstuff *srk)
+#else
+static int run_repair (G, badcount, badlist, badlen, scount, srk)
+graph *G;
+int badcount;
+int *badlist;
+int *badlen;
+stats *scount;
+srkstuff *srk;
+#endif
+{
+    int i, sum1, sum2;
+    int n1, n2;
+    node *n;
+    edge *e, *lastedge;
+
+    for (i = 0; i < badcount; i++) {
+#ifdef PRINT_REPAIRS
+        printf ("Bad Edge [%d, %d]\n", badlist[2*i], badlist[2*i + 1]);
+        fflush (stdout);
+#endif
+        sum1 = 0;
+        n = PNODE(badlist[2*i]);
+        while (n->blossom_parent != -1) {
+            n = PNODE(n->blossom_parent);
+            sum1 += n->pi;
+        }
+        sum2 = 0;
+        n = PNODE(badlist[2*i + 1]);
+        while (n->blossom_parent != -1) {
+            n = PNODE(n->blossom_parent);
+            sum2 += n->pi;
+        }
+        if (sum1 < sum2) {
+            n1 = badlist[2*i];
+            n2 = badlist[2*i + 1];
+        } else {
+            n1 = badlist[2*i + 1];
+            n2 = badlist[2*i];
+        }
+        if (bring_to_surface (G, PNODE(n1), scount, srk)){
+            fprintf (stderr, "bring_to_surface failed\n");
+            return 1;
+        }
+        if (add_repair_edge (G, n1, n2, 2 * badlen[i], scount, srk)) {
+            fprintf (stderr, "add_repair_edge failed\n");
+            return 1;
+        }
+        printf ("+"); fflush (stdout);
+    }
+    printf ("\n");
+
+    lastedge = PEDGE(G->nedges);
+    for (e = G->edgelist; e != lastedge; e++) {
+        if (e->mark) {
+            e->mark = 0;
+            if (e->x == 1) {
+                unmatch_edge (G, e);
+            }
+        }
+    }
+
+    if (G->unmatched_count > 0) {
+/*
+        if (match_main_forest (G, scount, srk)) {
+            fprintf (stderr, "match_main_forest failed\n");
+            return 1;
+        }
+*/
+        if (match_main_more_in_forest (G, scount, srk)) {
+            fprintf (stderr, "match_main_more_in_forest failed\n");
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_edges (graph *G, CCdatagroup *dat, int badcount, int *badlist,
+                      int *badlen)
+#else
+static int add_edges (G, dat, badcount, badlist, badlen)
+graph *G;
+CCdatagroup *dat;
+int badcount;
+int *badlist;
+int *badlen;
+#endif
+{
+    int i,j;
+    int ncount = G->nnodes;
+    int ecount = G->nedges;
+    edge *e;
+    edge *edgelist = G->edgelist;
+    node *nodelist = G->nodelist;
+    int maxbad = G->nnodes * MAX_BAD_PORTION;
+
+    /* init unused */
+    j = 3*ncount/2;
+    for (i = ncount; i < j; i++) {
+        nodelist[i].mark = i + 1;
+    }
+    nodelist[j].mark = -1;
+    G->unused = ncount;
+
+    /* Init edg_list */
+    for (i = 0; i < 3*ncount/2; i++) {
+        nodelist[i].edg_list = -1;
+    }
+
+    /* correct old edges */
+    for (i = 0, e = edgelist; i < ecount; i++, e++) {
+	e->nod1 = e->orig_nod1;
+	e->nod2 = e->orig_nod2;
+        e->slack = 2 * CCutil_dat_edgelen (e->nod1, e->nod2, dat); 
+    }
+
+    if (badcount <= maxbad) {
+        for (i = 0; i < badcount; i++) {
+            if (ecount + 1 < G->max_nedges) {
+	        edgelist[ecount].orig_nod1 =
+                                 edgelist[ecount].nod1 = badlist[2*i];
+	        edgelist[ecount].orig_nod2 =
+                                 edgelist[ecount].nod2 = badlist[2*i+1];
+	        edgelist[ecount].slack = 2 * badlen[i];
+	        ecount++;
+	    } else {
+	        fprintf(stderr, "Exceeded limit on the number of edges\n");
+                G->nedges = ecount;
+                return 1;
+	    }
+        }
+    } else {
+        printf ("Using only %.2f of the bad edges\n",
+                      ((double) maxbad) / ((double) badcount));
+        fflush (stdout);
+        for (i = 0; i < badcount; i++) {
+            if (CCutil_lprand () % badcount < maxbad) {
+                if (ecount + 1 < G->max_nedges) {
+	            edgelist[ecount].orig_nod1 =
+                                     edgelist[ecount].nod1 = badlist[2*i];
+	            edgelist[ecount].orig_nod2 =
+                                     edgelist[ecount].nod2 = badlist[2*i+1];
+	            edgelist[ecount].slack = 2 * badlen[i];
+	            ecount++;
+	        } else {
+	            fprintf(stderr, "Exceeded limit on the number of edges\n");
+                    G->nedges = ecount;
+                    return 1;
+                }
+	    }
+        }
+    }
+
+    printf(" Added %i edges ", ecount - G->nedges);
+    fflush (stdout);
+
+    G->nedges = ecount;
+
+    /* build the edg_lists */
+
+    for (i = 0, e = edgelist; i < ecount; i++, e++) {
+        e->ptrs[0] = nodelist[e->nod1].edg_list;
+        nodelist[e->nod1].edg_list = 2*i;
+        e->ptrs[1] = nodelist[e->nod2].edg_list;
+        nodelist[e->nod2].edg_list = 2*i + 1;
+    }
+    for (i = 0; i < ncount; i++) {
+        G->nodelist[i].mark = 0;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int price_repair (graph *G, int *finished, CCdatagroup *dat, stats *scount,
+                         srkstuff *srk, int partialprice) 
+#else
+static int price_repair (G, finished, dat, scount, srk, partialprice) 
+graph *G;
+int *finished;
+CCdatagroup *dat;
+stats *scount;
+srkstuff *srk;
+int partialprice;
+#endif
+{
+    int badcount = 0;
+    int *badlist = (int *) NULL;
+    int *badlen = (int *) NULL;
+    int i;
+    CCtsp_edgegenerator eg;
+    CCtsp_edgegenerator *myeg = (CCtsp_edgegenerator *) NULL;
+
+    *finished = 0;
+
+    if (partialprice > 0) {
+        printf ("Price using the nearest %d neighbor graph\n", partialprice);
+        fflush (stdout);
+        if (CCtsp_init_edgegenerator (&eg, G->nnodes, dat, (CCtsp_genadj *) NULL,
+                                partialprice)) {
+            fprintf (stderr, "init_edgegenerator failed\n");
+            return 1;
+        }
+        myeg = &eg;
+    }
+    
+    if (pricing (G, dat, scount, srk, &badcount, &badlist, &badlen, myeg, 0)) {
+        fprintf (stderr, "pricing failed\n");
+        if (myeg)
+            CCtsp_free_edgegenerator (myeg);
+        return 1;
+    }
+ 
+    while (badcount > 0) {
+        if (badcount > G->nnodes / SWITCH_LEVEL /* 10000 */) {
+            if (myeg)
+                CCtsp_free_edgegenerator (myeg);
+    	    if (add_edges (G, dat, badcount, badlist, badlen)) {
+                fprintf (stderr, "add_edges failed\n");
+                CC_IFFREE (badlist, int);
+                CC_IFFREE (badlen, int);
+                return 1;
+            } else {
+                CC_IFFREE (badlist, int);
+                CC_IFFREE (badlen, int);
+                return 0;
+            }
+        } else {
+            for (i = 0; i < 3 * G->nnodes / 2; i++)
+                G->nodelist[i].hit = 0; 
+            if (run_repair (G, badcount, badlist, badlen, scount, srk)) {
+                fprintf (stderr, "run_repair failed\n");
+                CC_IFFREE (badlist, int);
+                CC_IFFREE (badlen, int);
+                if (myeg)
+                    CCtsp_free_edgegenerator (myeg);
+                return 1;
+            }
+        } 
+        CC_IFFREE (badlist, int);
+        CC_IFFREE (badlen, int);
+
+        if (pricing(G,dat,scount,srk, &badcount, &badlist, &badlen, myeg, 1)) {
+            fprintf (stderr, "pricing failed\n");
+            if (myeg)
+                CCtsp_free_edgegenerator (myeg);
+            return 1;
+        }
+    }
+
+    *finished = 1;
+    if (myeg) 
+        CCtsp_free_edgegenerator (myeg);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int pricing (graph *G, CCdatagroup *dat, stats *scount, srkstuff *srk, 
+                    int *badcount, int **badlist, int **badlen, 
+                    CCtsp_edgegenerator *eg, int usehit) 
+#else
+static int pricing (G, dat, scount, srk, badcount, badlist, badlen, eg, usehit) 
+graph *G;
+CCdatagroup *dat;
+stats *scount;
+srkstuff *srk;
+int *badcount;
+int **badlist, **badlen;
+CCtsp_edgegenerator *eg;
+int usehit;
+#endif
+{
+    int i, k;
+    double szeit, penalty;
+    double *orig_pi = (double *) NULL;
+    int *orig_parent = (int *) NULL;
+    int rval = 0;
+    int ncount = G->nnodes;
+    node *nodelist = G->nodelist;
+    char *hit = (char *) NULL;
+
+    szeit = CCutil_zeit();
+    printf ("Pricing ...\n");
+    fflush (stdout);
+
+    orig_pi = CC_SAFE_MALLOC (ncount*3/2+1, double);
+    orig_parent = CC_SAFE_MALLOC (ncount*3/2+1, int);
+    if (!orig_pi || !orig_parent) {
+        fprintf (stderr, "out of memory in pricing\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    if (usehit) {
+        hit = CC_SAFE_MALLOC (ncount*3/2 + 1, char);
+        if (!hit) {
+            fprintf (stderr, "out of memory in pricing\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    for (i = 0; i < 3*ncount/2; i++) {
+        k = nodelist[i].blossom_parent;
+	orig_parent[i] = k;
+	orig_pi[i] = ((double) nodelist[i].pi) / 2.0;
+        if (hit) {
+            hit[i] = nodelist[i].hit;
+        }
+    }
+
+    if (matching_price (ncount, dat, orig_pi, orig_parent, badcount,
+                        badlist, badlen, &penalty, eg, hit) ) {
+	fprintf (stderr, "matching_price failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    printf("\n%i Edges are wrong in the extra graph, penalty=%.4f\n",
+           *badcount, penalty);
+
+    printf ("    Total time in pricing: %.2f seconds\n", CCutil_zeit () - szeit);
+    fflush(stdout);
+
+CLEANUP:
+
+    CC_IFFREE (orig_pi, double);
+    CC_IFFREE (orig_parent, int);
+    CC_IFFREE (hit, char);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_matching (graph *G, CCdatagroup *dat, int *elen, int fractional,
+                          int *bad) 
+#else
+static int test_matching (G, dat, elen, fractional, bad) 
+graph *G;
+CCdatagroup *dat;
+int *elen;
+int fractional;
+int *bad;
+#endif
+{
+    int i, c, len;
+    double a = 0.0, b = 0.0;
+    edge *e;
+    int ncount = G->nnodes;
+    node *nodelist = G->nodelist;
+
+    *bad = 0;
+
+    if (dat) {
+        if (fractional) {
+            for (i = 0; i < G->nedges; i++) {
+                e = G->edgelist + i;
+                if (e->x == 1) {
+                    a += (double) CCutil_dat_edgelen (e->orig_nod1, e->orig_nod2, dat);
+                    a += (double) CCutil_dat_edgelen (e->orig_nod1, e->orig_nod2, dat);
+                } else if (e->x == HALF) {
+                    a += (double) CCutil_dat_edgelen (e->orig_nod1, e->orig_nod2, dat);
+                }
+	    }
+            for (i = 0; i < ncount; i++)
+	        b += (double) nodelist[i].pi;
+        } else {
+	    for (i = 0; i < ncount; i++) {
+                e = nodelist[i].matched_edge + G->edgelist;
+                a += (double) CCutil_dat_edgelen (e->orig_nod1, e->orig_nod2, dat);
+            }
+	    for (i = 0; i <= 3*ncount/2; i++)
+	        b += (double) nodelist[i].pi;
+        }
+    } else {
+        if (fractional) {
+            for (i = 0; i < ncount; i++) {
+                a += (double) elen[nodelist[i].matched_edge];
+	        b += (double) nodelist[i].pi;
+	    }
+        } else {
+	    for (i = 0; i < ncount; i++) {
+                a += (double) elen[nodelist[i].matched_edge];
+            }
+	    for (i = 0; i <= 3*ncount/2; i++)
+	        b += (double) nodelist[i].pi;
+        }
+    }
+    b /= 2.0;
+    a /= 2.0;
+    printf("     Matching Length: %.1f, Dual %.1f\n", a, b);
+    fflush (stdout);
+
+    if (a != b) {
+        printf ("ERROR: the primal and dual values do not agree\n");
+        fflush (stdout);
+        *bad = 1;
+        return 0;
+    } 
+
+    if (fractional) {
+	for (i = 0, e = G->edgelist; i < G->nedges; i++, e++) {
+            if (dat) {
+                len = 2 * CCutil_dat_edgelen (e->orig_nod1, e->orig_nod2, dat);
+            } else {
+                len = 2 * elen[i];
+            }
+	    if ((c = len - nodelist[e->nod1].pi-nodelist[e->nod2].pi) < 0) {
+		printf("ERROR: Edge %i %i has slack < 0\n", e->nod1, e->nod2);
+                fflush (stdout);
+                *bad = 1;
+                return 0;
+	    }
+	    if (e->x != 0 && c > 0) {
+		printf("ERROR: Edge %i %i has x != 0 and slack > 0\n",
+                     e->nod1, e->nod2);
+                fflush (stdout);
+                *bad = 1;
+                return 0;
+	    }
+	}
+    } else {
+        int *mlist = (int *) NULL;
+        int *mlen = (int *) NULL;
+        double *pi = (double *) NULL;
+        int *parent = (int *) NULL;
+        int csbad, k;
+        int *badlist = (int *) NULL;
+        int *badlen = (int *) NULL;
+        int badcount = 0;
+        double penalty;
+        
+        mlist = CC_SAFE_MALLOC (ncount, int);
+        mlen = CC_SAFE_MALLOC (ncount/2, int);
+        pi = CC_SAFE_MALLOC (ncount*3/2+1, double);
+        parent = CC_SAFE_MALLOC (ncount*3/2+1, int);
+        if (!mlist || !mlen || !pi || !parent) {
+            fprintf (stderr, "out of memory in test_matching\n");
+            CC_IFFREE (mlist, int);
+            CC_IFFREE (mlen, int);
+            CC_IFFREE (pi, double);
+            CC_IFFREE (parent, int);
+            return 1;
+        }
+
+        for (i = 0, e = G->edgelist, k = 0; i < G->nedges; i++, e++) {
+            if (e->x == 1) {
+                mlist[2*k] = e->orig_nod1;
+                mlist[2*k + 1] = e->orig_nod2;
+                if (dat) {
+                    mlen[k] = CCutil_dat_edgelen (e->orig_nod1, e->orig_nod2, dat);
+                } else {
+                    mlen[k] = elen[i];
+                }
+                k++;
+            }
+        }
+        for (i = 0; i < 3*ncount/2; i++) {
+            parent[i] = nodelist[i].blossom_parent;
+            pi[i] = ((double) nodelist[i].pi) / 2.0;
+        }
+
+        if (matching_check (ncount, pi, parent, mlist, mlen, &csbad)) {
+            fprintf (stderr, "matching_check failed\n");
+            CC_FREE (mlist, int);
+            CC_FREE (mlen, int);
+            CC_FREE (pi, double);
+            CC_FREE (parent, int);
+            return 1;
+        }
+
+        if (csbad) {
+            printf ("matching_check found an error\n");
+            fflush (stdout);
+            *bad = 1;
+            CC_FREE (mlist, int);
+            CC_FREE (mlen, int);
+            CC_FREE (pi, double);
+            CC_FREE (parent, int);
+            return 0;
+        }
+
+        if (matching_price (ncount, dat, pi, parent, &badcount,
+               &badlist, &badlen, &penalty, (CCtsp_edgegenerator *) NULL,
+               (char *) NULL)) {
+	    fprintf (stderr, "matching_price failed\n");
+            CC_FREE (mlist, int);
+            CC_FREE (mlen, int);
+            CC_FREE (pi, double);
+            CC_FREE (parent, int);
+            return 1;
+        }
+
+        if (badcount) {
+            printf ("pricing on complete graph found %d bad edges\n", badcount);
+            fflush (stdout);
+            *bad = 1;
+            CC_IFFREE (badlist, int);
+            CC_IFFREE (badlen, int);
+            CC_FREE (mlist, int);
+            CC_FREE (mlen, int);
+            CC_FREE (pi, double);
+            CC_FREE (parent, int);
+            return 0;
+        }
+
+        CC_FREE (mlist, int);
+        CC_FREE (mlen, int);
+        CC_FREE (pi, double);
+        CC_FREE (parent, int);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dual_match_len (graph *G, int fractional, double *val) 
+#else
+static void dual_match_len (G, fractional, val) 
+graph *G;
+int fractional;
+double *val;
+#endif
+{
+    int i;
+    double b = 0.0;
+    int ncount = G->nnodes;
+    node *nodelist = G->nodelist;
+
+    if (fractional) {
+	for (i = 0; i < ncount; i++) {
+	    b += (double) nodelist[i].pi;
+	}
+    } else {
+	for (i = 0; i <= 3*ncount/2; i++)
+	    b += (double) nodelist[i].pi;
+    }
+    *val = b / 2.0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int make_match (graph *G) 
+#else
+static int make_match (G) 
+graph *G;
+#endif
+{
+    int i, i2, j, k, start, counter=0;
+    int ncount = G->nnodes;
+    edge *e;
+    node *nodelist = G->nodelist;
+    edge *edgelist = G->edgelist;
+
+    for (i = 0; i < ncount; i++) {
+	if (nodelist[i].status == MATCHED)
+	    counter++;
+	if (nodelist[i].status == HALVES) {
+	    k = 1;
+	    start = i;
+	    i2 = i;
+            j = OTHEREND_INT (PEDGE(nodelist[i2].matched_edge), i2);
+	    do {
+                e = PEDGE(nodelist[j].matched_edge);
+		if (k % 2) {
+		    nodelist[i2].status = MATCHED;
+		    nodelist[j].status = MATCHED;
+		    edgelist[nodelist[j].matched_edge].x = 0;
+		    nodelist[j].matched_edge = nodelist[i2].matched_edge;
+		    edgelist[nodelist[j].matched_edge].x = 1;
+		}
+		i2 = j;
+                j = OTHEREND_INT (e, i2);
+		k++;
+	    } while (j!=start);
+	    nodelist[i2].status = UNMATCHED;
+	    edgelist[nodelist[i2].matched_edge].x = 0;
+	    nodelist[i2].matched_edge = -1;
+	    counter++;
+	}
+	nodelist[i].label = NIX;
+	nodelist[i].child = -1;
+	nodelist[i].sibling = -1;
+	nodelist[i].parent = -1;
+	nodelist[i].parent_edge = -1;
+	nodelist[i].mark = 0;
+	nodelist[i].tree_root = -1;
+    }
+
+    counter=0;
+    for (i = 0; i < ncount; i++)
+	if (nodelist[i].status == MATCHED)
+	    counter++;
+    //    printf(" %i nodes are matched now !\n",counter);
+
+    /* build list of unmatched nodes */
+
+    G->unmatched_count = 0;
+    for (i = 0; i < ncount; i++) {
+	if (nodelist[i].status == UNMATCHED) {
+	    G->unmatched_count++;
+	}
+    }
+
+    j = -1;
+    for (i = 0; i < ncount; i++) {
+	if (nodelist[i].status == UNMATCHED) {
+            if (j != -1) 
+                nodelist[j].mark = i;
+            j = i;
+	}
+    }
+    if (j != -1)
+        nodelist[j].mark = -1;
+
+
+    if (G->unmatched_count == 0) {
+        G->unmatched = -1;
+    } else {
+        for (i = 0; nodelist[i].status != UNMATCHED; i++);
+        G->unmatched = i;
+    }
+    //    printf(" unmatched_count = %i\n", G->unmatched_count);
+    //    fflush (stdout);
+
+    /* hit is used to identify the blossoms that receive a label +  during */
+    /* the matching run; this will help the pricing code                   */
+
+    for (i = 0; i < 3 * ncount / 2; i++)  
+        nodelist[i].hit = 0;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int build_graph (graph *G, int ncount, int ecount, int *elist, int *elen)
+#else
+static int build_graph (G, ncount, ecount, elist, elen)
+graph *G;
+int ncount, ecount;
+int *elist, *elen;
+#endif
+{
+    int i, j;
+    edge *e;
+
+    if (ncount % 2 != 0) {
+        fprintf (stderr, "problem has an odd number of nodes\n");
+        return 1;
+    }
+
+    G->nnodes = ncount;
+    G->nodelist = CC_SAFE_MALLOC ((3*ncount/2+1), node);
+    if (!G->nodelist) {
+        fprintf (stderr, "out of memory in build_graph\n");
+        return 1;
+    }
+    for (i = 0; i < 3*ncount/2 + 1; i++) {
+        G->nodelist[i].blossom_parent = -1;
+        G->nodelist[i].matched_edge = -1;
+        G->nodelist[i].edg_list = -1;
+    }
+
+    /* init unused */
+
+    j = 3*ncount/2;
+    for (i = ncount; i < j; i++) {
+        G->nodelist[i].mark = i + 1;
+    }
+    G->nodelist[j].mark = -1;
+    G->unused = ncount;
+
+    G->nedges = ecount;
+    G->max_nedges = ecount + (1.5 * ncount);
+
+    G->edgelist = CC_SAFE_MALLOC (G->max_nedges, edge);
+    if (!G->edgelist) {
+        fprintf (stderr, "out of memory in build_graph\n");
+        CC_FREE (G->nodelist, node);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        G->nodelist[i].mark = 0;
+    }
+
+    for (i = 0, e = G->edgelist; i < ecount; i++, e++) {
+	e->nod1 = elist[2*i];
+	e->nod2 = elist[2*i+1];
+	e->orig_nod1 = e->nod1;
+	e->orig_nod2 = e->nod2;
+	e->slack =  2 * elen[i];  /* to work with ints */
+        e->mark = 0;
+        e->ptrs[0] = G->nodelist[e->nod1].edg_list;
+        G->nodelist[e->nod1].edg_list = 2*i;
+        e->ptrs[1] = G->nodelist[e->nod2].edg_list;
+        G->nodelist[e->nod2].edg_list = 2*i + 1;
+    }
+    for (; i < G->max_nedges; i++)
+        G->edgelist[i].mark = 0;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int write_match (graph *G, CCdatagroup *dat, int *elen, char* fname, int *outp) 
+#else
+  static int write_match (G, dat, elen, fname, outp) 
+graph *G;
+CCdatagroup *dat;
+int *elen;
+char *fname;
+int *outp;
+#endif
+{
+    int i, c, len = 0;
+    edge *e;
+    FILE* fp;
+
+    double szeit;
+
+    szeit = CCutil_zeit();
+    //    printf(" Writing %s ...", fname);
+    //    fflush(stdout);
+
+    //    if ((fp = fopen (fname, "w")) ==  (FILE *) NULL) {
+    //	fprintf(stderr," Error: Can't open file %s\n",fname);
+    //        return 1;
+    //    }
+
+    c = 0;
+    for (i = 0; i < G->nnodes; i++) {
+	if (i == G->edgelist[G->nodelist[i].matched_edge].orig_nod2 ||
+                 G->edgelist[G->nodelist[i].matched_edge].x == HALF) {
+	    c++;
+        }
+    }
+    //    printf(" %i nodes, %i edges ", G->nnodes, c);
+    //    fprintf (fp, "%i %i\n", G->nnodes, c);
+    outp[0] = c;
+    int KOUNT=0;
+    for (i = 0; i < G->nnodes; i++) {
+        e = PEDGE(G->nodelist[i].matched_edge);
+	if (i == e->orig_nod2 || e->x == HALF) {
+            if (dat)
+                len = CCutil_dat_edgelen (e->orig_nod1, e->orig_nod2, dat);
+            else
+                len = elen[e - G->edgelist];
+	    outp[1+3*KOUNT] = G->edgelist[G->nodelist[i].matched_edge].orig_nod1;
+	    outp[1+3*KOUNT+1] = G->edgelist[G->nodelist[i].matched_edge].orig_nod2;
+	    outp[1+3*KOUNT+2] = len;
+	    KOUNT++;
+	    //	    fprintf (fp,"%i %i %i\n",
+	    //                     G->edgelist[G->nodelist[i].matched_edge].orig_nod1,
+	    //                     G->edgelist[G->nodelist[i].matched_edge].orig_nod2, len);
+        }
+    }
+    //    fclose(fp);
+
+    //    printf(" ... in %.2f sec !! \n", CCutil_zeit () - szeit);
+    //    fflush(stdout);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int write_blossom_tree (graph *G, char* blossom_tree_file) 
+#else
+static int write_blossom_tree (G, blossom_tree_file) 
+graph *G;
+char *blossom_tree_file;
+#endif
+{
+    int i,j;
+    FILE *fp;
+    double szeit;
+    double t;
+
+    szeit = CCutil_zeit();
+    printf(" Writing %s ...",blossom_tree_file);
+    fflush(stdout);
+
+    if ((fp = fopen (blossom_tree_file, "w")) ==  (FILE *) NULL) {
+	fprintf(stderr," cannot open file %s\n",blossom_tree_file);
+        return 1;
+    }
+
+    for (i = 0; i < 3*G->nnodes/2; i++) {
+	j = G->nodelist[i].blossom_parent;
+        t = ((double) G->nodelist[i].pi) / 2.0;
+	fwrite (&j, sizeof(int), 1, fp);
+	fwrite (&t, sizeof(double), 1, fp);
+    }
+    fclose(fp);
+
+    printf(" ... in %.2f sec !! \n", CCutil_zeit () - szeit);
+    fflush(stdout);
+
+    return 0;
+}
diff --git a/contrib/blossom/MATCH/match.h b/contrib/blossom/MATCH/match.h
new file mode 100644
index 0000000000000000000000000000000000000000..f18f6cf0c4cbd1ec2aa6ab80722af6685cd294ad
--- /dev/null
+++ b/contrib/blossom/MATCH/match.h
@@ -0,0 +1,28 @@
+#ifndef  __MATCH_H
+#define  __MATCH_H
+
+#include "concorde.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    perfect_match (int ncount, CCdatagroup *dat, int ecount, int **elist,
+            int **elen, char *blo_filename, char *mat_filename,
+            int just_fractional, int no_fractional, int use_all_trees,
+            int partialprice, double *totalzeit),
+    matching_price (int ncount, CCdatagroup *dat, double *orig_pi,
+            int *orig_parent, int *badcount, int **badlist, int **badlen,
+            double *penalty, CCtsp_edgegenerator *starteg, char *hit),
+    matching_check (int ncount, double *orig_pi, int *orig_parent, 
+            int *matchlist, int *mlen, int *csbad);
+
+#else
+
+int
+    perfect_match (),
+    matching_price (),
+    matching_check ();
+
+#endif
+
+#endif  /* __MATCH_H */
diff --git a/contrib/blossom/MATCH/matprice.c b/contrib/blossom/MATCH/matprice.c
new file mode 100644
index 0000000000000000000000000000000000000000..338541933abca768aaf8504af87cc45640aeb61b
--- /dev/null
+++ b/contrib/blossom/MATCH/matprice.c
@@ -0,0 +1,1443 @@
+/************************************************************************/
+/*                                                                      */
+/*         PRICING ROUTINE FOR WEIGHTED PERFECT MATCHING PROBLEMS       */
+/*                                                                      */
+/*  Written by:  D. Applegate, W. Cook, and A. Rohe                     */
+/*  Date:  August 1, 1996                                               */
+/*                                                                      */
+/*                                                                      */
+/* EXPORTED FUNCTION:                                                   */
+/*   int matching_price (int ncount, CCdatagroup *dat,                  */
+/*          double *orig_pi, int *orig_parent, int *badcount,           */
+/*          int **badlist, int **badlen, double *penalty,               */
+/*          edgegenerator *starteg, char *hit)                          */
+/*     RETURNS the edges of negative reduced cost.                      */
+/*         -ncount is the number of nodes in the graph                  */
+/*         -dat is a pointer to the data used to generate edge lengths  */
+/*         -orig_pi is an array giving the dual variables on the nodes  */
+/*            and blossoms (the first ncount entries are the nodes)     */
+/*         -orig_parent is an array giving the parents of the nodes and */
+/*            and blossoms in the nesting structure created by the      */
+/*            matching algorithm (the entry is -1 if there is no parent)*/
+/*         -badcount will return the number of edges having negative    */
+/*            reduced cost                                              */
+/*         -badlist will return the negative edges in node node format  */
+/*            (the space for badlist will be allocated by this routine) */
+/*         -badlen will return the lengths of the negative edges        */
+/*         -penalty will return the sum of the negative reduced costs   */
+/*            cutcount)                                                 */
+/*         -starteg is a pointer to an edgegenerator that has been      */
+/*            initialized (this can be NULL, in which cas the pricing   */
+/*            is over the complete graph)                               */
+/*         -hit is array (of length 3*ncount/2) that marks the nodes    */
+/*            that have been hit by a positive dual change during the   */
+/*            course of the algorithm (it can be NULL)                  */
+/*   int matching_check (int ncount, CCdatagroup *dat, int *matchlist,  */
+/*          int *mlen, int *orig_parent, int *csbad)                    */
+/*     CHECKS that the complementary slackness conditions hold.         */
+/*         -variables are as above.                                     */
+/*         -matchlist is an array of length ncount giving the edges     */
+/*            in a perfect matching in end end format                   */
+/*         -mlen is an array of lenght ncount/2 giving the lengths of   */
+/*            the edges in the matching                                 */
+/*         -csbad will return 1 if complementary slackness conditions   */
+/*            are violated and 0 otherwise)                             */
+/*                                                                      */
+/*  NOTES:                                                              */
+/*                                                                      */
+/*    Returns 0 if it worked and 1 otherwise (for example, when one     */
+/*    of the mallocs failed). The nodes in the graph should be named    */
+/*    0 through #nodes - 1.                                             */
+/*                                                                      */
+/*    The arrays orig_pi and orig_parent are 3/2 ncount long (this      */
+/*    is the maximum number of nodes + blossoms used in the blossom     */
+/*    algorithms. Some of the entries will be wasted space. The real    */
+/*    entries can be determined by following the parent pointers from   */
+/*    the ncount nodes (the first ncount entries in the arrays).        */
+/*                                                                      */
+/*    If matchlist is not NULL, then the complementary slackness        */
+/*    conditions will be checked for the matching and dual solution.    */
+/*                                                                      */
+/************************************************************************/
+
+#include "concorde.h"
+#include "match.h"
+
+#define MAT_GEN_EPSILON  0.000001
+#define MAT_GEN_INFINITY 1000000000000.0
+
+typedef struct node {
+    struct node       *parent;
+    struct node       *child;
+    struct node       *sibling;
+    struct anc        *addset;
+    struct anc        *evallist;
+    double             pi;
+    double             sum;
+    int                prenum;
+    int                mark;
+    char               hit;
+} node;
+
+typedef struct anc {
+    struct anc        *parent;
+    struct anc        *next;
+    struct node       *ancestor;
+    struct node       *lca;
+    int                rank;
+} anc;
+
+typedef struct tree {
+    struct node       *nodelist;
+    struct node       *root;
+    int                ncount;
+    int                realncount;
+} tree;
+
+typedef struct junk_param {
+    struct tree       *T;
+    struct node       *nodelist;
+    CCdatagroup       *dat;
+    int               *list;
+    int               *len;
+    int               *badlist;
+    int               *badlen;
+    int               *mark;
+    double             penalty;
+    int                nwant;
+    int                ngot;  
+    int                total;
+    int                badcount;
+    int                phase;
+} junk_param;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    number_tree (node *n, int *prenum, int depth, int *maxdepth),
+    freetree (tree *T);
+static char
+    get_hit_work (node *n);
+static int
+    cs_matching (tree *T, int *mlist, int *mlen, int *bad),
+    check_card (node *b, int *not_odd),
+    match_kdtree_price (tree *T, CCdatagroup *dat, int *badcount,
+       int **badlist, int **badlen, double *penalty),
+    merge_edge_lists (int *totalcount, int **totallist, int **totallen,
+       int ecount, int *elist, int *elen),
+    buildtree (tree *T, int ncount, double *pi, int *parent, char *hit),
+    junk_check (int n1, int n2, void *pass_param),
+    ancestor_price (tree *T, int zero_rc, int ecount, int *elist,
+       int *elen, int *badcount, int **badlist, int **badlen, double *penalty);
+static double
+    get_sum_work (node *n);
+static anc
+   *ancest_work (node *p),
+   *find_anc (anc *x),
+   *union_anc (anc *x, anc *y);
+
+#else
+
+static void
+    number_tree (),
+    freetree ();
+static char
+    get_hit_work (node *n);
+static int
+    cs_matching (),
+    check_card (),
+    match_kdtree_price (),
+    merge_edge_lists (),
+    buildtree (),
+    junk_check (),
+    ancestor_price ();
+static double
+    get_sum_work ();
+static anc
+   *ancest_work (),
+   *find_anc (),
+   *union_anc ();
+
+#endif
+
+
+#ifdef DEBUG_MATPRICE
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    price_list (tree *T, int ecount, int *elist, int *elen, int *nbad);
+static double
+    price_it (tree *T, int n1, int n2, int len);
+static node
+   *easy_lca (node *n1, node *n2);
+
+#else
+
+static void
+    price_list ();
+static double
+    price_it ();
+static node
+   *easy_lca ();
+
+#endif
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int matching_price (int ncount, CCdatagroup *dat, double *orig_pi,
+                    int *orig_parent, int *badcount, int **badlist,
+                    int **badlen, double *penalty, CCtsp_edgegenerator *starteg,
+                    char *hit)
+#else
+int matching_price (ncount, dat, orig_pi, orig_parent,
+                    badcount, badlist, badlen, penalty, starteg, hit)
+int ncount;
+CCdatagroup *dat;
+double *orig_pi;
+int *orig_parent;
+int *badcount;
+int **badlen, **badlist;
+double *penalty;
+CCtsp_edgegenerator *starteg;
+char *hit;
+#endif
+{
+    tree T;
+    CCtsp_edgegenerator eg;
+    CCtsp_edgegenerator *myeg = (CCtsp_edgegenerator *) NULL;
+    double *sums = (double *) NULL;
+    int i;
+    int ngot, finished;
+    int *plist = (int *) NULL;
+    int *plen = (int *) NULL;
+    int nwant;
+    int rval = 0;
+    int rcount;
+    int *rlist = (int *) NULL;
+    int *rlen = (int *) NULL;
+    double rpenalty = 0.0;
+    int tcount = 0;
+    int *tlist = (int *) NULL;
+    int *tlen = (int *) NULL;
+    int totalpot = 0;
+
+
+    //    printf ("matching_price ....\n");fflush (stdout);
+    *badcount = 0;
+    *badlist = (int *) NULL;
+    *badlen = (int *) NULL;
+    *penalty = 0.0;
+
+    if (buildtree (&T, ncount, orig_pi, orig_parent, hit)) {
+      //        fprintf (stderr, "buildtree failed\n");
+        return 1;
+    }
+
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE && !starteg) {
+      //        printf ("Use kd-tree pricing ....\n");
+        fflush (stdout);
+
+        if (match_kdtree_price (&T, dat, badcount, badlist, badlen, penalty)) {
+	  //            fprintf (stderr, "match_kdtree_price failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    } else {
+      //        printf ("Use general pricing ...\n");
+        fflush (stdout);
+
+        if (!starteg) {
+            if (CCtsp_init_edgegenerator (&eg, ncount, dat, (CCtsp_genadj *) NULL,
+                                CCtsp_PRICE_COMPLETE_GRAPH)) {
+	      //                fprintf (stderr, "CCtsp_init_edgegenerator failed\n");
+                freetree (&T);
+                return 1;
+            }
+            myeg = &eg;
+        } else {
+            myeg = starteg;
+        }
+
+        sums = CC_SAFE_MALLOC (ncount, double);
+        if (!sums) {
+	  //            fprintf (stderr, "out of memory in matching_price\n");
+            rval = 1;
+            CCtsp_free_edgegenerator (&eg);
+            goto CLEANUP;
+        }
+    
+        for (i = 0; i < ncount; i++) {
+            sums[i] = T.nodelist[i].sum;
+        }
+
+        if (CCtsp_reset_edgegenerator (myeg, sums)) {
+	  //            fprintf (stderr, "CCtsp_reset_edgegenerator failed\n");
+            rval = 1;
+            if (!starteg)
+                CCtsp_free_edgegenerator (&eg);
+            goto CLEANUP;
+        }
+
+        nwant = 3 * ncount;
+
+        plist = CC_SAFE_MALLOC (nwant * 2, int);
+        plen = CC_SAFE_MALLOC (nwant, int);
+        if (!plist || !plen) {
+	  //            fprintf (stderr, "out of memory in matching_price\n");
+            rval = 1;
+            if (!starteg)
+                CCtsp_free_edgegenerator (&eg);
+            goto CLEANUP;
+        }
+
+        do {
+            ngot = 0;
+            finished = 0;
+            if (CCtsp_generate_edges (myeg, nwant, &ngot, plist, plen, &finished)) {
+	      //                fprintf (stderr, "generate_edges failed\n");
+                rval = 1;
+                if (!starteg)
+                    CCtsp_free_edgegenerator (&eg);
+                CC_IFFREE (tlist, int);
+                CC_IFFREE (tlen, int);
+                goto CLEANUP;
+            }
+        
+	    //            printf ("Found %d potential edges\n", ngot);
+	    //            printf ("Finished = %d\n", finished);
+            fflush (stdout);
+            totalpot += ngot;
+
+            if (ancestor_price (&T, 0, ngot, plist, plen, &rcount, &rlist,
+                                &rlen, &rpenalty)) {
+	      //                fprintf (stderr, "ancestor_price failed\n");
+                rval = 1;
+                CC_IFFREE (tlist, int);
+                CC_IFFREE (tlen, int);
+                if (!starteg)
+                    CCtsp_free_edgegenerator (&eg);
+                goto CLEANUP;
+            }
+       
+            if (rcount) {
+                *badcount += rcount;
+                *penalty += rpenalty;
+
+                if (merge_edge_lists (&tcount, &tlist, &tlen,
+                                       rcount,  rlist,  rlen)) {
+		  //                    fprintf (stderr, "merge_edge_lists failed\n");
+                    rval = 1;
+                    CC_IFFREE (tlist, int);
+                    CC_IFFREE (tlen, int);
+                    if (!starteg)
+                        CCtsp_free_edgegenerator (&eg);
+                    goto CLEANUP;
+                }
+
+                CC_IFFREE (rlist, int);
+                CC_IFFREE (rlen, int);
+            }
+        } while (!finished);
+
+	//        printf ("Total potential edges: %d\n", totalpot);
+        fflush (stdout);
+
+        if (badcount) {
+            *badlist = tlist;
+            *badlen = tlen;
+        }
+
+        if (!starteg)
+            CCtsp_free_edgegenerator (&eg);
+    }
+
+CLEANUP:
+
+    CC_IFFREE (plist, int);
+    CC_IFFREE (plen, int);
+    CC_IFFREE (rlist, int);
+    CC_IFFREE (rlen, int);
+    CC_IFFREE (sums, double);
+    freetree (&T);
+
+    return rval;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int matching_check (int ncount, double *orig_pi, int *orig_parent,
+                    int *matchlist, int *mlen, int *csbad)
+#else
+int matching_check (ncount, orig_pi, orig_parent, matchlist, mlen, csbad)
+int ncount;
+double *orig_pi;
+int *orig_parent;
+int *matchlist;
+int *mlen;
+int *csbad;
+#endif
+{
+    tree T;
+    double szeit = CCutil_zeit ();
+
+    *csbad = 0;
+    if (buildtree (&T, ncount, orig_pi, orig_parent, (char *) NULL)) {
+        fprintf (stderr, "buildtree failed\n");
+        return 1;
+    }
+
+    printf ("Check complementary slackness conditions ....\n");
+    fflush (stdout);
+    if (cs_matching (&T, matchlist, mlen, csbad)) {
+        fprintf (stderr, "cs_matching failed\n");
+        freetree (&T);
+        return 1;
+    }
+    if (*csbad) {
+        printf ("\nWARNING: complementary slackness NOT satisfied\n\n");
+        fflush (stdout);
+    } else {
+        printf ("Complementary slackness satisfied (%.2f seconds)\n\n", 
+                CCutil_zeit () - szeit);
+        fflush (stdout);
+    }
+
+    freetree (&T);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cs_matching (tree *T, int *mlist, int *mlen, int *bad)
+#else
+static int cs_matching (T, mlist, mlen, bad)
+tree *T;
+int *mlist, *mlen;
+int *bad;
+#endif
+{
+    int ncount = T->realncount;
+    node *nodelist = T->nodelist;
+    int i, k, not_odd = 0;
+    int bcount = 0;
+    int *blist = (int *) NULL;
+    int *blen = (int *) NULL;
+    char *mark = (char *) NULL;
+    double t, penalty = 0.0;
+    node *b, *n, *n1, *n2;
+    int local_magic = 0;
+
+    *bad = 0;
+
+    mark = CC_SAFE_MALLOC (ncount, char);
+    if (!mark) {
+        fprintf (stderr, "out of memory in cs_matching\n");
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        mark[i] = 0;
+    for (i = 0; i < ncount; i++) {
+        if (mark[mlist[i]]) {
+            printf ("node %d meets two edges in matching\n", mlist[i]);
+            fflush (stdout);
+            *bad = 1;
+            goto CLEANUP;
+        } else {
+            mark[mlist[i]] = 1;
+        }
+    }
+    printf ("All nodes meet exactly one matching edge\n");
+    fflush (stdout);
+
+    t = 0.0;
+    for (i = 0; i < ncount/2; i++) {
+        t += (double) mlen[i];
+    }
+    printf ("Length of matching: %.2f\n", t);
+    fflush (stdout);
+
+    if (ancestor_price (T, 1, ncount / 2, mlist, mlen, &bcount, &blist,
+                        &blen,  &penalty)) {
+        fprintf (stderr, "ancestor_price failed\n");
+        return 1;
+    }
+    CC_IFFREE (blist, int);
+    CC_IFFREE (blen, int);
+
+    if (bcount > 0) {
+        printf ("%d matching edges at nonzero reduced cost (%f sum)\n",
+                   bcount, penalty);
+        fflush (stdout);
+        *bad = 1;
+        goto CLEANUP;
+    } else {
+        printf ("All matching edges have zero reduced cost\n");
+        fflush (stdout);
+    }
+
+    for (b = T->root->child; b; b = b->sibling) 
+        check_card (b, &not_odd);
+    if (not_odd) {
+        printf ("%d blossoms do not have odd cardinality\n", not_odd);
+        fflush (stdout);
+        *bad = 1;
+        goto CLEANUP;
+    } else {
+        printf ("All blossoms have odd cardinality\n");
+        fflush (stdout);
+    }
+
+    for (i = 0; i < T->ncount; i++) {
+        nodelist[i].mark = 0;
+        nodelist[i].prenum = 0;
+    }
+    for (i = 0; i < ncount/2; i++) {
+        n1 = nodelist + mlist[2*i];
+        n2 = nodelist + mlist[2*i+1];
+        local_magic++;
+
+        n = n1;
+        do {
+            n->mark = local_magic;
+            n = n->parent;
+        } while (n);
+
+        do {
+            n2->prenum++;
+            n2 = n2->parent;
+        } while (n2->mark != local_magic);
+
+        do {
+            n1->prenum++;
+            n1 = n1->parent;
+        } while (n1 != n2);
+    }
+    for (i = 0; i < T->ncount; i++) 
+        nodelist[i].mark = 0;
+
+    k = 0;
+    for (i = T->realncount; i < T->ncount; i++) {
+        if (nodelist[i].prenum != 1 && nodelist + i != T->root)
+            k++;
+    }
+    if (k) {
+        printf ("%d blossoms do not contain exactly one matching edge\n", k);
+        fflush (stdout);
+        *bad = 1;
+        goto CLEANUP;
+    } else {
+        printf ("All blossoms meet exactly one matching edge\n");
+        fflush (stdout);
+    }
+
+
+
+CLEANUP:
+
+    CC_IFFREE (mark, char);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_card (node *b, int *not_odd)
+#else
+static int check_card (b, not_odd)
+node *b;
+int *not_odd;
+#endif
+{
+    if (b->child) {
+        int card = 0;
+        node *c;
+   
+        for (c = b->child; c; c = c->sibling) {
+            card += check_card (c, not_odd);
+        }
+        if (card % 2 == 0) 
+            (*not_odd)++;
+        return card;
+    } else {
+        return 1;
+    }
+}
+
+
+#define PULLIT     20
+
+#ifdef CC_PROTOTYPE_ANSI
+static int match_kdtree_price (tree *T, CCdatagroup *dat, int *badcount,
+            int **badlist, int **badlen, double *penalty)
+#else
+static int match_kdtree_price (T, dat, badcount, badlist, badlen, penalty)
+tree *T;
+CCdatagroup *dat;
+int *badcount;
+int **badlist, **badlen;
+double *penalty;
+#endif
+{
+    double smax = - MAT_GEN_INFINITY;
+    int i, j;
+    node *nodelist = T->nodelist;
+    int ncount = T->realncount;
+    double *wcoord = (double *) NULL;
+    double szeit = CCutil_zeit ();
+    double dist;
+    CCkdtree kt;
+    junk_param p;
+    int *list = (int *) NULL;
+    int *len = (int *) NULL;
+    int *perm = (int *) NULL;
+    int newtop, newbottom;
+    int rval = 0;
+
+    {
+        double mins = nodelist[0].sum;
+        double maxs = nodelist[0].sum;
+        double *sum = (double *) NULL;
+
+        sum = CC_SAFE_MALLOC (ncount, double);
+        perm = CC_SAFE_MALLOC (ncount, int);
+        if (!sum || !perm) {
+            fprintf (stderr, "out of memory in match_kdtree_price\n");
+            CC_IFFREE (sum, double);
+            rval = 1;
+            goto CLEANUP;
+        }
+        for (i = 0; i < ncount; i++) {
+            sum[i] = nodelist[i].sum;
+            perm[i] = i;
+        }
+
+        for (i = 0; i < ncount; i++) {
+            if (sum[i] > maxs)
+                maxs = sum[i];
+            if (sum[i] < mins)
+                mins = sum[i];
+        }
+        printf ("Spread: (%f, %f)\n", mins, maxs);
+        fflush (stdout);
+
+        CCutil_double_perm_quicksort (perm, sum, ncount);
+
+        newtop = ncount - ncount/PULLIT;
+        newbottom = ncount/PULLIT;
+
+        printf ("Remove %d nodes to get spead of (%f, %f)\n",
+          2 * (ncount / PULLIT), sum[perm[newbottom]], sum[perm[newtop - 1]]);
+        fflush (stdout);
+
+        CC_IFFREE (sum, double);
+    }
+
+    *badcount = 0;
+    *badlist = (int *) NULL;
+    *badlen = (int *) NULL;
+    *penalty = 0.0;
+
+    p.T = T;
+    p.dat = dat;
+    p.nodelist = nodelist;
+    p.nwant = 3 * ncount;
+    p.ngot = 0;
+    p.total = 0;
+    p.penalty = 0.0;
+
+    list = CC_SAFE_MALLOC (2 * p.nwant, int);
+    len = CC_SAFE_MALLOC (p.nwant, int);
+    p.mark = CC_SAFE_MALLOC (ncount, int);
+
+    if (!list || !len || !p.mark) {
+        fprintf (stderr, "out of memory in match_kdtree_price\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    p.list = list;
+    p.len = len;
+    p.badcount = 0;
+    p.badlist = (int *) NULL;
+    p.badlen = (int *) NULL;
+
+    for (i = 0; i < ncount; i++)
+        p.mark[i] = 0;
+
+    wcoord = CC_SAFE_MALLOC (ncount, double);
+    if (!wcoord) {
+        fprintf (stderr, "out of memory in match_kdtree_price\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++)
+        wcoord[i] = 0.0;
+    for (j = newbottom; j < newtop; j++) {
+        i = perm[j];
+        if (nodelist[i].sum > smax)
+            smax = nodelist[i].sum; 
+    }
+    for (j = newbottom; j < newtop; j++) {
+        i = perm[j];
+        wcoord[i] = smax - nodelist[i].sum;
+    }
+
+    dist = 2 * smax - MAT_GEN_EPSILON; 
+
+    printf ("Build the kdtree ...\n"); fflush (stdout);
+
+    if (CCkdtree_build (&kt, ncount, dat, wcoord)) {
+        fprintf (stderr, "CCkdtree_build failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    p.phase = 0;
+    for (i = 0; i < newbottom; i++)
+        CCkdtree_delete (&kt, perm[i]);
+    for (i = ncount - 1; i >= newtop; i--)
+        CCkdtree_delete (&kt, perm[i]);
+    for (j = newbottom; j < newtop; j++) {
+        i = perm[j];
+        if (nodelist[i].hit) {
+            if (CCkdtree_fixed_radius_nearest (&kt, dat, wcoord, i, dist, 
+                             junk_check, (void *) (&p))) {
+                fprintf (stderr, "CCkdtree_fixed_radius_nearest failed\n");
+                CCkdtree_free (&kt);
+                CC_IFFREE (p.badlist, int);
+                CC_IFFREE (p.badlen, int);
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (j % 100000 == 99999) {
+            printf ("Processed %d nodes\n", j + 1);
+            fflush (stdout);
+        }
+    }
+    CCkdtree_free (&kt);
+
+    printf ("Processing the deleted nodes ....\n");
+    fflush (stdout);
+
+    smax = - MAT_GEN_INFINITY;
+    for (i = 0; i < ncount; i++) {
+        if (nodelist[i].sum > smax)
+            smax = nodelist[i].sum; 
+    }
+    for (i = 0; i < ncount; i++) {
+        wcoord[i] = smax - nodelist[i].sum;
+    }
+
+    dist = 2 * smax - MAT_GEN_EPSILON; 
+
+    if (CCkdtree_build (&kt, ncount, dat, wcoord)) {
+        fprintf (stderr, "CCkdtree_build failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < newbottom; i++)
+        p.mark[perm[i]] = 1;
+    p.phase = 1;
+
+    for (j = 0;  j < newbottom; j++) {
+        i = perm[j];
+        if (CCkdtree_fixed_radius_nearest (&kt, dat, wcoord, i, dist, 
+                         junk_check, (void *) (&p))) {
+            fprintf (stderr, "CCkdtree_fixed_radius_nearest failed\n");
+            CCkdtree_free (&kt);
+            CC_IFFREE (p.badlist, int);
+            CC_IFFREE (p.badlen, int);
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (j % 1000 == 999) {
+            printf ("+");
+            fflush (stdout);
+        }
+    }
+
+    printf ("\nNow the top nodes ....\n");
+    fflush (stdout);
+
+    for (i = ncount - 1; i >= newtop; i--)
+        p.mark[perm[i]] = 2;
+    p.phase = 2;
+
+    for (j = ncount - 1; j >= newtop; j--) {
+        i = perm[j];
+        if (CCkdtree_fixed_radius_nearest (&kt, dat, wcoord, i, dist, 
+                         junk_check, (void *) (&p))) {
+            fprintf (stderr, "CCkdtree_fixed_radius_nearest failed\n");
+            CCkdtree_free (&kt);
+            CC_IFFREE (p.badlist, int);
+            CC_IFFREE (p.badlen, int);
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (j % 1000 == 999) {
+            printf ("-");
+            fflush (stdout);
+        }
+    }
+    CCkdtree_free (&kt);
+    printf ("\n");
+    fflush (stdout);
+
+    if (p.ngot) {
+        int *rlist = (int *) NULL;
+        int *rlen = (int *) NULL;
+        int rcount = 0;
+        double rpenalty = 0.0;
+
+        if (ancestor_price (p.T, 0, p.ngot, p.list, p.len, &rcount, &rlist,
+                                &rlen, &rpenalty)) {
+            fprintf (stderr, "ancestor_price failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+
+        if (rcount) {
+            p.penalty += rpenalty;
+            if (merge_edge_lists (&(p.badcount), &(p.badlist), &(p.badlen),
+                                       rcount, rlist, rlen)) {
+                fprintf (stderr, "merge_edge_lists failed\n");
+                CC_IFFREE (rlist, int);
+                CC_IFFREE (rlen, int);
+                CC_IFFREE (p.badlist, int);
+                CC_IFFREE (p.badlen, int);
+                rval = 1;
+                goto CLEANUP;
+            }
+            CC_IFFREE (rlist, int);
+            CC_IFFREE (rlen, int);
+        }
+    }
+
+    printf ("Kdtree price time: %.2f seconds\n", CCutil_zeit () - szeit);
+    printf ("Total number of potential edges: %d\n", p.total);
+    fflush (stdout);
+
+    *badcount = p.badcount;
+    *badlist = p.badlist;
+    *badlen = p.badlen;
+    *penalty = p.penalty;
+
+CLEANUP:
+
+    CC_IFFREE (wcoord, double);
+    CC_IFFREE (list, int);
+    CC_IFFREE (len, int);
+    CC_IFFREE (p.mark, int);
+    CC_IFFREE (perm, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int junk_check (int n1, int n2, void *pass_param)
+#else
+static int junk_check (n1, n2, pass_param)
+int n1, n2;
+void *pass_param;
+#endif
+{
+    junk_param *p = (junk_param *) pass_param;
+    double t;
+    int l;
+
+    if ((!p->nodelist[n2].hit) ||
+        (p->phase == 0 && n1 < n2) ||
+        (p->phase == 1 && (n1 < n2 || !p->mark[n2])) ||
+        (p->phase == 2 && (!p->mark[n2] || (p->mark[n2] == 2 && n1 < n2)))) { 
+        l = CCutil_dat_edgelen (n1, n2, p->dat);
+        t = ((double) l) - p->nodelist[n1].sum - p->nodelist[n2].sum;
+        if (t > -MAT_GEN_EPSILON) {
+            printf ("What the hey: %f\n", t);
+            fflush (stdout);
+        }
+        p->total++;
+        p->len[p->ngot] = l;
+        p->list[2 * p->ngot] = n1;
+        p->list[2 * p->ngot + 1] = n2;
+        p->ngot++;
+
+        if (p->ngot == p->nwant) {
+            int *rlist = (int *) NULL;
+            int *rlen = (int *) NULL;
+            int rcount = 0;
+            double rpenalty = 0.0;
+
+            if (ancestor_price (p->T, 0, p->ngot, p->list, p->len,
+                      &rcount, &rlist, &rlen, &rpenalty)) {
+                fprintf (stderr, "ancestor_price failed\n");
+                return 1;
+            }
+
+            if (rcount) {
+                p->penalty += rpenalty;
+                if (merge_edge_lists (&(p->badcount), &(p->badlist),
+                             &(p->badlen), rcount,  rlist,  rlen)) {
+                    fprintf (stderr, "merge_edge_lists failed\n");
+                    CC_IFFREE (rlist, int);
+                    CC_IFFREE (rlen, int);
+                    return 1;
+                }
+                CC_IFFREE (rlist, int);
+                CC_IFFREE (rlen, int);
+            }
+            p->ngot = 0;
+        }
+    }
+    
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int merge_edge_lists (int *totalcount, int **totallist, int **totallen,
+            int ecount, int *elist, int *elen)
+#else
+static int merge_edge_lists (totalcount, totallist, totallen, ecount, elist,
+            elen)
+int *totalcount;
+int **totallist, **totallen;
+int ecount;
+int *elist, *elen;
+#endif
+{
+    int *nlist = (int *) NULL;
+    int *nlen = (int *) NULL;
+    int ncount = *totalcount + ecount;
+    int i, k;
+
+    if (!ecount)
+        return 0;
+
+    nlist = CC_SAFE_MALLOC (2 * ncount, int);
+    nlen = CC_SAFE_MALLOC (ncount, int);
+    if (!nlist || !nlen) {
+        fprintf (stderr, "out of memory in merge_edge_lists\n");
+        CC_IFFREE (nlist, int);
+        CC_IFFREE (nlen, int);
+        return 1;
+    }
+
+    for (i = 0; i < *totalcount; i++) {
+        nlist[2 * i] = (*totallist)[2 * i];
+        nlist[2 * i + 1] = (*totallist)[2 * i + 1];
+        nlen[i] = (*totallen)[i];
+    }
+    for (k = 0; k < ecount; k++, i++) {
+        nlist[2 * i] = elist[2 * k];
+        nlist[2 * i + 1] = elist[2 * k + 1];
+        nlen[i] = elen[k];
+    }
+
+    if (*totalcount) {
+        CC_IFFREE (*totallist, int);
+        CC_IFFREE (*totallen, int);
+    }
+
+    *totalcount = ncount;
+    *totallist = nlist;
+    *totallen = nlen;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int buildtree (tree *T, int ncount, double *pi, int *parent, char *hit)
+#else
+static int buildtree (T, ncount, pi, parent, hit)
+tree *T;
+int ncount;
+double *pi;
+int *parent;
+char *hit;
+#endif
+{
+    int bcount = 3 * ncount/2;
+    int *mark = (int *) NULL;
+    int *invnames = (int *) NULL;
+    int i, j, k;
+    int count = 0;
+    node *nodelist;
+    
+    T->ncount = 0;
+    T->realncount = 0;
+    T->nodelist = (node *) NULL;
+
+    mark = CC_SAFE_MALLOC (bcount, int);
+    if (!mark) {
+        fprintf (stderr, "out of memory in buildtree\n");
+        return 1;
+    }
+
+    for (i = 0; i < bcount; i++)
+        mark[i] = 0;
+
+    for (i = 0; i < ncount; i++) {
+        j = i;
+        while (j != -1 && mark[j] == 0) {
+            mark[j] = 1;
+            j = parent[j];
+        }
+    }
+    for (i = 0; i < bcount; i++)
+        if (mark[i])
+            count++;
+
+    printf ("%d tree nodes\n", count);
+    fflush (stdout);
+
+
+    T->nodelist = CC_SAFE_MALLOC (count + 1, node);
+    if (!T->nodelist) {
+        fprintf (stderr, "out of memory in buildtree\n");
+        CC_IFFREE (mark, int);
+        return 1;
+    }
+    T->ncount = count;
+    T->realncount = ncount;
+    T->root = T->nodelist + count;
+    T->root->parent = (node *) NULL;
+    T->root->child = (node *) NULL;
+    T->root->sibling = (node *) NULL;
+    T->root->pi = 0.0;
+    T->root->hit = 0;
+    nodelist = T->nodelist;
+
+    invnames = CC_SAFE_MALLOC (bcount, int);
+    if (!invnames) {
+        fprintf (stderr, "out of memory in buildtree\n");
+        CC_IFFREE (mark, int);
+        freetree (T);
+        return 1;
+    }
+
+    for (k = 0, i = 0; i < bcount; i++)
+        if (mark[i]) 
+            invnames[i] = k++;
+
+    for (k = 0, i = 0; i < bcount; i++) {
+        if (mark[i]) {
+            if (parent[i] == -1) {
+                nodelist[k].parent = T->root;
+            } else {
+                nodelist[k].parent = nodelist + invnames[parent[i]];
+            }
+            nodelist[k].child = (node *) NULL;
+            nodelist[k].sibling = (node *) NULL;
+            nodelist[k].pi = pi[i];
+            if (hit) {
+                nodelist[k].hit = hit[i];
+            } else {
+                nodelist[k].hit = 1;
+            }
+            k++;
+        }
+    }
+
+    for (i = 0; i < count; i++) {
+        if (nodelist[i].parent->child == (node *) NULL) {
+            nodelist[i].parent->child = nodelist + i;
+        } else {
+            nodelist[i].sibling = nodelist[i].parent->child->sibling;
+            nodelist[i].parent->child->sibling = nodelist + i;
+        }
+    }
+
+    T->root->sum = 0.0;
+    for (i = 0; i <= count; i++)
+        nodelist[i].mark = 0;
+    for (i = 0; i < ncount; i++)
+        get_sum_work (nodelist + i);
+    for (i = 0; i <= count; i++)
+        nodelist[i].mark = 0;
+    if (hit) {
+        int hcount = 0;
+        for (i = 0; i < ncount; i++) {
+            get_hit_work (nodelist + i);
+            if (nodelist[i].hit)
+                hcount++;
+        }
+        printf ("%d nodes must be checked\n", hcount);
+        for (i = 0; i <= count; i++)
+            nodelist[i].mark = 0;
+    } else {
+        for (i = 0; i < ncount; i++)
+            nodelist[i].hit = 1;
+    }
+
+    {
+        double minsum =  1000000000000.0;
+        double maxsum = -1000000000000.0;
+        for (i = 0; i < count; i++) {
+            if (nodelist[i].sum < minsum)
+                minsum = nodelist[i].sum;
+            if (nodelist[i].sum > maxsum)
+                maxsum = nodelist[i].sum;
+        }
+        printf ("Range of sums: %f  to %f\n", minsum, maxsum);
+        fflush (stdout);
+    }
+
+    
+ 
+    CC_IFFREE (invnames, int);
+    CC_IFFREE (mark, int);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double get_sum_work (node *n)
+#else
+static double get_sum_work (n)
+node *n;
+#endif
+{
+    if (!n)
+        return 0.0;
+
+    if (n->mark)
+        return n->sum;
+    else {
+        n->mark = 1;
+        n->sum = n->pi + get_sum_work (n->parent);
+        return n->sum;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static char get_hit_work (node *n)
+#else
+static char get_hit_work (n)
+node *n;
+#endif
+{
+    if (!n)
+        return 0;
+
+    if (n->mark || n->hit)
+        return n->hit;
+    else {
+        n->mark = 1;
+        n->hit = get_hit_work (n->parent);
+        return n->hit;
+    }
+}
+
+
+#ifdef DEBUG_MATPRICE
+#ifdef CC_PROTOTYPE_ANSI
+static void price_list (tree *T, int ecount, int *elist, int *elen, int *nbad)
+#else
+static void price_list (T, ecount, elist, elen, nbad)
+tree *T;
+int ecount;
+int *elist, *elen;
+int *nbad;
+#endif
+{
+    int i;
+    double t;
+    FILE *out = fopen ("dump.edges", "w");
+    double szeit = CCutil_zeit ();
+
+    if (!out) {
+        fprintf (stderr, "couldn't open dump.edges\n");
+        exit (1);
+    }
+
+    *nbad = 0;
+
+    for (i = 0; i < ecount; i++) {
+        if (i % 10000 == 0) {
+            printf ("T[%d](%.0f sec)  ", i / 10000, CCutil_zeit () - szeit);
+            fflush (stdout);
+        }
+        t = price_it (T, elist[2 * i], elist[2 * i + 1], elen[i]);
+        if (t < -MAT_GEN_EPSILON) {
+            (*nbad)++;
+            fprintf (out, "%d %d %d\n", elist[2 * i], elist[2 * i + 1],
+                                        elen[i]);
+        }
+    }
+    printf ("Found %d bad edges [%.2f seconds]\n", *nbad, CCutil_zeit () - szeit);
+    fflush (stdout);
+    fclose (out);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double price_it (tree *T, int n1, int n2, int len)
+#else
+static double price_it (T, n1, n2, len)
+int n1, n2, len;
+tree *T;
+#endif
+{
+    node *lca;
+    node *m1 = T->nodelist + n1;
+    node *m2 = T->nodelist + n2;
+
+    lca = easy_lca (m1, m2);
+    return ((double) len) - m1->sum - m2->sum + (2 * lca->sum);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *easy_lca (node *n1, node *n2)
+#else
+static node *easy_lca (n1, n2)
+#endif
+{
+    node *n, *a;
+    for (n = n1; n; n = n->parent)
+        n->mark = 1;
+    for (n = n2; n; n = n->parent)
+        if (n->mark) {
+            a = n;
+            break;
+        }
+    for (n = n1; n; n = n->parent)
+        n->mark = 0;
+
+    return a;
+}
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static void freetree (tree *T)
+#else
+static void freetree (T)
+tree *T;
+#endif
+{
+    CC_IFFREE (T->nodelist, node);
+    T->ncount = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int ancestor_price (tree *T, int zero_rc, int ecount, int *elist,
+        int *elen, int *badcount, int **badlist, int **badlen, double *penalty)
+#else
+static int ancestor_price (T, zero_rc, ecount, elist, elen, badcount, badlist,
+        badlen, penalty)
+tree *T;
+int zero_rc;
+int ecount;
+int *elist, *elen;
+int *badcount;
+int **badlist, **badlen;
+double *penalty;
+#endif
+{
+    int prenum = 0;
+    int i, nbad;
+    anc *anclist = (anc *) NULL;
+    anc *p;
+    node *n1, *n2, *t;
+    node *nodelist = T->nodelist;
+    int maxdepth = 0;
+    double szeit = CCutil_zeit ();
+    double w;
+
+    printf ("ancstor_price(%d) ....\n", ecount);
+    fflush (stdout);
+
+    *badcount = 0;
+    *badlist = (int *) NULL;
+    *badlen = (int *) NULL;
+    *penalty = 0.0;
+
+    number_tree (T->root, &prenum, 0, &maxdepth);
+/*
+    printf ("Maximum Depth of Tree: %d\n", maxdepth);
+    fflush (stdout); 
+*/
+    if (prenum != T->ncount + 1) {
+        printf ("Yipes in ancest_init\n");
+        fflush (stdout);
+    }
+
+    anclist = CC_SAFE_MALLOC (ecount, anc);
+    if (!anclist) {
+        fprintf (stderr, "out of memory in ancestor_price\n");
+        return 1;
+    }
+
+    for (i = 0; i < ecount; i++) {
+        n1 = nodelist + elist[2 * i];
+        n2 = nodelist + elist[2 * i + 1]; 
+
+        if (n1->prenum > n2->prenum) {
+            CC_SWAP(n1, n2, t);
+        }
+
+        p = anclist + i;
+
+        p->next = n2->evallist;
+        n2->evallist = p;
+        if (n1->addset) {
+            p->ancestor = (node *) NULL;
+	    n1->addset->rank = 1;
+	    p->rank = 0;
+	    p->parent = n1->addset; 
+        } else {
+	    p->ancestor = n1;
+	    p->rank = 0;
+	    n1->addset = p;
+	    p->parent = p;
+        }
+    }
+    ancest_work (T->root);
+
+    *penalty = 0.0;
+    nbad = 0;
+ 
+    if (zero_rc) {
+        for (i = 0; i < ecount; i++) {
+            n1 = nodelist + elist[2 * i];
+            n2 = nodelist + elist[2 * i + 1]; 
+
+            w = ((double) elen[i]) - n1->sum - n2->sum +
+                                            (2 * anclist[i].lca->sum);
+            if (w != 0.0) {
+                printf ("edge (%d,%d) with rc %f\n",
+                                 elist[2 * i], elist[2*i+1], w);
+                fflush (stdout);
+                (*penalty) += w;
+                nbad++;
+                anclist[i].rank = 1;
+            } else {
+                anclist[i].rank = 0;
+            }
+        }
+    } else {
+        for (i = 0; i < ecount; i++) {
+            n1 = nodelist + elist[2 * i];
+            n2 = nodelist + elist[2 * i + 1]; 
+
+            w = ((double) elen[i]) - n1->sum - n2->sum +
+                                            (2 * anclist[i].lca->sum);
+            if (w < -MAT_GEN_EPSILON) {
+                (*penalty) += w;
+                nbad++;
+                anclist[i].rank = 1;
+            } else {
+                anclist[i].rank = 0;
+            }
+        }
+    }
+
+    printf ("Number of bad edges: %d  (penalty = %f)\n", nbad, *penalty);
+    fflush (stdout);
+
+    if (nbad > 0) {
+        *badlist = CC_SAFE_MALLOC (2 * nbad, int);
+        *badlen = CC_SAFE_MALLOC (nbad, int);
+        if (!(*badlist) || !(*badlen)) {
+            fprintf (stderr, "out of memory in ancestor_price\n");
+            CC_IFFREE (*badlist, int);
+            CC_IFFREE (*badlen, int);
+            CC_IFFREE (anclist, anc);
+            return 0;
+        }
+        nbad = 0;
+        for (i = 0; i < ecount; i++) {
+            if (anclist[i].rank) {
+                (*badlist)[2 * nbad] = elist[2 * i];
+                (*badlist)[2 * nbad + 1] = elist[2 * i + 1];
+                (*badlen)[nbad] = elen[i];
+                nbad++;
+            }
+        }
+        *badcount = nbad;
+    }
+           
+    printf ("Ancestor Time: %.2f seconds\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    CC_IFFREE (anclist, anc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static anc *ancest_work (node *p)
+#else
+static anc *ancest_work (p)
+node *p;
+#endif
+{
+    node *q;
+    anc *a;
+
+    for (q = p->child; q; q = q->sibling) {
+	a = ancest_work (q);
+	if (a) {
+	    if (p->addset) {
+		p->addset = union_anc (a, p->addset);
+	    } else {
+		p->addset = a;
+	    }
+	    p->addset->ancestor = p;
+	}
+    }
+
+    for (a = p->evallist; a; a = a->next) {
+	a->lca = find_anc(a)->ancestor;
+    }
+
+    return p->addset;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void number_tree (node *n, int *prenum, int depth, int *maxdepth)
+#else
+static void number_tree (n, prenum, depth, maxdepth)
+node *n;
+int *prenum;
+int depth;
+int *maxdepth;
+#endif
+{
+    if (depth > *maxdepth)
+        *maxdepth = depth;
+    n->prenum = (*prenum)++;
+    n->addset = (anc *) NULL;
+    n->evallist = (anc *) NULL;
+    for (n = n->child; n; n = n->sibling) {
+	number_tree (n, prenum, depth + 1, maxdepth);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static anc *find_anc (anc *x)
+#else
+static anc *find_anc (x)
+anc *x;
+#endif
+{
+    anc *p = x->parent;
+    return (x == p) ? x : (x->parent = find_anc (p));
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static anc *union_anc (anc *x, anc *y)
+#else
+static anc *union_anc (x, y)
+anc *x;
+anc *y;
+#endif
+{
+    anc *t;
+
+    if (x->rank > y->rank) {
+	CC_SWAP (x, y, t);
+    } else if (x->rank == y->rank) {
+	y->rank++;
+    }
+    x->parent = y;
+    return y;
+}
+
diff --git a/contrib/blossom/MATCH/matprice.h b/contrib/blossom/MATCH/matprice.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b1161d79aee3032b22c68cf8733e4dd37c345dc
--- /dev/null
+++ b/contrib/blossom/MATCH/matprice.h
@@ -0,0 +1,22 @@
+#ifndef  __MATPRICE_H
+#define  __MATPRICE_H
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+   matching_price (int ncount, CCdatagroup *dat, double *orig_pi,
+                   int *orig_parent, int *badcount, int **badlist,
+                   int **badlen, double *penalty, CCtsp_edgegenerator *starteg,
+                   char *hit),
+   matching_check (int ncount, double *orig_pi, int *orig_parent,
+                   int *matchlist, int *mlen, int *csbad);
+
+#else
+
+int
+    matching_price (),
+    matching_check ();
+
+#endif
+
+#endif  /* __MATPRICE_H */
diff --git a/contrib/blossom/MATCH/mp_main.c b/contrib/blossom/MATCH/mp_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d28b1a7f726558eebe16b19d2f29e7876b723a0
--- /dev/null
+++ b/contrib/blossom/MATCH/mp_main.c
@@ -0,0 +1,428 @@
+/***************************************************************************/
+/*                                                                         */
+/*                TEST PROGRAM FOR PRICING MATCHINGS                       */
+/*                                                                         */
+/*  Written by:  D. Applegate, W. Cook, and A. Rohe                        */
+/*  Date: August 1, 1996                                                   */
+/*                                                                         */
+/*  SEE short decsribtion in usage ().                                     */
+/*                                                                         */
+/*  Link with:                                                             */
+/*     (see Makefile)                                                      */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/*     The dual file is a binary file that contains 3/2 ncount records.    */
+/*   Each record is an int followed by a double. Each record corresponds   */
+/*   to either a node, or a blossom, or wasted space. The node records     */
+/*   are the initial ncount entries; the blossom and wasted records are    */
+/*   mixed in the remaint ncount/2 records. The first entry of a record    */
+/*   gives the index of the parent of the node or blossom in the nesting   */
+/*   structure; it is -1 if there is no parent. The second entry is the    */
+/*   dual value of the node or blossom. To determine which records are     */
+/*   blossoms and which are wasted, you can trace the parent pointers of   */
+/*   the node records to find the remaining records that are hit.          */
+/*                                                                         */
+/*     If a matching file is given, then the complementary slackness       */
+/*   conditions will be checked. A matching file has the format of a       */
+/*   standard edge file.                                                   */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "concorde.h"
+#include "matprice.h"
+
+static int norm = CC_EUCLIDEAN;
+static char *dualfilename = (char *) NULL;
+static char *datfilename = (char *) NULL;
+static char *matfilename = (char *) NULL;
+static char *badfilename = (char *) NULL;
+static int binary_in = 0;
+static int tsplib_in = 0;
+static int seed = 0;
+
+#ifdef  CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+
+static void
+    usage (char *f);
+
+static int
+    parseargs (int ac, char **av),
+    read_matching (char *fname, int ncount, int **matchlist,
+                       CCdatagroup *dat),
+    read_blossom_tree (char* blossom_tree_file, int ncount, double **pi,
+                       int **parent);
+
+#else  /* CC_PROTOTYPE_ANSI */
+
+int
+    main ();
+
+static void
+    usage ();
+
+static int
+    parseargs (),
+    read_matching (),
+    read_blossom_tree ();
+
+#endif /* CC_PROTOTYPE_ANSI */
+
+
+#ifdef  CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    double szeit;
+    int ncount;
+    double *pi = (double *) NULL;
+    int *parent = (int *) NULL;
+    CCdatagroup dat;
+    int csbad = 0;
+    int badcount = 0;
+    int *badlist = (int *) NULL;
+    int *badlen = (int *) NULL;
+    int *matchlist = (int *) NULL;
+    double penalty;
+    int rval = 0;
+    long l;
+#ifdef  CC_PROTOTYPE_ANSI
+    extern long time (long *);
+#else
+    extern long time ();
+#endif
+
+    seed = time (&l);
+    if (parseargs (ac, av)) 
+        return 0;
+    CCutil_sprand (seed);
+
+    if (datfilename == (char *) NULL || dualfilename == (char *) NULL) {
+        usage (av[0]);
+        return 0;
+    }
+    ncount = 0;
+
+    szeit = CCutil_zeit ();
+    if (tsplib_in) {
+        if (CCutil_gettsplib (datfilename, &ncount, &dat)) {
+            fprintf (stderr, "could not read the TSPLIB file\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        norm = dat.norm;
+    } else {
+        if (CCutil_getdata (datfilename, binary_in, norm, &ncount, &dat)) {
+            fprintf (stderr, "Could not create data set\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (CCutil_init_dat_edgelen (&dat)) {
+        fprintf (stderr, "init_dat_edgelen failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Number of nodes: %d\n", ncount);
+    fflush (stdout);
+                  
+    if (read_blossom_tree (dualfilename, ncount, &pi, &parent)) {
+        fprintf (stderr, "read_blossom_tree failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (matfilename) {
+        if (read_matching (matfilename, ncount, &matchlist, &dat)) {
+            fprintf (stderr, "read_matching failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    printf ("Hello !\n");
+    if (matching_price (ncount, &dat, pi, parent, 
+                        &badcount, &badlist, &badlen, &penalty, NULL, NULL)) {
+        fprintf (stderr, "matching_price failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Found %d bad edges, with total penalty %f\n", badcount, penalty);
+    fflush (stdout);
+
+    if (badcount) {
+        if (badfilename) {
+            if (CCutil_writeedges (ncount, badfilename, badcount, badlist, &dat)) {
+                fprintf (stderr, "CCutil_writeedges failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        } else {
+            printf ("Writing bad edges to dump.edges\n");
+            fflush (stdout);
+            if (CCutil_writeedges (ncount, "dump.edges", badcount, badlist, &dat)) {
+                fprintf (stderr, "CCutil_writeedges failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+    }
+  
+    if (matfilename) {
+        int *mlen = CC_SAFE_MALLOC (ncount/2, int);
+        int i;
+
+        for (i = 0; i < ncount/2; i++ ) 
+            mlen[i] = CCutil_dat_edgelen (matchlist[2*i],matchlist[2*i+1], &dat);
+        
+        if ( matching_check (ncount, pi, parent, matchlist, mlen, &csbad)) {
+            fprintf (stderr, "matching_check failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (csbad) {
+        printf ("COMPLEMENTARY SLACKNESS CONDITIONS ARE VIOLATED\n");
+        fflush (stdout);
+    }
+
+    printf ("Total Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (badlist, int);
+    CC_IFFREE (badlen, int);
+    CC_IFFREE (pi, double);
+    CC_IFFREE (parent, int);
+    CC_IFFREE (matchlist, int);
+    CCutil_freedatagroup (ncount, &dat);
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: bigchunk_free_world failed\n");
+        return 1;
+    }
+
+    return rval;
+}
+
+#ifdef  CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "bd:m:n:o:s:T0123456789")) != EOF)
+	switch (c) {
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'd':
+            dualfilename = CCutil_bix_optarg;
+            break;
+        case 'm':
+            matfilename = CCutil_bix_optarg;
+            break;
+        case 'n':
+            datfilename = CCutil_bix_optarg;
+            break;
+        case 'o':
+            badfilename = CCutil_bix_optarg;
+            break;
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 'T':
+            tsplib_in = 1;
+            break;
+        case '0':
+            norm = CC_MAXNORM;
+            break;
+        case '1':
+            norm = CC_EUCLIDEAN_CEIL;
+            break;
+        case '2':
+            norm = CC_EUCLIDEAN;
+            break;
+        case '3':
+            norm = CC_EUCLIDEAN_3D;
+            break;
+        case '4':
+            norm = CC_IBM;
+            break;
+        case '5':
+            norm = CC_ATT;
+            break;
+        case '6':
+            norm = CC_GEOGRAPHIC;
+            break;
+        case '7':
+            norm = CC_MATRIXNORM;
+            break;
+        case '8':
+            norm = CC_DSJRANDNORM;
+            break;
+        case '9':
+            norm = CC_CRYSTAL;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+	default:
+	    usage (av[0]);
+            return 1;
+	}
+    if (CCutil_bix_optind != ac) {
+	usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef  CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "Usage: %s [-see below-]\n", f);
+    fprintf (stderr, "   -b    datfile in integer binary format\n");
+    fprintf (stderr, "   -d f  dual file - MUST be specified\n");
+    fprintf (stderr, "   -m f  matching file (to check complementary slackness\n");
+    fprintf (stderr, "   -n f  dat file - MUST be specified\n");
+    fprintf (stderr, "   -o f  output file for bad edges (default: dump.edges)\n");
+    fprintf (stderr, "   -s #  random seed\n");
+    fprintf (stderr, "   -T    the dat file is a TSPLIB file\n");
+    fprintf (stderr, "   -0    price out using MAX norm\n");
+    fprintf (stderr, "   -1    price out using JOHNSON norm\n");
+    fprintf (stderr, "   -2    price out using EUCLIDEAN norm (default)\n");
+    fprintf (stderr, "   -3    price out using Rounded Euclidean 3D norm\n");
+    fprintf (stderr, "   -(4 5 6 7 8 9) IBM ATT GEO MATRIX DSJRAND CRYSTAL norm\n");
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int read_matching (char *fname, int ncount, int **matchlist,
+                          CCdatagroup *dat) 
+#else
+static int read_matching (fname, ncount, matchlist, dat) 
+char *fname;
+int ncount;
+int **matchlist;
+CCdatagroup *dat;
+#endif
+{
+    int *matlen = (int *) NULL;
+    int i, mcount, len;
+
+    if (CCutil_getedgelist (ncount, fname, &mcount, matchlist, &matlen)) {
+        fprintf (stderr, "getedgelist failed\n");
+        return 1;
+    }
+
+    if (mcount != ncount / 2) {
+        fprintf (stderr, "matching file %s has wrong format\n", fname);
+        CC_IFFREE (matlen, int);
+        return 1;
+    }
+
+    for (i = 0; i < mcount; i++) {
+        len = CCutil_dat_edgelen ((*matchlist)[2*i], (*matchlist)[2*i+1], dat);
+        if (matlen[i] != len) {
+            fprintf (stderr, "length of (%d,%d) is %d not %d\n",
+                  (*matchlist)[2*i], (*matchlist)[2*i+1], len, matlen[i]);
+            CC_IFFREE (matlen, int);
+            return 1;
+        }
+    }
+
+    CC_IFFREE (matlen, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int read_blossom_tree (char* blossom_tree_file, int ncount,
+                              double **pi, int **parent) 
+#else
+static int read_blossom_tree (blossom_tree_file, ncount, pi, parent) 
+char *blossom_tree_file;
+int ncount;
+double **pi;
+int **parent;
+#endif
+{
+    int i,j;
+    FILE* f;
+    int *mark = (int *) NULL;
+    int c1 = 0, c2 = 0;
+    int bcount = 3 * ncount/2;
+    double szeit;
+
+    *pi = CC_SAFE_MALLOC (bcount + 1, double);
+    *parent = CC_SAFE_MALLOC (bcount + 1, int);
+    mark = CC_SAFE_MALLOC (bcount + 1, int);
+    if (!(*pi) || !(*parent) || !mark) {
+        fprintf (stderr, "out of memory in read_blossom_tree\n");
+        CC_IFFREE (*pi, double);
+        CC_IFFREE (*parent, int);
+        CC_IFFREE (mark, int);
+        return 1;
+    }
+
+    printf("Reading %s ...",blossom_tree_file);
+    fflush(stdout);
+    szeit = CCutil_zeit();
+    if ((f = fopen(blossom_tree_file,"r"))==NULL) {
+	fprintf(stderr," Error: Can't open file %s\n",blossom_tree_file);
+        CC_IFFREE (*pi, double);
+        CC_IFFREE (*parent, int);
+        CC_IFFREE (mark, int);
+        return 1;
+    }
+    for (i = 0; i < bcount; i++) {
+	fread ((*parent)+i, sizeof(int), 1, f);
+	fread ((*pi)+i, sizeof(double), 1, f);
+    }
+    fclose (f);
+    printf(" ... in %.2f sec\n",CCutil_zeit () - szeit);
+    fflush(stdout);
+
+    for (i = 0; i < bcount; i++) 
+	mark[i]=0;
+
+    for (i = 0; i < ncount; i++) {
+	j=i;
+	while (j != -1 && mark[j] == 0) {
+	    mark[j] = 1;
+	    j = (*parent)[j];
+	}
+    }
+
+    for (i = ncount; i < bcount; i++) {
+	if (mark[i]) {
+	    c1++;
+	    if ((*pi)[i] == 0.0) 
+		c2++;
+	}
+    }
+
+    printf ("Number of blossoms: %d (with %d at 0 value)\n", c1, c2);
+    fflush(stdout);
+
+    CC_IFFREE(mark, int);
+    return 0;
+}
diff --git a/contrib/blossom/MATCH/tri_call.c b/contrib/blossom/MATCH/tri_call.c
new file mode 100644
index 0000000000000000000000000000000000000000..255c8ae73e68cd25b9b593ed5e6b740bb28c929a
--- /dev/null
+++ b/contrib/blossom/MATCH/tri_call.c
@@ -0,0 +1,185 @@
+/***********************************************************/
+/*                                                         */
+/*             ROUTINE TO START TRIANGLE CODE              */
+/*                                                         */
+/*  TRIANGLE is a program to calculte Delaunay             */
+/*  trianglulations, it can be found at                    */
+/*      http://www.cs.cmu.edu/~quake/triangle.html         */
+/*                                                         */
+/*  Written by:  A. Rohe                                   */
+/*  Date:  July 28, 1997                                   */
+/*                                                         */
+/*  This program should be compiled with make tri_call     */
+
+/*  This program should be compiled with make tri_call     */
+/*                                                         */
+/*  It can be used the following way:                      */
+/*                                                         */
+/*  tri_call  <data-file> <edge-file> <triangle>           */
+/*                                                         */
+/*  <data-file> is a normal blossom4 x-y input file        */
+/*  <edge-file> is a the edgefile-name you would like      */
+/*  <triangle>  is the place of and name of the triangle   */
+/*              executable                                 */
+/*                                                         */
+/*  The program will creat a <data-file>.node file and     */
+/*  a <data-file>.1.edge file and not delete them !        */
+/*                                                         */
+/***********************************************************/
+/*                                                         */
+/*  example:                                               */
+/*                                                         */
+/*  tri_call 100.dat 100.del ./triangle                    */
+/*                                                         */
+/*  this reads the file 100.dat, writes the delaunay       */
+/*  triangulation to 100.del using the program             */
+/*  ./triangle.                                            */
+/*  The files 100.dat.node and 100.del.1.edge will         */
+/*  be created.                                            */
+/*                                                         */
+/***********************************************************/
+/*                                                         */
+/*  Then this data can be used the following way:          */
+/*                                                         */
+/*  - To get the minimum weight perfect matching in        */
+/*    in the complete graph starting with the              */
+/*    Delaunay triangulation:                              */
+/*        blossom4 -x 100.dat -e 100.del                   */
+/*                                                         */
+/*  - To get the minimum weight perfect matching in        */
+/*    in the Delaunay triangulation:                       */
+/*        blossom4 -e 100.del                              */
+/*                                                         */
+/***********************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+int nodes;
+double *x,*y;
+
+ /*
+** read_xy, reads the x and y coordinates
+*/
+#ifdef PROTOTYPE_ANSI
+static void read_write_xy (char* name)
+#else
+static void read_write_xy (name)
+char *name;
+#endif
+{
+    int i;
+    FILE *fp1,*fp2;
+    char name2[200];
+
+    /* OPEN name */
+    if ((fp1=fopen(name,"r"))==NULL) {
+        printf("Can't open file %s \n",name);
+        exit(1);
+    }
+    /* OPEN name2 */
+    sprintf(name2,"%s.node",name);
+    if ((fp2=fopen(name2,"w"))==NULL) {
+        printf("Can't open file %s \n",name2);
+        exit(1);
+    }
+
+    /* get #nodes */
+    fscanf(fp1,"%i",&nodes);
+    fprintf(fp2,"%i 2 0 0\n",nodes);
+    printf("Number of nodes: %i\n",nodes);
+    printf("Reading from %s and writing to %s\n",name,name2);
+
+    /* initialize the x[]'s */
+    if ((x=(double *)malloc(nodes * sizeof(double))) == NULL) {
+        printf("Not enough memory to allocate buffer for x\n");
+        exit(1);  /* terminate program if out of memory */
+    }
+    /* initialize the yy[]'s */
+    if ((y=(double *)malloc(nodes * sizeof(double))) == NULL) {
+        printf("Not enough memory to allocate buffer for y\n");
+        exit(1);  /* terminate program if out of memory */
+    }
+
+    /* read from fp1 and write to fp2 */
+    for (i=0;i<nodes;i++) {
+        fscanf(fp1,"%lf %lf",x+i,y+i);
+        fprintf(fp2,"%i %lf %lf\n",i,x[i],y[i]);
+    }
+    fclose(fp1);
+    fclose(fp2);
+}
+
+ /*
+** read_xy, reads the x and y coordinates
+*/
+#ifdef PROTOTYPE_ANSI
+static void read_write_edges (char* name,char* edgefile)
+#else
+static void read_write_edges (name,edgefile)
+char *name;
+char *edgefile;
+#endif
+{
+    int i,a,b;
+    int edges,dummy;
+    FILE *fp1,*fp2;
+    char name2[200];
+
+    /* OPEN name */
+    if ((fp1=fopen(edgefile,"w"))==NULL) {
+        printf("Can't open file %s \n",edgefile);
+        exit(1);
+    }
+    /* OPEN name2 */
+    sprintf(name2,"%s.1.edge",name);
+    if ((fp2=fopen(name2,"r"))==NULL) {
+        printf("Can't open file %s \n",name2);
+        exit(1);
+    }
+
+    fscanf(fp2,"%i %i",&edges,&dummy);
+    fprintf(fp1,"%i %i\n",nodes,edges);
+    printf("Number of edges: %i\n",edges);
+    printf("Reading from %s and writing to %s\n",name2,edgefile);
+
+    for (i=0;i<edges;i++) {
+        fscanf(fp2,"%i %i %i",&dummy,&a,&b);
+        fprintf(fp1,"%i %i %i\n",a,b,(int)(0.5 + sqrt( (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]) )));
+    }
+    fclose(fp1);
+    fclose(fp2);
+    free(x);
+    free(y);
+}
+
+/*
+** main program
+*/
+#ifdef PROTOTYPE_ANSI
+int  main (int ac, char **av)
+#else
+int  main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    char triangle_call[200];
+
+    if (ac<4) {
+        printf("\nNot enough parameters:\n%s  <data-file> <edge-file> <triangle>\n",av[0]);
+        exit(1);  /* terminate program */
+    }
+
+    read_write_xy(av[1]);
+
+    sprintf(triangle_call,"%s -e -B -P -N -E -z %s",av[3],av[1]);
+    printf("I'll do the command '%s' \n",triangle_call);
+    fflush(stdout);
+    system(triangle_call);
+
+    read_write_edges(av[1],av[2]);
+    printf("Ready !\n");
+
+}
diff --git a/contrib/blossom/README.txt b/contrib/blossom/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..007eab2e1568a4e2870ecd93c19b63ab0ba15b7e
--- /dev/null
+++ b/contrib/blossom/README.txt
@@ -0,0 +1,83 @@
+
+This directory contains the source code for concorde97 and MATCH
+(which contains the Blossom IV code).
+
+As a special exception granted by Prof. Bill Cook, the code in this
+directory can be used within the Gmsh system for both academic and
+non-academic use. Note that this exception to the standard license is
+granted only for use within the Gmsh system: see the original email
+exchange below:
+
+
+Subject: Re: Concorde non academic use
+Date: Thu, 22 Sep 2011 18:01:14 +0200
+Cc: <Jean-Francois.Remacle@uclouvain.be>
+To: Bill Cook <bico@isye.gatech.edu>
+
+Dear Prof. Cook,
+
+Thanks for your email: it will make many Gmsh users very happy!
+
+All the best,
+
+Christophe
+
+On 22 Sep 2011, at 17:15, Bill Cook wrote:
+>
+> Dear Professor Remacle, Thanks for your email.  That is nice to hear
+> that the matching code in useful in your finite-element work.  It is
+> fine to include Blossom IV and Concorde in your distribution, including
+> use for non-academic work.  Could you please include wording that the
+> Concorde license is granted only for use within the Gmsh system?
+>
+> Thanks again.
+>
+> Best regards,
+>
+> Bill
+>
+>
+>
+> Jean-Fran=E7ois Remacle wrote:
+>> Dear Dr. Cook,
+>>
+>> We are the developers of GMSH, the open source mesh generator (see =
+www.geuz.org/gmsh <http://www.geuz.org/gmsh> or
+>> http://onlinelibrary.wiley.com/doi/10.1002/nme.2579/abstract).  We =
+provide Gmsh under the GPL license.
+>>
+>> In a recent research, we have developed a new method for building =
+specific kind of meshes (quadrilaterals). This new method requires to =
+compute optimal perfect matchings. We have found out that the "Blossom =
+IV" implementation was indeed quite effective. This implementation makes =
+use of Concorde.
+>>
+>> In your web page, it is said that "concorde is available for academic =
+research use; for other uses, contact William Cook =
+<mailto:bico@isye.gatech.edu?subject=3DConcorde> for licensing =
+options.". We'd like that Gmsh users can take advantage of our new =
+algorithm.  Yet, even though most of Gmsh's users are form academia, =
+some  are from engineering offices. This is indeed incompatible with =
+Concorde's license.
+>> I therefore contact you for getting more information about the =
+licensing options that are available.
+>>
+>> Best regards,
+>>
+>> Jean-Fran=E7ois Remacle & Christophe Geuzaine.
+>>
+>> ------------------------------------------------------------------
+>> Prof. Jean-Francois Remacle
+>> Universite catholique de Louvain (UCL)
+>> Ecole Polytechnique de Louvain (EPL) - Louvain School of Engineering
+>> Institute of Mechanics, Materials and Civil Engineering (iMMC)
+>> Center for Systems Engineering and Applied Mechanics (CESAME)
+>> Tel : +32-10-472352 -- Mobile : +32-473-909930
+>>
+>>
+>
+
+--
+Prof. Christophe Geuzaine
+University of Liege, Electrical Engineering and Computer Science
+http://www.montefiore.ulg.ac.be/~geuzaine
diff --git a/contrib/blossom/concorde97/00_README b/contrib/blossom/concorde97/00_README
new file mode 100644
index 0000000000000000000000000000000000000000..dacdaf7b2e3d80202750f25c4f0081f234230a3a
--- /dev/null
+++ b/contrib/blossom/concorde97/00_README
@@ -0,0 +1,42 @@
+INSTRUCTIONS FOR CONFIGURING:  (Preliminary Version (27.08.97))
+
+1.  Edit Makefile.conf to describe your system.  If you are fortunate,
+your processor, operating system, and compiler already have a prebuilt
+entry listed in the comments at the start of the file.  If so,
+uncomment the "SYS=" line and set it to your system's configuration
+name.
+
+2.  Otherwise, edit the lines defining CC, OPTFLAGS, COMFLAGS,
+LOADFLAGS, RANLIB, OBJNAME, and CCSYSNAME.  Each entry in
+Makefile.conf is preceeded by a brief comment describing its meaning.
+Try CCSYS_STANDARD if you have an ANSI C compiler, and
+CCSYS_STANDARD_KNR if you have an older, K&R C compiler.  If you are
+fortunate, that will be enough.
+
+3.  Otherwise, you will have to create an entry in INCLUDE/machdefs.h.
+Each stanza in machdefs.h contains system-dependent information for
+the compiler.  Pick a system that you think is "close" to yours, copy
+it, and choose a new name (which you will use in Makefile.conf) for
+the new description.  If you have an ANSI C compiler, include the line
+"#define CC_PROTOTYPE_ANSI", otherwise include the line "#undef
+CC_PROTOTYPE_ANSI".  You may need to adjust the list of system include
+files to match your system.  Then, select a way to access the amount of
+cpu time a process has used on your system.  Most systems can access
+the cpu time through either get_rusage() or times().  In this case,
+just "#define CC_ZEIT_RUSAGE" or "#define CC_ZEIT_TIMES".  Otherwise,
+use "#define CC_ZEIT_DUMMY", in which case all cpu times reported by
+the programs will be 0.0, or define a new CCutil_zeit() function which
+returns the accumulated cpu time on your system.
+
+
+INSTRUCTIONS FOR COMPILING:
+
+Once you have configured your system, compiling is straightforward.
+The makefiles included with the code depend upon GNU Make.  If you
+don't have it, the source code can be downloaded by anonymous ftp from
+ftp://prep.ai.mit.edu/pub/gnu/make-3.75.tar.gz.  Then, to make
+everything, in the top level directory, enter the command "make all".
+If you only want to make concorde.a and concorde.h, enter the command
+"make".  If you only want to make the executable and library in one
+subdirectory, cd into that subdirectory and enter "make".
+
diff --git a/contrib/blossom/concorde97/BIGGUY/Makefile b/contrib/blossom/concorde97/BIGGUY/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..6b80298396888bfd4db2fcc5758460608c2a8a7e
--- /dev/null
+++ b/contrib/blossom/concorde97/BIGGUY/Makefile
@@ -0,0 +1,34 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=bigguy.a
+LIBSRCS=bigguy.c
+ALLSRCS=bg_test.c $(LIBSRCS)
+LIBS=$(ROOT)/UTIL/util.a
+
+all: bg_test $(LIB)
+
+bg_test: bg_test.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ -lm
+
+test: bg_test
+	time bg_test < bigguy.tst > bigguy.ts2
+	cmp bigguy.tst bigguy.ts2
+
+clean:
+	-rm -f *.$o $(LIB) bg_test bigguy.ts2
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+bg_test.$o:  bg_test.c  $(I)/machdefs.h $(I)/util.h     $(I)/bigguy.h   
+bigguy.$o:   bigguy.c   $(I)/machdefs.h $(I)/util.h     $(I)/bigguy.h   
diff --git a/contrib/blossom/concorde97/BIGGUY/bg_test.c b/contrib/blossom/concorde97/BIGGUY/bg_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..ebd17c49ad8be518bea2ce26c8d592cb4449ce0d
--- /dev/null
+++ b/contrib/blossom/concorde97/BIGGUY/bg_test.c
@@ -0,0 +1,281 @@
+#include "machdefs.h"
+#include "util.h"
+#include "bigguy.h"
+
+#define EPSILON ((1.0/(1<<15))*(1.0/(1<<15)))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static CCbigguy
+    bgrand (double *delta, int maxx);
+
+static int
+    bgcheck (CC_SFILE *sfin, CC_SFILE *sfout, CCbigguy x, char *name),
+    dotest (int maxx, int maxy, int maxs, int ntrial, double *delta,
+        CCbigguy *sum, CC_SFILE *sfin, CC_SFILE *sfout);
+
+static void
+    sum_chk (CCbigguy *sum, CCbigguy x);
+
+static short
+    shortrand (short maxs);
+
+#else
+
+static CCbigguy
+    bgrand();
+
+static int
+    bgcheck (),
+    dotest ();
+
+static void
+    sum_chk ();
+
+static short
+    shortrand ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int i;
+    int x, y, d;
+    int nerrs = 0;
+    CC_SFILE *sfin = CCutil_sdopen (0, "r");
+    CC_SFILE *sfout = CCutil_sdopen (1, "w");
+    double delta;
+    CCbigguy sum;
+
+    CCutil_sprand (47);
+
+    if (ac > 1) {
+        fprintf (stderr, "Usage: %s < std_file > new_file\n", av[0]);
+        return 1;
+    }
+
+    nerrs += bgcheck (sfin, sfout, CCbigguy_MINBIGGUY, "CCbigguy_MINBIGGUY");
+    nerrs += bgcheck (sfin, sfout, CCbigguy_MAXBIGGUY, "CCbigguy_MAXBIGGUY");
+    nerrs += bgcheck (sfin, sfout, CCbigguy_ZERO, "CCbigguy_ZERO");
+    nerrs += bgcheck (sfin, sfout, CCbigguy_ONE, "CCbigguy_ONE");
+
+    delta = 0.0;
+
+    sum = CCbigguy_ZERO;
+    nerrs += bgcheck (sfin, sfout, sum, "sum_init");
+    
+    for (i=6; i<=30; i+=8) {
+        for (x=(1<<i), y=(1<<i); y >= 1; y /= 16, x += 15*y) {
+            for (d=(y < 32767 ? y : 32767); d>0; d /= 6) {
+                nerrs += dotest (x, y/d, d, 100, &delta, &sum, sfin, sfout);
+            }
+            for (d=(y < 32767 ? y : 32767); d>0; d /= 6) {
+                nerrs += dotest (y, x/d, d, 100, &delta, &sum, sfin, sfout);
+            }
+        }
+    }
+
+    CCutil_sclose (sfin);
+    CCutil_sclose (sfout);
+
+    fprintf (stderr, "%d total errors\n", nerrs);
+    fprintf (stderr, "Total delta: %.20f\n", delta);
+
+    return nerrs;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int dotest (int maxx, int maxy, int maxs, int ntrial, double *delta,
+                   CCbigguy *sum, CC_SFILE *sfin, CC_SFILE *sfout)
+#else
+static int dotest (maxx, maxy, maxs, ntrial, delta, sum, sfin, sfout)
+int maxx;
+int maxy;
+int maxs;
+int ntrial;
+double *delta;
+CCbigguy *sum;
+CC_SFILE *sfin;
+CC_SFILE *sfout;
+#endif
+{
+    int i;
+    int j;
+    CCbigguy x;
+    CCbigguy y;
+    CCbigguy a, b, c, d, e, f, g;
+    short s;
+    int nerrs = 0;
+
+    if (maxs > 32767) maxs = 32767;
+    
+    for (i=0; i<ntrial; i++) {
+        x = bgrand (delta, maxx);
+        y = bgrand (delta, maxy);
+        s = shortrand (maxs);
+
+        a = x;
+        CCbigguy_add (&a, y);
+
+        b = x;
+        CCbigguy_sub (&b, y);
+
+        c = x;
+        CCbigguy_addmult (&c, y, CCbigguy_cmp (x, y));
+
+        d = x;
+        CCbigguy_addmult (&d, y, s);
+
+        e = CCbigguy_ceil (x);
+
+        j = CCutil_lprand();
+
+        f = CCbigguy_itobigguy (j);
+
+        g = CCbigguy_itobigguy (-j);
+
+        sum_chk (sum, x);
+        sum_chk (sum, y);
+        sum_chk (sum, a);
+        sum_chk (sum, b);
+        sum_chk (sum, c);
+        sum_chk (sum, d);
+        sum_chk (sum, e);
+        sum_chk (sum, f);
+        sum_chk (sum, g);
+
+        if (i < 3) {
+            char nambuf[5];
+            sprintf (nambuf, "x%d", i);
+            nerrs += bgcheck (sfin, sfout, x, nambuf);
+            nambuf[0] = 'y';
+            nerrs += bgcheck (sfin, sfout, y, nambuf);
+            nambuf[0] = 'a';
+            nerrs += bgcheck (sfin, sfout, a, nambuf);
+            nambuf[0] = 'b';
+            nerrs += bgcheck (sfin, sfout, b, nambuf);
+            nambuf[0] = 'c';
+            nerrs += bgcheck (sfin, sfout, c, nambuf);
+            nambuf[0] = 'd';
+            nerrs += bgcheck (sfin, sfout, d, nambuf);
+            nambuf[0] = 'e';
+            nerrs += bgcheck (sfin, sfout, e, nambuf);
+            nambuf[0] = 'f';
+            nerrs += bgcheck (sfin, sfout, f, nambuf);
+            nambuf[0] = 'g';
+            nerrs += bgcheck (sfin, sfout, g, nambuf);
+        }
+    }
+    nerrs += bgcheck (sfin, sfout, *sum, "end sum");
+
+    return nerrs;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void sum_chk (CCbigguy *sum, CCbigguy x)
+#else
+static void sum_chk (sum, x)
+CCbigguy *sum;
+CCbigguy x;
+#endif
+{
+    CCbigguy y;
+    
+    if (CCbigguy_cmp (x, CCbigguy_ZERO) > 0 &&
+        CCbigguy_cmp (*sum, CCbigguy_ZERO) > 0) {
+        y = CCbigguy_MAXBIGGUY;
+        CCbigguy_sub (&y, x);
+        if (CCbigguy_cmp (*sum, y) >= 0) {
+            CCbigguy_sub (sum, CCbigguy_MAXBIGGUY);
+        }
+    } else if (CCbigguy_cmp (x, CCbigguy_ZERO) < 0 &&
+        CCbigguy_cmp (*sum, CCbigguy_ZERO) < 0) {
+        y = CCbigguy_MINBIGGUY;
+        CCbigguy_sub (&y, x);
+        if (CCbigguy_cmp (*sum, y) <= 0) {
+            CCbigguy_sub (sum, CCbigguy_MINBIGGUY);
+        }
+    }
+    CCbigguy_add (sum, x);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int bgcheck (CC_SFILE *sfin, CC_SFILE *sfout, CCbigguy x, char *name)
+#else
+static int bgcheck (sfin, sfout, x, name)
+CC_SFILE *sfin;
+CC_SFILE *sfout;
+CCbigguy x;
+char *name;
+#endif
+{
+    CCbigguy v;
+
+    CCbigguy_sread (sfin, &v);
+    CCbigguy_swrite (sfout, x);
+    if (CCbigguy_cmp(v,x)) {
+        fprintf (stderr, "%s misread (%.15f != %.15f)\n", name,
+                 CCbigguy_bigguytod(v), CCbigguy_bigguytod(x));
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static CCbigguy bgrand (double *delta, int maxv)
+#else
+static CCbigguy bgrand (delta, maxv)
+double *delta;
+int maxv;
+#endif
+{
+    CCbigguy x, y;
+    double d16 = 1.0 / (1 << 16);
+    double d32 = d16 * d16;
+    double dx;
+
+    dx = d32 * (CCutil_lprand() & 0xffff);
+    x = CCbigguy_dtobigguy (dx);
+    *delta += fabs(dx - CCbigguy_bigguytod(x));
+
+    dx = d16 * (CCutil_lprand() & 0xffff);
+    y = CCbigguy_dtobigguy(dx);
+    *delta += fabs(dx - CCbigguy_bigguytod(y));
+    CCbigguy_add (&x, y);
+
+    dx = 1.0 * (CCutil_lprand() % maxv);
+    y = CCbigguy_dtobigguy(dx);
+    *delta += fabs(dx - CCbigguy_bigguytod(y));
+    CCbigguy_add (&x, y);
+
+    if (CCutil_lprand() & 1) {
+        return x;
+    } else {
+        dx = CCbigguy_bigguytod(x);
+        y = CCbigguy_ZERO;
+        CCbigguy_sub (&y, x);
+        *delta += fabs(dx + CCbigguy_bigguytod(y));
+        return y;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static short shortrand (short maxs)
+#else
+static short shortrand (maxs)
+short maxs;
+#endif
+{
+    int s = CCutil_lprand() % maxs;
+
+    if (CCutil_lprand() % 1) s = -s;
+
+    return (short) s;
+}
diff --git a/contrib/blossom/concorde97/BIGGUY/bigguy.c b/contrib/blossom/concorde97/BIGGUY/bigguy.c
new file mode 100644
index 0000000000000000000000000000000000000000..445190746e39289e2801ae2a97f410c2c3cadd32
--- /dev/null
+++ b/contrib/blossom/concorde97/BIGGUY/bigguy.c
@@ -0,0 +1,375 @@
+/**************************************************************************/
+/*                                                                        */
+/*  BIGGUY OPERATIONS:                                                    */
+/*                                                                        */
+/*  x += y                  CCbigguy_add (CCbigguy *x, CCbigguy y)        */
+/*  x -= y                  CCbigguy_sub (CCbigguy *x, CCbigguy y)        */
+/*  x += y*m                CCbigguy_addmult (CCbigguy *x, CCbigguy y,    */
+/*                                            short m)                    */
+/*  x<y -1, x==y 0, x>y 1   CCbigguy_cmp (CCbigguy x, CCbigguy y)         */
+/*  ceil(x)                 CCbigguy_ceil (CCbigguy x)                    */
+/*                                                                        */
+/*  (double) x              CCbigguy_bigguytod (CCbigguy x)               */
+/*  (bigguy) i              CCbigguy_itobigguy (int i)                    */
+/*  (bigguy) d              CCbigguy_dtobigguy (double d)                 */
+/*                                                                        */
+/*  read(x)                 CCbigguy_sread (CC_SFILE *f, CCbigguy *x)     */
+/*  write(x)                CCbigguy_swrite (CC_SFILE *f, CCbigguy x)     */
+/*                                                                        */
+/*  biggest possible x      const CCbigguy CCbigguy_MAXBIGGUY             */
+/*  smallest possible x     const CCbigguy CCbigguy_MINBIGGUY             */
+/*  0                       const CCbigguy CCbigguy_ZERO                  */
+/*  1                       const CCbigguy CCbigguy_ONE                   */
+/*                                                                        */
+/*                                                                        */
+/*  EXPORTED FUNCTIONS:                                                   */
+/*                                                                        */
+/*      int                                                               */
+/*          CCbigguy_swrite (CC_SFILE *f, CCbigguy x)                     */
+/*          CCbigguy_sread (CC_SFILE *f, CCbigguy *x)                     */
+/*                                                                        */
+/*  If  CC_BIGGUY_LONGLONG is not defined                                 */
+/*                                                                        */
+/*      void                                                              */
+/*          CCbigguy_addmult (CCbigguy *x, CCbigguy y, short m)           */
+/*                                                                        */
+/*      int                                                               */
+/*          CCbigguy_cmp (CCbigguy x, CCbigguy y)                         */
+/*                                                                        */
+/*      double                                                            */
+/*          CCbigguytod (CCbigguy x)                                      */
+/*                                                                        */
+/*      CCbigguy                                                          */
+/*          CCbigguy_itobigguy (int d)                                    */
+/*          CCbigguy_dtobigguy (double d)                                 */
+/*          CCbigguy_ceil (CCbigguy x)                                    */
+/*                                                                        */
+/*  If an overflow occurs (in CCbigguy_dtobigguy, CCbigguy_ceil, or       */
+/*  CCbigguy_addmult), an error message is output and the routines        */
+/*  abort.                                                                */
+/*                                                                        */
+/*  If  CC_BIGGUY_LONGLONG is defined, these are implemented by macros,   */
+/*  and have no overflow checking.                                        */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "bigguy.h"
+
+#ifdef  CC_BIGGUY_LONGLONG
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCbigguy_swrite (CC_SFILE *f, CCbigguy x)
+#else
+int CCbigguy_swrite(f, x)
+CC_SFILE *f;
+CCbigguy x;
+#endif
+{
+    if (CCutil_swrite_short (f, (x>>48)&0xffff)) return -1;
+    if (CCutil_swrite_short (f, (x>>32)&0xffff)) return -1;
+    if (CCutil_swrite_short (f, (x>>16)&0xffff)) return -1;
+    if (CCutil_swrite_short (f, x&0xffff)) return -1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCbigguy_sread (CC_SFILE *f, CCbigguy *x)
+#else
+int CCbigguy_sread (f, x)
+CC_SFILE *f;
+CCbigguy *x;
+#endif
+{
+    unsigned short y;
+
+    if (CCutil_sread_short (f, &y)) return -1;
+    *x = ((CCbigguy) y) << 48;
+    if (CCutil_sread_short (f, &y)) return -1;
+    *x |= ((CCbigguy) y) << 32;
+    if (CCutil_sread_short (f, &y)) return -1;
+    *x |= ((CCbigguy) y) << 16;
+    if (CCutil_sread_short (f, &y)) return -1;
+    *x |= ((CCbigguy) y);
+    return 0;
+}
+
+#else  /* CC_BIGGUY_LONGLONG */
+
+const CCbigguy CCbigguy_MINBIGGUY = {0x8000,0x0000,0x0000,0x0001};
+const CCbigguy CCbigguy_MAXBIGGUY = {0x7fff,0xffff,0xffff,0xffff};
+const CCbigguy CCbigguy_ZERO = {0,0,0,0};
+const CCbigguy CCbigguy_ONE  = {0,1,0,0};
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    bigguy_neg (CCbigguy *x);
+
+#else
+
+static void
+    bigguy_neg ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static void bigguy_neg (CCbigguy *x)
+#else
+static void bigguy_neg (x)
+CCbigguy *x;
+#endif
+{
+    x->ihi = ((unsigned short) 65535) - x->ihi;
+    x->ilo = ((unsigned short) 65535) - x->ilo;
+    x->fhi = ((unsigned short) 65535) - x->fhi;
+    x->flo = ((unsigned short) 65535) - x->flo;
+
+    if (x->flo < 65535) {
+        x->flo++;
+    } else {
+        x->flo = 0;
+        if (x->fhi < 65535) {
+            x->fhi++;
+        } else {
+            x->fhi = 0;
+            if (x->ilo < 65535) {
+                x->ilo++;
+            } else {
+                x->ilo = 0;
+                x->ihi++;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCbigguy_swrite (CC_SFILE *f, CCbigguy x)
+#else
+int CCbigguy_swrite (f, x)
+CC_SFILE *f;
+CCbigguy x;
+#endif
+{
+    if (CCutil_swrite_short (f, x.ihi)) return -1;
+    if (CCutil_swrite_short (f, x.ilo)) return -1;
+    if (CCutil_swrite_short (f, x.fhi)) return -1;
+    if (CCutil_swrite_short (f, x.flo)) return -1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCbigguy_sread (CC_SFILE *f, CCbigguy *x)
+#else
+int CCbigguy_sread (f, x)
+CC_SFILE *f;
+CCbigguy *x;
+#endif
+{
+    if (CCutil_sread_short (f, &(x->ihi))) return -1;
+    if (CCutil_sread_short (f, &(x->ilo))) return -1;
+    if (CCutil_sread_short (f, &(x->fhi))) return -1;
+    if (CCutil_sread_short (f, &(x->flo))) return -1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+double CCbigguy_bigguytod (CCbigguy x)
+#else
+double CCbigguy_bigguytod (x)
+CCbigguy x;
+#endif
+{
+    int sgn = 1;
+
+    if (x.ihi >= 32768) {
+        bigguy_neg (&x);
+        sgn = -1;
+    }
+    
+    return sgn * (((double) x.ihi) * 65536.0 +
+                  ((double) x.ilo) +
+                  ((double) x.fhi) / 65536.0 +
+                  ((double) x.flo) / (65536.0*65536.0));
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+CCbigguy CCbigguy_itobigguy (int d)
+#else
+CCbigguy CCbigguy_itobigguy (d)
+int d;
+#endif
+{
+    CCbigguy x;
+    int sgn;
+
+    if (d < 0) {
+        d = -d;
+        sgn = -1;
+    } else {
+        sgn = 1;
+    }
+
+    x.ihi = ((unsigned short) (d >> 16));
+    x.ilo = ((unsigned short) (d & 0xffff));
+    x.fhi = 0;
+    x.flo = 0;
+
+    if (x.ihi >= 32768) {
+/*      fprintf (stderr, "OVERFLOW in CCbigguy_itobigguy\n");
+        fprintf (stderr, "BIGGUY errors are fatal\n");
+        abort ();
+*/    }
+    
+    if (sgn == -1) {
+        bigguy_neg (&x);
+    }
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+CCbigguy CCbigguy_dtobigguy (double d)
+#else
+CCbigguy CCbigguy_dtobigguy (d)
+double d;
+#endif
+{
+    CCbigguy x;
+    int sgn;
+
+    if (d < 0.0) {
+        d = -d;
+        sgn = -1;
+    } else {
+        sgn = 1;
+    }
+
+    if (d / 65536.0 >= 32768.0) {
+/*      fprintf (stderr, "OVERFLOW in CCbigguy_dtobigguy (%.6f)\n", d * sgn);
+        fprintf (stderr, "BIGGUY errors are fatal\n");
+        abort ();
+*/    }
+    
+    x.ihi = ((unsigned short) (d / 65536.0));
+    d -= ((double) x.ihi) * 65536.0;
+    x.ilo = ((unsigned short) d);
+    d -= ((double) x.ilo);
+    x.fhi = ((unsigned short) (d * 65536.0));
+    d -= ((double) x.fhi) / 65536.0;
+    x.flo = ((unsigned short) (d * 65536.0 * 65536.0));
+
+    if (sgn == -1) {
+        bigguy_neg (&x);
+    }
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+CCbigguy CCbigguy_ceil (CCbigguy x)
+#else
+CCbigguy CCbigguy_ceil (x)
+CCbigguy x;
+#endif
+{
+    if (x.fhi || x.flo) {
+        x.fhi = 0;
+        x.flo = 0;
+        x.ilo++;
+        if (x.ilo == 0) {
+            if (x.ihi == 32767) {
+/*              fprintf (stderr, "OVERFLOW in CCbigguy_ceil\n");
+                fprintf (stderr, "BIGGUY errors are fatal\n");
+                abort ();
+*/          }
+            x.ihi++;
+        }
+    }
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCbigguy_cmp (CCbigguy x, CCbigguy y)
+#else
+int CCbigguy_cmp (x, y)
+CCbigguy x;
+CCbigguy y;
+#endif
+{
+    if (x.ihi >= 32768 && y.ihi < 32768) return -1;
+    else if (x.ihi < 32768 && y.ihi >= 32768) return 1;
+    else if (x.ihi < y.ihi) return -1;
+    else if (x.ihi > y.ihi) return 1;
+    else if (x.ilo < y.ilo) return -1;
+    else if (x.ilo > y.ilo) return 1;
+    else if (x.fhi < y.fhi) return -1;
+    else if (x.fhi > y.fhi) return 1;
+    else if (x.flo < y.flo) return -1;
+    else if (x.flo > y.flo) return 1;
+    else return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCbigguy_addmult (CCbigguy *x, CCbigguy y, short m)
+#else
+void CCbigguy_addmult (x, y, m)
+CCbigguy *x;
+CCbigguy y;
+short m;
+#endif
+{
+    int carry = 0;
+    int sgn = 1;
+
+    if (m == -32768) {
+/*      fprintf (stderr, "OVERFLOW in CCbigguy_addmult\n");
+        fprintf (stderr, "BIGGUY errors are fatal\n");
+        abort ();
+*/    }
+    
+    if (y.ihi >= 32768) {
+        bigguy_neg (&y);
+        m = -m;
+    }
+
+    if (x->ihi >= 32768) {
+        bigguy_neg (x);
+        m = -m;
+        sgn = -1;
+    }
+
+    carry = x->flo + m * y.flo;
+    x->flo = carry & ((unsigned short) 0xffff);
+    carry -= x->flo;
+    carry /= 65536;
+    carry = carry + x->fhi + m * y.fhi;
+    x->fhi = carry & ((unsigned short) 0xffff);
+    carry -= x->fhi;
+    carry /= 65536;
+    carry = carry + x->ilo + m * y.ilo;
+    x->ilo = carry & ((unsigned short) 0xffff);
+    carry -= x->ilo;
+    carry /= 65536;
+    carry = carry + x->ihi + m * y.ihi;
+    x->ihi = carry & ((unsigned short) 0xffff);
+    carry -= x->ihi;
+    carry /= 65536;
+
+    if (carry < -1 || carry > 0 ||
+        (carry == -1 && x->ihi < 32768) ||
+        (carry == 0 && x->ihi >= 32768)) {
+/*      fprintf (stderr, "OVERFLOW in CCbigguy_addmult\n");
+        fprintf (stderr, "BIGGUY errors are fatal\n");
+        abort ();
+*/    }
+
+    if (sgn == -1) {
+        bigguy_neg (x);
+    }
+}
+
+#endif /* CC_BIGGUY_LONGLONG */
diff --git a/contrib/blossom/concorde97/BIGGUY/bigguy.tst b/contrib/blossom/concorde97/BIGGUY/bigguy.tst
new file mode 100644
index 0000000000000000000000000000000000000000..d0765488bc43591efc21fcc54434c696703c6d61
Binary files /dev/null and b/contrib/blossom/concorde97/BIGGUY/bigguy.tst differ
diff --git a/contrib/blossom/concorde97/CUT/Makefile b/contrib/blossom/concorde97/CUT/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b85301465e81862965eac083d090d6838532ddc3
--- /dev/null
+++ b/contrib/blossom/concorde97/CUT/Makefile
@@ -0,0 +1,34 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=cut.a
+LIBSRCS=segments.c connect.c  shrink.c mincut.c cut_st.c
+ALLSRCS=mc_main.c  $(LIBSRCS)
+LIBS=$(ROOT)/UTIL/util.a
+
+all: mincut $(LIB)
+
+mincut: mc_main.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ -lm
+
+clean:
+	-rm -f *.$o $(LIB) mincut
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+connect.$o:  connect.c  $(I)/machdefs.h $(I)/util.h     $(I)/cut.h      
+cut_st.$o:   cut_st.c   $(I)/machdefs.h $(I)/util.h     $(I)/cut.h      
+mc_main.$o:  mc_main.c  $(I)/machdefs.h $(I)/util.h     $(I)/cut.h      
+mincut.$o:   mincut.c   $(I)/machdefs.h $(I)/util.h     $(I)/cut.h      
+segments.$o: segments.c $(I)/machdefs.h $(I)/util.h     $(I)/cut.h      
+shrink.$o:   shrink.c   $(I)/machdefs.h $(I)/util.h     $(I)/cut.h      
diff --git a/contrib/blossom/concorde97/CUT/connect.c b/contrib/blossom/concorde97/CUT/connect.c
new file mode 100644
index 0000000000000000000000000000000000000000..26f5da432f78321d6160d62c3559d30ce173fdd0
--- /dev/null
+++ b/contrib/blossom/concorde97/CUT/connect.c
@@ -0,0 +1,278 @@
+/***************************************************************************/
+/*                                                                         */
+/*                   Cuts from Connected Components                        */
+/*                                                                         */
+/*                              TSP CODE                                   */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 17, 1997                                                */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCcut_connect_components (int ncount, int ecount, int *elist,    */
+/*            double *x, int *ncomp, int **compscount, int **comps)        */
+/*     RETURNS the connected components of the graph given by the edgeset  */
+/*      -ncount is the number of nodes                                     */
+/*      -ecount is the number of edges                                     */
+/*      -elist is the edge list in node node format                        */
+/*      -x is an vector of length ecount (it can be NULL); is it is not    */
+/*       NULL, then the connected components will be for the graph         */
+/*       consisting of the positive edges                                  */
+/*      -ncomp will return the number of connected components              */
+/*      -compscount will return the number of nodes in each of the         */
+/*       components (it will be an ncomp long array)                       */
+/*      -comps will return the nodes in the components (it will be an      */
+/*       ncount array, with the first compscount[0] elements making up     */
+/*       the first component, etc.)                                        */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "cut.h"
+
+#define CONNECT_ZERO_EPSILON (1e-10)
+
+typedef struct node {
+    int *adj;
+    int degree;
+    int mark;
+} node;
+
+typedef struct graph {
+    node *nodelist;
+    int  *adjspace;
+    int ncount;
+    int ecount;
+} graph;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    build_graph (graph *G, int ncount, int ecount, int *elist,
+                 double *x);
+
+static void
+    free_graph (graph *G),
+    connect_search (graph *G, int n, int marker, int *dstack);
+
+#else
+
+static int
+    build_graph ();
+
+static void
+    free_graph (),
+    connect_search ();
+
+#endif
+
+#ifdef  CC_PROTOTYPE_ANSI
+int CCcut_connect_components (int ncount, int ecount, int *elist, double *x,
+        int *ncomp, int **compscount, int **comps)
+#else
+int CCcut_connect_components (ncount, ecount, elist, x, ncomp, compscount,
+        comps)
+int ncount;
+int ecount;
+int *elist;
+double *x;
+int *ncomp;
+int **compscount;
+int **comps;
+#endif
+{
+    graph G;
+    int i, k, rval;
+    int *nmarks = (int *) NULL;
+    int *dstack = (int *) NULL;
+
+    G.nodelist = (node *) NULL;
+    G.adjspace = (int *) NULL;
+
+    *ncomp = 0;
+    *comps = CC_SAFE_MALLOC (ncount, int);
+    if (!(*comps)) {
+        fprintf (stderr, "out of memory in CCcut_connect_components\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = build_graph (&G, ncount, ecount, elist, x);
+    if (rval) {
+        fprintf (stderr, "build_graph failed\n");
+        goto CLEANUP;
+    }
+
+    dstack = CC_SAFE_MALLOC (ncount, int);
+    if (!dstack) {
+        fprintf (stderr, "out of memory in CCcut_connect_components\n");
+        CC_FREE (*comps, int);
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++) {
+        if (!G.nodelist[i].mark) {
+            (*ncomp)++;
+            connect_search (&G, i, *ncomp, dstack);
+        }
+    }
+
+    *compscount = CC_SAFE_MALLOC (*ncomp, int);
+    nmarks = CC_SAFE_MALLOC (*ncomp, int);
+    if (!(*compscount) || !nmarks) {
+        fprintf (stderr, "out of memory in CCcut_connect_components\n");
+        CC_FREE (*comps, int);
+        CC_IFFREE (*compscount, int);
+        CC_IFFREE (nmarks, int);
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < *ncomp; i++) {
+        nmarks[i] = 0;
+    }
+    for (i = 0; i < ncount; i++) {
+        nmarks[G.nodelist[i].mark - 1]++;
+    }
+    for (i = 0, k = 0; i < *ncomp; i++) {
+        (*compscount)[i] = nmarks[i];
+        nmarks[i] = k;
+        k += (*compscount)[i];
+    }
+    for (i = 0; i < ncount; i++) {
+        (*comps)[(nmarks[G.nodelist[i].mark - 1])++] = i;
+    }
+
+CLEANUP:
+
+    free_graph (&G);
+    CC_IFFREE (nmarks, int);
+    CC_IFFREE (dstack, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int build_graph (graph *G, int ncount, int ecount, int *elist,
+        double *x)
+#else
+static int build_graph (G, ncount, ecount, elist, x)
+graph *G;
+int ncount, ecount;
+int *elist;
+double *x;
+#endif
+{
+    int rval = 0;
+    int i;
+    int *p;
+    node *nodelist;
+
+    G->nodelist = (node *) NULL;
+    G->adjspace = (int *) NULL;
+    G->ncount = ncount;
+    if (x) {
+        G->ecount = 0;
+        for (i = 0; i < ecount; i++) {
+            if (x[i] > CONNECT_ZERO_EPSILON)
+                G->ecount++;
+        }
+    } else {
+       G->ecount = ecount;
+    }
+
+    G->nodelist = CC_SAFE_MALLOC (G->ncount, node);
+    G->adjspace = CC_SAFE_MALLOC (2*G->ecount, int);
+    if (!G->nodelist || !G->adjspace) {
+        fprintf (stderr, "out of memory in build_graph\n");
+        rval = 1; goto CLEANUP;
+    }
+    nodelist = G->nodelist;
+
+    for (i = 0; i < ncount; i++) {
+        nodelist[i].degree = 0;
+        nodelist[i].mark = 0;
+    }
+
+    if (x) {
+        for (i = 0; i < ecount; i++) {
+            if (x[i] > CONNECT_ZERO_EPSILON) {
+                nodelist[elist[2*i]].degree++;
+                nodelist[elist[2*i+1]].degree++;
+            }
+        }
+    } else {
+        for (i = 0; i < ecount; i++) {
+            nodelist[elist[2*i]].degree++;
+            nodelist[elist[2*i+1]].degree++;
+        }
+    }
+
+    p = G->adjspace;
+    for (i = 0; i < ncount; i++) {
+        nodelist[i].adj = p;
+        p += nodelist[i].degree;
+        nodelist[i].degree = 0;
+    }
+
+    if (x) {
+        for (i = 0; i < ecount; i++) {
+            if (x[i] > CONNECT_ZERO_EPSILON) {
+                nodelist[elist[2*i]].adj[nodelist[elist[2*i]].degree++]
+                                                = elist[2*i+1];
+                nodelist[elist[2*i+1]].adj[nodelist[elist[2*i+1]].degree++]
+                                                = elist[2*i];
+            }
+        }
+    } else {
+        for (i = 0; i < ecount; i++) {
+            nodelist[elist[2*i]].adj[nodelist[elist[2*i]].degree++]
+                                            = elist[2*i+1];
+            nodelist[elist[2*i+1]].adj[nodelist[elist[2*i+1]].degree++]
+                                            = elist[2*i];
+        }
+    }
+
+CLEANUP:
+
+    if (rval) {
+        CC_IFFREE (G->nodelist, node);
+        CC_IFFREE (G->adjspace, int);
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_graph (graph *G)
+#else
+static void free_graph (G)
+graph *G;
+#endif
+{
+    CC_IFFREE (G->nodelist, node);
+    CC_IFFREE (G->adjspace, int);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void connect_search (graph *G, int n, int marker, int *dstack)
+#else
+static void connect_search (G, n, marker, dstack)
+graph *G;
+int n, marker;
+int *dstack;
+#endif
+{
+    int i, k, head = 0;
+    node *nodelist = G->nodelist;
+
+    nodelist[n].mark = marker;
+    dstack[head++] = n;
+
+    while (head > 0) {
+        n = dstack[--head];
+        for (i = 0; i < nodelist[n].degree; i++) {
+            k = nodelist[n].adj[i];
+            if (!nodelist[k].mark) {
+                nodelist[k].mark = marker;
+                dstack[head++] =  k;
+            }
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/CUT/cut_st.c b/contrib/blossom/concorde97/CUT/cut_st.c
new file mode 100644
index 0000000000000000000000000000000000000000..4e45ffa0b6bd04e85a070a0f3cbac58199574805
--- /dev/null
+++ b/contrib/blossom/concorde97/CUT/cut_st.c
@@ -0,0 +1,844 @@
+/***************************************************************************/
+/*                                                                         */
+/*         MINIMUM S-T CUTS IN DIRECTED AND UNDIRECTED GRAPHS              */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: July 25, 1996                                                    */
+/*                                                                         */
+/*  An implementation of the Push-Relabel Flow Algorithm described in      */
+/*   A. Goldberg and R. Tarjan, "A new approach to the maximum-flow        */
+/*   problem",  Journal of the ACM 35 (1988) 921-940.                      */
+/*                                                                         */
+/* EXPORTED FUNCTION:                                                      */
+/*   int mincut_st (int ncount, int ecount, int *elist, double *ecap,      */
+/*           int s, int t, double *value, int **cut, int *cutcount)        */
+/*     COMPUTES the min st-cut in a directed or undirected graph.          */
+/*      -ncount is the number of nodes in the graph.                       */
+/*      -ecount is the number of directed (undirected) edges.              */
+/*      -elist gives the edges in node node format (interpreted as         */
+/*           tail head when compiled for directed graphs).                 */
+/*      -ecap gives the capacities of the edges.                           */
+/*      -s is the name of the source node.                                 */
+/*      -t is the name of the sink node.                                   */
+/*      -value returns the capacity of the minimum cut.                    */
+/*      -cut (if not NULL) returns a list of nodes in a a minimum cut (it  */
+/*       returns the side that contains t); it will be allocated to an     */
+/*       array of the appropriate size.                                    */
+/*      -cutcount returns the number of nodes in the listed cut, if cut    */
+/*       is not NULL (if cut is NULL, then cutcount can be NULL).          */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      Returns 0 if it worked and 1 otherwise (for example, when one      */
+/*      of the mallocs failed). The nodes in the graph should be named     */
+/*      0 through #nodes - 1.                                              */
+/*                                                                         */
+/*      Define UNDIRECTED_GRAPH to compile the code for undirected         */
+/*      graphs. (This appears to be the way to go for tsp instances.)      */
+/*                                                                         */
+/*      Two node selection rules are implemented: queue and highest        */
+/*      label. One of QUEUE_PRF and HIGHEST_LABEL_PRF must be defined      */
+/*      (but not both).                                                    */
+/*                                                                         */
+/*      The code can carry out global relabelings via a backwards          */
+/*      breadth-first-search from the sink. The frequency of the           */
+/*      relabelings is controlled by the defined constant                  */
+/*      GLOBAL_RELABEL_FREQUENCY. A relabling will occur after each        */
+/*      #nodes * GLOBAL_RELABEL_FREQUENCY nodes have been processed.       */
+/*      A resonable choice for the constant is 1.                          */
+/*                                                                         */
+/*      Defining USE_GAP turns on the gap heuristic of Derigs and          */
+/*      Meyer for determing nodes that can be labeled to ncount.           */
+/*      This can be used with either the queue or highest label            */
+/*      variants.                                                          */
+/*                                                                         */
+/*      To use this code for maxflows, allow nodes with labels up to       */
+/*      2*ncount to become active, or implement an algorithm to            */
+/*      decompose the preflow to create a flow.                            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "cut.h"
+
+#define UNDIRECTED_GRAPH
+
+#define HIGHEST_LABEL_PRF
+#undef  QUEUE_PRF
+
+#define USE_GAP
+#define GLOBAL_RELABEL_FREQUENCY 1.0
+
+#define INFINITY (1<<30)
+#define PRF_EPSILON 0.000000001
+#define GOING_IN  0
+#define GOING_OUT 1
+
+#ifdef QUEUE_PRF
+#define ADD_TO_ACTIVE(n) {                                                \
+    if (!(n)->active) {                                                   \
+        (n)->qnext = (node *) NULL;                                       \
+        if (qtail) {                                                      \
+            qtail->qnext = (n);                                           \
+        } else {                                                          \
+            qhead = (n);                                                  \
+        }                                                                 \
+        qtail = (n);                                                      \
+        (n)->active = 1;                                                  \
+    }                                                                     \
+}
+#endif
+
+#ifdef HIGHEST_LABEL_PRF
+#define ADD_TO_ACTIVE(n) {                                                \
+    if (!(n)->active) {                                                   \
+        (n)->highnext = high[(n)->flowlabel];                             \
+        high[(n)->flowlabel] = (n);                                       \
+        if (G->highest < (n)->flowlabel)                                  \
+            G->highest = (n)->flowlabel;                                  \
+        (n)->active = 1;                                                  \
+    }                                                                     \
+}
+#endif
+
+#ifdef UNDIRECTED_GRAPH
+#define RELABEL_BODY(n)                                                   \
+    for (rele = (n)->out; rele; rele = rele->outnext) {                   \
+        if (rele->cap - rele->flow > PRF_EPSILON &&                       \
+                (relt = rele->ends[1]->flowlabel) < relm)                 \
+            relm = relt;                                                  \
+    }                                                                     \
+    for (rele = (n)->in; rele; rele = rele->innext) {                     \
+        if (rele->cap + rele->flow > PRF_EPSILON &&                       \
+                 (relt = rele->ends[0]->flowlabel) < relm)                \
+            relm = relt;                                                  \
+    }                                                                     \
+    (n)->flowlabel = ++relm;
+#else
+#define RELABEL_BODY(n)                                                   \
+    for (rele = (n)->out; rele; rele = rele->outnext) {                   \
+        if (rele->cap - rele->flow > PRF_EPSILON &&                       \
+                (relt = rele->ends[1]->flowlabel) < relm)                 \
+            relm = relt;                                                  \
+    }                                                                     \
+    for (rele = (n)->in; rele; rele = rele->innext) {                     \
+        if (rele->flow > PRF_EPSILON &&                                   \
+                 (relt = rele->ends[0]->flowlabel) < relm)                \
+            relm = relt;                                                  \
+    }                                                                     \
+    (n)->flowlabel = ++relm;
+#endif
+
+#ifdef USE_GAP
+#define RELABEL(n) {                                                      \
+    int relm = INFINITY;                                                  \
+    edge *rele;                                                           \
+    int relt, relold = (n)->flowlabel;                                    \
+                                                                          \
+    RELABEL_BODY(n)                                                       \
+                                                                          \
+    if ((n)->levelprev) {                                                 \
+        (n)->levelprev->levelnext = (n)->levelnext;                       \
+    } else {                                                              \
+        level[relold] = (n)->levelnext;                                   \
+    }                                                                     \
+    if ((n)->levelnext)                                                   \
+        (n)->levelnext->levelprev = (n)->levelprev;                       \
+                                                                          \
+    if (relm < ncount) {                                                  \
+        if (level[relm]) {                                                \
+            level[relm]->levelprev = (n);                                 \
+            (n)->levelnext = level[relm];                                 \
+            (n)->levelprev = (node *) NULL;                               \
+            level[relm] = (n);                                            \
+        } else {                                                          \
+            (n)->levelprev = (node *) NULL;                               \
+            (n)->levelnext = (node *) NULL;                               \
+            level[relm] = (n);                                            \
+        }                                                                 \
+        if (!level[relold]) {                                             \
+            relold++;                                                     \
+            while (level[relold]) {                                       \
+                node *relno;                                              \
+                for (relno = level[relold]; relno;                        \
+                                            relno = relno->levelnext) {   \
+                    relno->flowlabel = ncount;                            \
+                }                                                         \
+                level[relold] = (node *) NULL;                            \
+                relold++;                                                 \
+            }                                                             \
+        }                                                                 \
+    }                                                                     \
+}
+#else
+#define RELABEL(n) {                                                      \
+    int relm = INFINITY;                                                  \
+    edge *rele;                                                           \
+    int relt;                                                             \
+                                                                          \
+    RELABEL_BODY(n)                                                       \
+}
+#endif /* USE_GAP */
+
+typedef struct edge {
+    struct node     *ends[2];
+    struct edge     *innext;
+    struct edge     *outnext;
+    double          cap;
+    double          flow;
+} edge;
+
+typedef struct node {
+    struct  node    *qnext;
+    struct  node    *tnext;
+#ifdef USE_GAP
+    struct  node    *levelnext;
+    struct  node    *levelprev;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+    struct  node    *highnext;
+#endif
+    struct  edge    *in;
+    struct  edge    *out;
+    struct  edge    *incurrent;
+    struct  edge    *outcurrent;
+    double           excess;
+    int              magiclabel;
+    int              flowlabel;
+    char             inout;
+    char             active;
+} node;
+
+typedef struct graph {
+    struct  node    *nodelist;
+    struct  edge    *edgelist;
+#ifdef USE_GAP
+    struct  node   **level;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+    struct  node   **high;
+    int              highest;
+#endif
+    int              nnodes;
+    int              nedges;
+    int              magicnum;
+} graph;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    setlabels (graph *G, node *s, node *t),
+    backwards_bfs (node *s, int K, graph *G),
+    init_graph (graph *G),
+    free_graph (graph *G);
+static int
+    grab_the_cut (graph *G, node *n, int **cut, int *cutcount),
+    buildgraph (graph *G, int ncount, int ecount, int *elist, double *gap);
+static double
+    flow (graph *G, node *s, node *t);
+
+#else
+
+static void
+    setlabels (),
+    backwards_bfs (),
+    init_graph (),
+    free_graph ();
+static int
+    grab_the_cut (),
+    buildgraph ();
+static double
+    flow ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_mincut_st (int ncount, int ecount, int *elist, double *ecap,
+        int s, int t, double *value, int **cut, int *cutcount)
+#else
+int CCcut_mincut_st (ncount, ecount, elist, ecap, s, t, value, cut, cutcount)
+int ncount, ecount, *elist;
+int s, t;
+double *ecap, *value;
+int **cut, *cutcount;
+#endif
+{
+    int rval = 0;
+    graph G;
+
+    init_graph (&G);
+
+    if (cut) {
+        *cut = (int *) NULL;
+        if (cutcount) {
+            *cutcount = 0;
+        } else {
+            fprintf (stderr, "cut is specified but not cutcount\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    rval = buildgraph (&G, ncount, ecount, elist, ecap);
+    if (rval) {
+        fprintf (stderr, "Buildgraph failed\n"); goto CLEANUP;
+    }
+    *value = flow (&G, G.nodelist + s, G.nodelist + t);
+    if (cut) {
+        rval = grab_the_cut (&G, G.nodelist + t, cut, cutcount);
+        if (rval) {
+            fprintf (stderr, "grab_the_cut failed\n"); goto CLEANUP;
+        }
+    }
+
+
+CLEANUP:
+
+    free_graph (&G);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double flow (graph *G, node *s, node *t)
+#else
+static double flow (G, s, t)
+graph *G;
+node *s, *t;
+#endif
+{
+#ifdef QUEUE_PRF
+    node *qhead = (node *) NULL;
+    node *qtail = (node *) NULL;
+#endif
+    node *n;
+    edge *e;
+    int count, round;
+    int i;
+    int ncount = G->nnodes;
+    edge *edgelist = G->edgelist;
+    node *nodelist = G->nodelist;
+#ifdef USE_GAP
+    node **level = G->level;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+    node **high = G->high;
+#endif
+
+/*
+    printf ("Find cut separating %d and %d ...\n", s - nodelist, t - nodelist);
+    fflush (stdout);
+*/
+
+    for (i = 0; i < ncount; i++) {
+        nodelist[i].excess = 0.0;
+        nodelist[i].active = 0;
+#ifdef HIGHEST_LABEL_PRF
+        high[i] = (node *) NULL;
+#endif
+    }
+#ifdef HIGHEST_LABEL_PRF
+    G->highest = 0;
+#endif
+
+    for (i = G->nedges - 1; i >= 0; i--)
+        edgelist[i].flow = 0.0;
+
+    t->active = 1;              /* a lie, which keeps s and t off the */
+    s->active = 1;              /* active int                         */
+
+    for (e = s->out; e; e = e->outnext) {
+        if (e->cap > 0.0) {
+            e->flow = e->cap;
+            e->ends[1]->excess += e->cap;
+#ifdef QUEUE_PRF
+            ADD_TO_ACTIVE(e->ends[1]);
+#endif
+#ifdef HIGHEST_LABEL_PRF
+            e->ends[1]->active = 1;
+#endif
+        }
+    }
+#ifdef UNDIRECTED_GRAPH
+    for (e = s->in; e; e = e->innext) {
+        if (e->cap > 0.0) {
+            e->flow = -e->cap;
+            e->ends[0]->excess += e->cap;
+#ifdef QUEUE_PRF
+            ADD_TO_ACTIVE(e->ends[0]);
+#endif
+#ifdef HIGHEST_LABEL_PRF
+            e->ends[0]->active = 1;
+#endif
+        }
+    }
+#endif
+
+
+    setlabels (G, s, t);
+    count = 0;
+    round = (int) (GLOBAL_RELABEL_FREQUENCY * ncount);
+
+#ifdef QUEUE_PRF
+    while (qhead) {
+        n = qhead;
+        qhead = qhead->qnext;
+        if (!qhead)
+            qtail = (node *) NULL;
+        n->active = 0;
+        if (n->flowlabel >= ncount)
+            continue;
+#endif
+
+#ifdef HIGHEST_LABEL_PRF
+    while (G->highest) {
+        n = high[G->highest];
+        n->active = 0;
+        high[G->highest] = high[G->highest]->highnext;
+        if (!high[G->highest]) {
+            G->highest--;
+            while (G->highest && (high[G->highest] == (node *) NULL))
+                G->highest--;
+        }
+#endif
+
+        if (count == round) {
+            setlabels (G, s, t);
+            if (n->flowlabel >= ncount)
+                continue;
+            count = 0;
+        } else
+            count++;
+
+        if (n->inout == GOING_IN)
+            goto DO_ME_IN;
+
+        if (n->outcurrent) {
+            while (n->excess > 0.0) {
+                e = n->outcurrent;
+                { /* PUSH OUT */
+                    double rf = e->cap - e->flow;
+                    node *n1 = e->ends[1];
+                    if (n->flowlabel == n1->flowlabel + 1 && rf > 0.0) {
+                        if (n->excess <= rf) {
+                            e->flow += n->excess;
+                            n1->excess += n->excess;
+                            n->excess = 0.0;
+                            ADD_TO_ACTIVE(n1);
+                        } else {
+                            e->flow += rf;
+                            n1->excess += rf;
+                            n->excess -= rf;
+                            ADD_TO_ACTIVE(n1);
+                            n->outcurrent = e->outnext;
+                            if (!n->outcurrent) {
+                                n->outcurrent = n->out;
+                                n->inout = GOING_IN;
+                                goto DO_ME_IN;
+                            }
+                        }
+                    } else {
+                        n->outcurrent = e->outnext;
+                        if (!n->outcurrent) {
+                            n->outcurrent = n->out;
+                            n->inout = GOING_IN;
+                            goto DO_ME_IN;
+                        }
+                    }
+                }
+            }
+        }
+DO_ME_IN:
+        if (n->incurrent) {
+            while (n->excess > 0.0) {
+                e = n->incurrent;
+                { /* PUSH IN */
+#ifdef UNDIRECTED_GRAPH
+                    double rf = e->cap + e->flow;
+#else
+                    double rf = e->flow;
+#endif
+                    node *n1 = e->ends[0];
+                    if (n->flowlabel == n1->flowlabel + 1 && rf > 0.0) {
+                        if (n->excess <= rf) {
+                            e->flow -= n->excess;
+                            n1->excess += n->excess;
+                            n->excess = 0.0;
+                            ADD_TO_ACTIVE(n1);
+                        } else {
+                            e->flow -= rf;
+                            n1->excess += rf;
+                            n->excess -= rf;
+                            ADD_TO_ACTIVE(n1);
+                            n->incurrent = e->innext;
+                            if (!n->incurrent) {
+                                n->incurrent = n->in;
+                                n->inout = GOING_OUT;
+                                RELABEL(n);
+                                break;
+                            }
+                        }
+                    } else {
+                        n->incurrent = e->innext;
+                        if (!n->incurrent) {
+                            n->incurrent = n->in;
+                            n->inout = GOING_OUT;
+                            RELABEL(n);
+                            break;
+                        }
+                    }
+                }
+            }
+        } else {
+            /* n->in is NULL */
+            n->inout = GOING_OUT;
+            RELABEL(n);
+        }
+        if (n->excess > 0.0 && n->flowlabel < ncount) {
+            ADD_TO_ACTIVE(n);
+        }
+    }
+
+    return t->excess;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void setlabels (graph *G, node *s, node *t)
+#else
+static void setlabels (G, s, t)
+graph *G;
+node *s, *t;
+#endif
+{
+    node *n;
+    int ncount = G->nnodes;
+    int num = ++(G->magicnum);
+    int i;
+    /* static int duke = 0; */
+
+    t->flowlabel = 0;
+    backwards_bfs (t, num, G);
+    if (s->magiclabel == num) {
+        printf ("Help - s should not get a label\n");
+        s->flowlabel = ncount;
+    }
+
+    for (i = G->nnodes, n = G->nodelist; i;  i--, n++) {
+        n->outcurrent = n->out;
+        n->incurrent = n->in;
+        n->inout = GOING_OUT;
+        if (n->magiclabel != num) {
+            n->flowlabel = ncount;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void backwards_bfs (node *s, int K, graph *G)
+#else
+static void backwards_bfs (s, K, G)
+node *s;
+int K;
+graph *G;
+#endif
+{
+    node *this, *next, *tail;
+    edge *e;
+    int  dist;
+#ifdef USE_GAP
+    node dummy;
+    node **level = G->level;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+    node **high = G->high;
+#endif
+
+    s->magiclabel = K;
+    next = s;
+    s->tnext = (node *) NULL;
+    dist = s->flowlabel;
+
+#ifdef USE_GAP
+    {
+        int i;
+        for (i = 0; level[i]; i++)
+            level[i] = (node *) NULL;
+        level[dist] = s;
+        s->levelnext = (node *) NULL;
+    }
+#endif
+#ifdef HIGHEST_LABEL_PRF
+    {
+        int i;
+        for (i = 0; i <= G->highest; i++)
+            high[i] = (node *) NULL;
+        G->highest = 0;
+    }
+#endif
+
+    do {
+#ifdef USE_GAP
+        level[dist]->levelprev = (node *) NULL;
+        level[dist + 1] = &dummy;
+        dummy.levelprev = (node *) NULL;
+#endif
+        dist++;
+        for (this = next, next = (node *) NULL; this; this = this->tnext) {
+            for (e = this->out; e; e = e->outnext) {
+                tail = e->ends[1];
+#ifdef UNDIRECTED_GRAPH
+                if (tail->magiclabel != K && e->cap + e->flow > 0.0) {
+#else
+                if (tail->magiclabel != K && e->flow > 0.0) {
+#endif
+                    tail->flowlabel = dist;
+                    tail->tnext = next;
+                    next = tail;
+                    tail->magiclabel = K;
+#ifdef USE_GAP
+                    tail->levelnext = level[dist];
+                    level[dist]->levelprev = tail;
+                    level[dist] = tail;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+                    if (tail->active) {
+                        tail->highnext = high[dist];
+                        high[dist] = tail;
+                    }
+#endif
+                }
+            }
+            for (e = this->in; e; e = e->innext) {
+                tail = e->ends[0];
+                if (tail->magiclabel != K && e->cap - e->flow > 0.0) {
+                    tail->flowlabel = dist;
+                    tail->tnext = next;
+                    next = tail;
+                    tail->magiclabel = K;
+#ifdef USE_GAP
+                    tail->levelnext = level[dist];
+                    level[dist]->levelprev = tail;
+                    level[dist] = tail;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+                    if (tail->active) {
+                        tail->highnext = high[dist];
+                        high[dist] = tail;
+                    }
+#endif
+                }
+            }
+        }
+#ifdef USE_GAP
+        if (dummy.levelprev) {
+            dummy.levelprev->levelnext = (node *) NULL;
+            level[dist]->levelprev = (node *) NULL;
+        } else {
+            level[dist] = (node *) NULL;
+        }
+#endif
+#ifdef HIGHEST_LABEL_PRF
+        if (high[dist])
+            G->highest = dist;
+#endif
+    } while (next);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grab_the_cut (graph *G, node *n, int **cut, int *cutcount)
+#else
+static int grab_the_cut (G, n, cut, cutcount)
+graph *G;
+node *n;
+int **cut;
+int *cutcount;
+#endif
+{
+    int rval = 0;
+    edge *e;
+    node *q, *top;
+    int count = 0;
+    int i, num;
+    node *nodelist = G->nodelist;
+    int *tcut = (int *) NULL;
+
+    *cut = (int *) NULL;
+    *cutcount = 0;
+
+    tcut = CC_SAFE_MALLOC (G->nnodes, int);
+    if (!tcut) {
+        fprintf (stderr, "out of memory in grab_the_cut\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    G->magicnum++;
+    num = G->magicnum;
+    tcut[count++] = n - nodelist;
+    q = n;
+    q->magiclabel = num;
+    q->tnext = (node *) NULL;
+
+    while (q) {
+        top = q;
+        q = q->tnext;
+        for (e = top->out; e; e = e->outnext) {
+#ifdef UNDIRECTED_GRAPH
+            if (e->cap + e->flow > 0.0 && e->ends[1]->magiclabel != num) {
+#else
+            if (e->flow > 0.0 && e->ends[1]->magiclabel != num) {
+#endif
+                tcut[count++] = e->ends[1] - nodelist;
+                e->ends[1]->magiclabel = num;
+                e->ends[1]->tnext = q;
+                q = e->ends[1];
+            }
+        }
+        for (e = top->in; e; e = e->innext) {
+            if (e->cap - e->flow > 0.0 && e->ends[0]->magiclabel != num) {
+                tcut[count++] = e->ends[0] - nodelist;
+                e->ends[0]->magiclabel = num;
+                e->ends[0]->tnext = q;
+                q = e->ends[0];
+            }
+        }
+    }
+
+    *cut = CC_SAFE_MALLOC (count, int);
+    if (!(*cut)) {
+        fprintf (stderr, "out of memory in grab_the_cut\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < count; i++) {
+        (*cut)[i] = tcut[i];
+    }
+    *cutcount = count;
+
+CLEANUP:
+
+    if (rval) {
+        CC_IFFREE (*cut, int);
+    }
+    CC_IFFREE (tcut, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int buildgraph (graph *G, int ncount, int ecount, int *elist,
+        double *ecap)
+#else
+static int buildgraph (G, ncount, ecount, elist, ecap)
+graph *G;
+int ncount, ecount, *elist;
+double *ecap;
+#endif
+{
+    int i;
+    edge *edgelist;
+    node *nodelist;
+
+    G->nodelist = (node *) NULL;
+    G->edgelist = (edge *) NULL;
+#ifdef USE_GAP
+    G->level = (node **) NULL;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+    G->high = (node **) NULL;
+#endif
+
+    G->magicnum = 0;
+    G->nnodes = ncount;
+    G->nedges = ecount;
+    G->nodelist = CC_SAFE_MALLOC (ncount, node);
+    G->edgelist = CC_SAFE_MALLOC (ecount, edge);
+    if (!G->nodelist || !G->edgelist) {
+        fprintf (stderr, "Out of memory in buildgraph\n");
+        CC_IFFREE (G->nodelist, node);
+        CC_IFFREE (G->edgelist, edge);
+        return 1;
+    }
+#ifdef USE_GAP
+    G->level = CC_SAFE_MALLOC (ncount + 1, node *);
+    if (!G->level) {
+        fprintf (stderr, "Out of memory in buildgraph\n");
+        CC_IFFREE (G->nodelist, node);
+        CC_IFFREE (G->edgelist, edge);
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        G->level[i] = (node *) NULL;
+    G->level[ncount] = (node *) NULL;  /* A guard dog for a while loop */
+#endif
+
+#ifdef HIGHEST_LABEL_PRF
+    G->high = CC_SAFE_MALLOC (ncount, node *);
+    if (!G->high) {
+        fprintf (stderr, "Out of memory in buildgraph\n");
+        CC_IFFREE (G->nodelist, node);
+        CC_IFFREE (G->edgelist, edge);
+        return 1;
+    }
+#endif
+
+    nodelist = G->nodelist;
+    edgelist = G->edgelist;
+
+    for (i = 0; i < ncount; i++) {
+        nodelist[i].in = (edge *) NULL;
+        nodelist[i].out = (edge *) NULL;
+        nodelist[i].magiclabel = 0;
+    }
+
+    for (i = 0; i < ecount; i++) {
+        int tail = elist[2 * i];
+        int head = elist[(2 * i) + 1];
+        if (tail < 0 || tail >= ncount ||
+            head < 0 || head >= ncount) {
+            fprintf (stderr, "Edge list in wrong format: Edge %d = [%d, %d]\n",
+                         i, tail, head);
+            return 1;
+        }
+        edgelist[i].ends[0] = nodelist + tail;
+        edgelist[i].ends[1] = nodelist + head;
+        edgelist[i].cap = ecap[i];
+        edgelist[i].outnext = nodelist[tail].out;
+        nodelist[tail].out = &(edgelist[i]);
+        edgelist[i].innext = nodelist[head].in;
+        nodelist[head].in = &(edgelist[i]);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void init_graph (graph *G)
+#else
+static void init_graph (G)
+graph *G;
+#endif
+{
+    if (G) {
+        G->nodelist = (node *) NULL;
+        G->edgelist = (edge *) NULL;
+#ifdef USE_GAP
+        G->level = (node **) NULL;
+#endif
+#ifdef HIGHEST_LABEL_PRF
+        G->high = (node **) NULL;
+#endif
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_graph (graph *G)
+#else
+static void free_graph (G)
+graph *G;
+#endif
+{
+    CC_IFFREE (G->nodelist, node);
+    CC_IFFREE (G->edgelist, edge);
+#ifdef USE_GAP
+    CC_IFFREE (G->level, node *);
+#endif
+#ifdef HIGHEST_LABEL_PRF
+    CC_IFFREE (G->high, node *);
+#endif
+}
diff --git a/contrib/blossom/concorde97/CUT/mc_main.c b/contrib/blossom/concorde97/CUT/mc_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..f9c6f5c342673eb973e1b23fdcb496e8f48770ab
--- /dev/null
+++ b/contrib/blossom/concorde97/CUT/mc_main.c
@@ -0,0 +1,423 @@
+/************************************************************************/
+/*                                                                      */
+/*        Demo of Min-Cutw for Directed and Undirected Graphs           */
+/*                                                                      */
+/*  Written by:  Applegate, Bixby, Chvatal,  and Cook                   */
+/*  Date: September, 1994 (Bonn)                                        */
+/*        July 28, 1997 (bico)                                          */
+/*                                                                      */
+/************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "cut.h"
+
+#undef  USE_DIRECTED_GRAPH
+
+static int source = -1, sink = -1;
+static int showcut = 0;
+static int violatedcuts = 0;
+static int use_shrink = 1;
+static int find_global = 0;
+static int binary_in = 0;
+static char *fname = (char *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+
+static void
+    usage (char *f),
+    display_cut (int *cut, int count);
+
+static int
+    parseargs (int ac, char **av),
+    shrink_ones (int ncount, int ecount, int *elist, double *dlen,
+        int *oncount, int *oecount, int **olist, double **olen,
+        double *minval),
+    display_all_cuts (double val, int cnt, int *cut, void *pass_param);
+
+#else
+
+int
+    main ();
+
+static void
+    usage (),
+    display_cut ();
+
+static int
+    parseargs (),
+    shrink_ones (),
+    display_all_cuts ();
+
+#endif
+
+#ifdef USE_DIRECTED_GRAPH
+#ifdef CC_PROTOTYPE_ANSI
+static int
+    duplicate_edges (int ncount, int ecount, int *elist, double *ecap,
+        int **tlist, double **tcap);
+#else
+    duplicate_edges ();
+#endif
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int rval = 0;
+    double val;
+    double szeit;
+    int i, cutcount;
+    int ncount, ecount;
+    int *elist = (int *) NULL;
+    int *cut   = (int *) NULL;
+    int **mycut = (int **) NULL;
+    double *ecap = (double *) NULL;
+
+    if (parseargs (ac, av)) goto CLEANUP;
+
+    if (find_global && violatedcuts) {
+        fprintf (stderr, "use at most one of -p and -c arguments\n");
+        goto CLEANUP;
+    }
+
+#ifdef USE_DIRECTED
+    if (find_global || violatedcuts) {
+        fprintf (stderr, "not set up for global cut in directed graphs\n");
+        goto CLEANUP;
+    }
+#endif
+
+
+    rval = CCutil_getedges_double (&ncount, fname, &ecount, &elist, &ecap,
+                                   binary_in);
+    if (rval) {
+        fprintf (stderr, "getedges_double failed\n"); goto CLEANUP;
+    }
+
+    if (showcut) {
+        mycut = &cut;
+    } else {
+        mycut = (int **) NULL;
+    }
+
+    if (find_global) {
+        szeit = CCutil_zeit ();
+        rval = CCcut_mincut (ncount, ecount, elist, ecap, &val, mycut,
+                            &cutcount);
+        if (rval) {
+            fprintf (stderr, "CCcut_mincut failed\n"); goto CLEANUP;
+        }
+        printf ("Minimum Cut Value: %f (%.2f seconds)\n", val, CCutil_zeit () - szeit);
+        fflush (stdout);
+        if (showcut) display_cut (cut, cutcount);
+        goto CLEANUP;
+    } else if (violatedcuts) {
+        szeit = CCutil_zeit ();
+        rval = CCcut_violated_cuts (ncount, ecount, elist, ecap,
+                2.0 - CC_MINCUT_ONE_EPSILON, display_all_cuts, (void *) NULL);
+        if (rval) {
+            fprintf (stderr, "CCcut_violated_cuts failed\n");
+            goto CLEANUP;
+        }
+        printf ("Running time: %.2f seconds\n", CCutil_zeit () - szeit);
+        goto CLEANUP;
+    }
+
+    szeit = CCutil_zeit ();
+    if (use_shrink) {
+        int tncount, tecount;
+        int *telist = (int *) NULL;
+        double *tecap = (double *) NULL;
+        double minval = CC_MINCUT_BIGDOUBLE;
+        double sszeit = CCutil_zeit ();
+
+        rval = shrink_ones (ncount, ecount, elist, ecap, &tncount, &tecount,
+                            &telist, &tecap, &minval);
+        if (rval) {
+            fprintf (stderr, "shrink_ones failed\n"); goto CLEANUP;
+        }
+        printf ("Shrunk graph has %d nodes and %d edges\n", tncount, tecount);
+        if (minval != CC_MINCUT_BIGDOUBLE) {
+            printf ("Shrinking found cut of value %f\n", minval);
+        }
+        fflush (stdout);
+        printf ("Time for shrinking: %.2f seconds\n", CCutil_zeit () - sszeit);
+        fflush (stdout);
+        CC_IFFREE(elist, int);
+        CC_IFFREE(ecap, double);
+        ncount = tncount;
+        ecount = tecount;
+        elist = telist;
+        ecap = tecap;
+    }
+
+#ifdef USE_DIRECTED_GRAPH
+    {
+        int tncount, tecount;
+        int *telist = (int *) NULL;
+        double *tecap = (double *) NULL;
+
+        rval = duplicate_edges (ncount, ecount, elist, ecap, &telist, &tecap);
+        if (rval) {
+            fprintf (stderr, "duplicated_edges failed\n"); goto CLEANUP;
+        }
+        CC_IFFREE(elist, int);
+        CC_IFFREE(ecap, double);
+        ecount *= 2;
+        elist = telist;
+        ecap = tecap;
+    }
+#endif
+
+
+    if (source == -1)
+        source = 0;
+
+    if (sink != -1) {
+        if (source < 0 || sink < 0 || source >= ncount ||
+            sink >= ncount || source == sink) {
+            printf ("Bad source sink pair\n");
+            fflush (stdout);
+            goto CLEANUP;
+        }
+
+        szeit = CCutil_zeit ();
+        rval = CCcut_mincut_st (ncount, ecount, elist, ecap, source, sink,
+                            &val, mycut, &cutcount);
+        if (rval) {
+           fprintf (stderr, "mincut_st failed\n"); goto CLEANUP;
+        }
+        printf ("Cut value: %f\n", val);
+        printf ("Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+        fflush (stdout);
+
+        if (showcut) display_cut (cut, cutcount);
+    } else {
+        double minval = CC_MINCUT_BIGDOUBLE;
+        double fzeit = CCutil_zeit ();
+
+        printf ("compute all cuts from source node %d\n", source);
+        fflush (stdout);
+        for (i = 0; i < ncount; i++) {
+            if (i != source) {
+                rval = CCcut_mincut_st (ncount, ecount, elist, ecap, source, i,
+                                        &val, (int **) NULL, (int *) NULL);
+                if (rval) {
+                    fprintf (stderr, "mincut_digraph failed\n"); goto CLEANUP;
+                }
+                if (val < minval)
+                    minval = val;
+                printf ("."); fflush (stdout);
+                if (i % 75 == 0)
+                    printf ("%d\n", i);
+            }
+        }
+        printf ("\nMinimum Cut Value: %f\n", minval);
+        printf ("Running Time: %.2f (seconds)\n", CCutil_zeit () - fzeit);
+        fflush (stdout);
+    }
+
+    printf ("Total Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (elist, int);
+    CC_IFFREE (ecap, double);
+    CC_IFFREE (cut, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "bcCps:St:")) != EOF)
+        switch (c) {
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'c':
+            violatedcuts = 1;
+            break;
+        case 'C':
+            showcut++;
+            break;
+        case 'p':
+            find_global = 1;
+            break;
+        case 's':
+            source = atoi (CCutil_bix_optarg);
+            break;
+        case 'S':
+            use_shrink = 0;
+            break;
+        case 't':
+            sink = atoi (CCutil_bix_optarg);
+            break;
+        case '?':
+        default:
+            usage (av[0]);
+            return 1;
+        }
+    if (CCutil_bix_optind >= ac) {
+        usage (av[0]);
+        return 1;
+    }
+
+    fname = av[CCutil_bix_optind++];
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "usage: %s [- below -] edge_file\n", f);
+    fprintf (stderr, "    b:   binary input file\n");
+    fprintf (stderr, "    c:   display all cuts < 2.0\n");
+    fprintf (stderr, "    p:   use Padberg-Rinaldi style shrinking\n");
+    fprintf (stderr, "    s #: source\n");
+    fprintf (stderr, "    t #: sink\n");
+    fprintf (stderr, "    S:   do not use the TSP shrink routines\n");
+    fprintf (stderr, "    C:   display the min cut\n");
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void display_cut (int *cut, int count)
+#else
+static void display_cut (cut, count)
+int *cut;
+int count;
+#endif
+{
+    int i;
+
+    printf ("MIN CUT:\n");
+    for (i = 0; i < count; i++) {
+        printf ("%3d ", cut[i]);
+        if (i % 10 == 9)
+            printf ("\n");
+    }
+    if (i % 10) printf ("\n");
+    fflush (stdout);
+}
+
+#ifdef USE_DIRECTED_GRAPH
+#ifdef CC_PROTOTYPE_ANSI
+static int duplicate_edges (int ncount, int ecount, int *elist, double *ecap,
+        int **tlist, double **tcap)
+#else
+static int duplicate_edges (ncount, ecount, elist, ecap, tlist, tcap)
+int ncount, ecount;
+int *elist;
+double *ecap;
+int **tlist;
+double **tcap;
+#endif
+{
+    int i;
+
+    *tlist = (int *) NULL;
+    *tcap = (double *) NULL;
+
+
+    /* Convert the graph to a digraph */
+
+    *tlist = CC_SAFE_MALLOC (4 * ecount, int);
+    *tcap  = CC_SAFE_MALLOC (2 * ecount, double);
+    if (!*tlist || !*tcap) {
+        fprintf (stderr, "Out of memory in duplicate_edges\n");
+        CC_IFFREE (*tlist, int);
+        CC_IFFREE (*tcap, double);
+        return 1;
+    }
+
+    for (i = 0; i < ecount; i++) {
+        (*tlist)[4 * i] = (*tlist)[4 * i + 3] = elist[2 * i];
+        (*tlist)[4 * i + 1] = (*tlist)[4 * i + 2] = elist[2 * i + 1];
+        (*tcap)[2 * i] = (*tcap)[2 * i + 1] = ecap[i];
+    }
+
+    return 0;
+}
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int shrink_ones (int ncount, int ecount, int *elist, double *dlen,
+        int *oncount, int *oecount, int **olist, double **olen, double *minval)
+#else
+static int shrink_ones (ncount, ecount, elist, dlen, oncount, oecount, olist,
+        olen, minval)
+int ncount, ecount;
+int *elist;
+double *dlen;
+int *oncount, *oecount;
+int **olist;
+double **olen;
+double *minval;
+#endif
+{
+    int rval = 0;
+    CC_SRKgraph G;
+
+    CCcut_SRK_init_graph (&G);
+    rval = CCcut_SRK_buildgraph (&G, ncount, ecount, elist, dlen);
+    if (rval) {
+        fprintf (stderr, "buildgraph failed in shrink_ones\n"); goto CLEANUP;
+    }
+    CCcut_SRK_subtour_shrink (&G, minval, CC_MINCUT_ONE_EPSILON,
+                        (CC_SRKcallback *) NULL, (int **) NULL, (int *) NULL);
+
+    rval = CCcut_SRK_grab_edges (&G, oncount, oecount, olist, olen,
+                          (CC_SRKexpinfo *) NULL);
+    if (rval) {
+        fprintf (stderr, "grab edges failed in shrink_ones\n"); goto CLEANUP;
+    }
+
+
+CLEANUP:
+
+    CCcut_SRK_free_graph (&G);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int display_all_cuts (double val, int cnt, int *cut, void *pass_param)
+#else
+static int display_all_cuts (val, cnt, cut, pass_param)
+double val;
+int cnt;
+int *cut;
+void *pass_param;
+#endif
+{
+    if (pass_param) {
+        fprintf (stderr, "don't know about pass_param in display_all_cuts\n");
+        return 1;
+    }
+
+    if (cut && cnt) {
+        printf ("Found cut of value %f\n", val); fflush (stdout);
+    }
+    return 0;
+}
diff --git a/contrib/blossom/concorde97/CUT/mincut.c b/contrib/blossom/concorde97/CUT/mincut.c
new file mode 100644
index 0000000000000000000000000000000000000000..41b9d6c4ce259d7f78d3235887265a09c716de27
--- /dev/null
+++ b/contrib/blossom/concorde97/CUT/mincut.c
@@ -0,0 +1,360 @@
+/***************************************************************************/
+/*                                                                         */
+/*             GLOBAL MIN-CUT USING PADBERG-RINALDI SHRINKING              */
+/*                                                                         */
+/*                                TSP CODE                                 */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: July 24, 1997                                                    */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*                                                                         */
+/*    int CCcut_mincut (int ncount, int ecount, int *elist, double *dlen,  */
+/*           double *cutval, int **cut, int *cutcount)                     */
+/*     COMPUTES the global minimum cut in an undirected graph.             */
+/*      -ncount is the number of nodes in the graph.                       */
+/*      -ecount is the number of edges in the graph.                       */
+/*      -elist is the list of edges in end0 end1 format                    */
+/*      -dlen is a list of the edge capacities                             */
+/*      -cutval returns the capacity of the mincut (it can be NULL).       */
+/*      -cut will return the indices of the nodes in the minimum cut;      */
+/*       this variable can be passed in as NULL, otherwise it will be      */
+/*       an allocated to an array of the appropriate length.               */
+/*      -cutcount will return the number of nodes in the minimum cut if    */
+/*       cut is not NULL (if cut is NULL, then cutcount can be NULL).      */
+/*    NOTE: This function assumes graph is connected. Paths of 1's are     */
+/*     are shrunk - this is valid for the tsp, but not in general.         */
+/*                                                                         */
+/*   int CCcut_violated_cuts (int ncount, int ecount, int *elist,          */
+/*           double *dlen, double cutoff, int (*doit_fn) (double, int,     */
+/*           int *, void *), void *pass_param)                             */
+/*    COMPUTES the global minimum cut, but calls the doit_fn function for  */
+/*     cut the algorithm encounters that has capacity at most cutoff.      */
+/*     -doit_fn (if not NULL) will be called for each cut having capacity  */
+/*       less than or equal to the cutoff value; the arguments will be the */
+/*       value of the cut, the number of nodes in the cut, the array of    */
+/*       the members of the cut, and pass_param.                           */
+/*     -pass_param will be passed to doit_fn; it can be NULL or it can be  */
+/*       used to pass information to the doit_fn function.                 */
+/*    NOTE: This function assumes graph is connected.                      */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/*    This code works with undirected graphs. The shrinking routines       */
+/*    assume that we are working with the TSP and not interested in cuts   */
+/*    of weight 2.0 or more.                                               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "cut.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    mincut_work (int ncount, int ecount, int *elist, double *dlen,
+        double *cutval, int **cut, int *cutcount, double cutoff,
+        int (*doit_fn) (double, int, int *, void *), void *pass_param),
+    flip_the_cut (int ncount, int **cut, int *cutcount);
+
+#else
+
+static int
+    mincut_work (),
+    flip_the_cut ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_mincut (int ncount, int ecount, int *elist, double *dlen,
+        double *cutval, int **cut, int *cutcount)
+#else
+int CCcut_mincut (ncount, ecount, elist, dlen, cutval, cut, cutcount)
+int ncount, ecount;
+int *elist;
+double *dlen;
+double *cutval;
+int **cut, *cutcount;
+#endif
+{
+    int rval = 0;
+
+    rval = mincut_work (ncount, ecount, elist, dlen, cutval, cut, cutcount,
+                        0.0, NULL, (void *) NULL);
+    if (rval) {
+        fprintf (stderr, "mincut_work failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_violated_cuts (int ncount, int ecount, int *elist, double *dlen,
+        double cutoff, int (*doit_fn) (double, int, int *, void *),
+        void *pass_param)
+#else
+int CCcut_violated_cuts (ncount, ecount, elist, dlen, cutoff, doit_fn,
+        pass_param)
+int ncount, ecount;
+int *elist;
+double *dlen;
+double cutoff;
+int (*doit_fn) ();
+void *pass_param;
+#endif
+{
+    int rval = 0;
+
+    rval = mincut_work (ncount, ecount, elist, dlen, (double *) NULL,
+                  (int **) NULL, (int *) NULL, cutoff, doit_fn, pass_param);
+    if (rval) {
+        fprintf (stderr, "mincut_work failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int mincut_work (int ncount, int ecount, int *elist, double *dlen,
+        double *cutval, int **cut, int *cutcount, double cutoff,
+        int (*doit_fn) (double, int, int *, void *), void *pass_param)
+#else
+static int mincut_work (ncount, ecount, elist, dlen, cutval, cut,
+        cutcount, cutoff, doit_fn, pass_param)
+int ncount, ecount;
+int *elist;
+double *dlen;
+double *cutval;
+int **cut, *cutcount;
+double cutoff;
+int (*doit_fn) ();
+void *pass_param;
+#endif
+{
+    int rval = 0;
+    CC_SRKgraph G;
+    CC_SRKexpinfo E;
+    int i, sncount, secount;
+    int *slist = (int *) NULL;
+    double *slen = (double *) NULL;
+    double minval = CC_MINCUT_BIGDOUBLE;
+    double val;
+    CC_SRKnode *squeue = (CC_SRKnode *) NULL;
+    CC_SRKedge *f;
+    int *tcut = (int *) NULL;
+    int **mytcut = (int **) NULL;
+    int tcount = 0;
+    CC_SRKcallback *cb = (CC_SRKcallback *) NULL;
+
+    CCcut_SRK_init_graph (&G);
+    CCcut_SRK_init_expinfo (&E);
+    if (cut) {
+        *cut = (int *) NULL;
+        if (cutcount) {
+            *cutcount = 0;
+        } else {
+            fprintf (stderr, "cut specified, but not cutcount\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+    if (cut || doit_fn) {
+        mytcut = &tcut;
+    } else {
+        mytcut = (int **) NULL;
+    }
+    if (cutval) {
+        *cutval = CC_MINCUT_BIGDOUBLE;
+    }
+    if (doit_fn) {
+        cb = CC_SAFE_MALLOC (1, CC_SRKcallback);
+        if (!cb) {
+            fprintf (stderr, "out of memory in mincut_work\n");
+            rval = 1; goto CLEANUP;
+        }
+        cb->cutoff     = cutoff;
+        cb->pass_param = pass_param;
+        cb->doit_fn    = doit_fn;
+    }
+
+    rval = CCcut_SRK_buildgraph (&G, ncount, ecount, elist, dlen);
+    if (rval) {
+        fprintf (stderr, "buildgraph failed in shrink_ones\n"); goto CLEANUP;
+    }
+    rval = CCcut_SRK_subtour_shrink (&G, &minval, CC_MINCUT_ONE_EPSILON,
+                               cb, cut, cutcount);
+    if (rval) {
+        fprintf (stderr, "CCcut_SRK_subtour_shrink failed\n"); goto CLEANUP;
+    }
+
+    if (CCcut_SRK_grab_edges (&G, &sncount, &secount, &slist, &slen,
+                       (CC_SRKexpinfo *) NULL)) {
+        fprintf (stderr, "grab edges failed in shrink_ones\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    while (sncount > 1) {
+        if ( G.head->adj       == (CC_SRKedge *) NULL ||
+             G.head->next->adj == (CC_SRKedge *) NULL) {
+            fprintf (stderr, "Disconnected graph\n");
+            rval = 1; goto CLEANUP;
+        }
+        rval = CCcut_mincut_st (sncount, secount, slist, slen, 0, 1,
+                                &val, mytcut, &tcount);
+        if (rval) {
+            fprintf (stderr, "CCcut_mincut_st failed\n");
+            goto CLEANUP;
+        }
+        if (val < minval) {
+            minval = val;
+            if (cut) {
+                CC_IFFREE (*cut, int);
+                rval = CCcut_SRK_grab_nodes (&G, &E);
+                if (rval) {
+                    fprintf (stderr, "CCcut_SRK_grab_nodes failed\n");
+                    goto CLEANUP;
+                }
+                CCcut_SRK_expand (&E, tcut, tcount, cut, cutcount);
+                CCcut_SRK_free_expinfo (&E);
+            }
+        }
+        if (val < cutoff && doit_fn) {
+            int *fcut = (int *) NULL;
+            int fcutcount = 0;
+
+            rval = CCcut_SRK_grab_nodes (&G, &E);
+            if (rval) {
+                fprintf (stderr, "CCcut_SRK_grab_nodes failed\n");
+                goto CLEANUP;
+            }
+            CCcut_SRK_expand (&E, tcut, tcount, &fcut, &fcutcount);
+            CCcut_SRK_free_expinfo (&E);
+            rval = doit_fn (val, fcutcount, fcut, pass_param);
+            if (rval) {
+                fprintf (stderr, "doit_fn failed\n");
+                CC_IFFREE (fcut, int);
+                goto CLEANUP;
+            }
+            CC_IFFREE (fcut, int);
+        }
+
+        if (cut || doit_fn) {
+            CC_IFFREE (tcut, int);
+        }
+
+        CCcut_SRK_identify_nodes (&G, G.head, G.head->next);
+
+        squeue = (CC_SRKnode *) NULL;
+        for (f = G.head->adj; f; f = f->next) {
+            f->end->qnext = squeue;
+            squeue = f->end;
+        }
+        G.head->qnext = squeue;
+        squeue = G.head;
+
+        CCcut_SRK_identify_pr_edges (&G, &minval, &i, squeue,
+                     CC_MINCUT_ONE_EPSILON, cb, cut, cutcount);
+
+        /* if (i) { printf ("[%d]", i); fflush (stdout); } */
+
+        CC_IFFREE (slist, int);
+        CC_IFFREE (slen, double);
+        rval = CCcut_SRK_grab_edges (&G, &sncount, &secount, &slist, &slen,
+                            (CC_SRKexpinfo *) NULL);
+        if (rval) {
+            fprintf (stderr, "grab edges failed in shrink_ones\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (cutval) {
+        *cutval = minval;
+    }
+
+    if (cut) {
+        if (*cutcount > ncount/2) {
+            rval = flip_the_cut (ncount, cut, cutcount);
+            if (rval) {
+                fprintf (stderr, "flip_the_cut failed\n"); goto CLEANUP;
+            }
+        }
+    }
+
+CLEANUP:
+
+    if (rval) {
+        if (cut) {
+            CC_IFFREE (*cut, int);
+        }
+    }
+    CC_IFFREE (slist, int);
+    CC_IFFREE (slen, double);
+    CC_IFFREE (tcut, int);
+    CCcut_SRK_free_graph (&G);
+    CCcut_SRK_free_expinfo (&E);
+    CC_IFFREE (cb, CC_SRKcallback);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int flip_the_cut (int ncount, int **cut, int *cutcount)
+#else
+static int flip_the_cut (ncount, cut, cutcount)
+int ncount;
+int **cut;
+int *cutcount;
+#endif
+{
+    int rval = 0;
+    int i;
+    char *marks = (char *) NULL;
+    int *newcut = (int *) NULL;
+    int newcutcount = 0;
+
+    if (*cutcount == ncount) {
+        fprintf (stderr, "cut is the entire graph\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    marks = CC_SAFE_MALLOC (ncount, char);
+    if (!marks) {
+        fprintf (stderr, "out of memory in flip_the_cut\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++) {
+        marks[i] = 0;
+    }
+    for (i = 0; i < *cutcount; i++) {
+        marks[(*cut)[i]] = 1;
+    }
+
+    newcut = CC_SAFE_MALLOC (ncount - *cutcount, int);
+    if (!newcut) {
+        fprintf (stderr, "out of memory in flip_the_cut\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++) {
+        if (!marks[i]) {
+            newcut[newcutcount++] = i;
+        }
+    }
+
+    CC_IFFREE (*cut, int);
+    *cut = newcut;
+    *cutcount = newcutcount;
+
+CLEANUP:
+
+    if (rval) {
+        CC_IFFREE (newcut, int);
+    }
+    CC_IFFREE (marks, char);
+
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/CUT/segments.c b/contrib/blossom/concorde97/CUT/segments.c
new file mode 100644
index 0000000000000000000000000000000000000000..aa76be3fd85c610949c1adc125d24f575cb8f064
--- /dev/null
+++ b/contrib/blossom/concorde97/CUT/segments.c
@@ -0,0 +1,352 @@
+/***************************************************************************/
+/*                                                                         */
+/*                LINEAR SUBTOUR SEPARATION ROUTINES                       */
+/*                           preliminary                                   */
+/*                                                                         */
+/*                              TSP CODE                                   */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: July 25, 1995                                                    */
+/*  Thanks: Phil Gibbons, for helpful ideas                                */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCcut_linsub (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,  */
+/*            int ecount, int *elist, double *x)                           */
+/*      -cuts will return any new cuts found (they will be added to the    */
+/*       head of the linked list                                           */
+/*      -cutcount will return the number of new cuts added                 */
+/*      -ncount is the number of nodes                                     */
+/*      -ecount is the number of edges                                     */
+/*      -elist contains the LP edges in node node format                   */
+/*      -x is an LP solution                                               */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      linsub runs in time O(m log n).                                    */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "cut.h"
+
+#define NO_PATHS
+
+typedef struct psh {
+    int base;
+    int size;
+    double *sum;
+    double *minpre;
+} psh;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    psh_free (psh *p),
+    psh_add (psh *p, int i, double v);
+
+static int
+    add_the_cut (int (*doit_fn) (double, int, int, void *),
+        void *pass_param, double val, int a, int b),
+    psh_init (psh *p, int k),
+    psh_minloc (psh *p);
+
+static double
+    psh_minval (psh *p);
+
+#else
+
+static void
+    psh_free (),
+    psh_add ();
+
+static int
+    add_the_cut (),
+    psh_init (),
+    psh_minloc ();
+
+static double
+    psh_minval ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_linsub (int ncount, int ecount, int *elist, double *x, double cutoff,
+        int (*doit_fn) (double, int, int, void *), void *pass_param)
+#else
+int CCcut_linsub (ncount, ecount, elist, x, cutoff, doit_fn, pass_param)
+int ncount, ecount;
+int *elist;
+double *x;
+double cutoff;
+int (*doit_fn) ();
+void *pass_param;
+#endif
+{
+    int rval = 0;
+    psh p;
+    int i, j;
+    double v;
+    int count = 0;
+    int *perm = (int *) NULL;
+    int *eperm = (int *) NULL;
+    int *ends = (int *) NULL;
+    double *xends = (double *) NULL;
+#ifdef NO_PATHS
+    double sum_next;
+#endif
+    printf ("linsub ... "); fflush (stdout);
+
+    if (psh_init (&p, ncount)) {
+        return -1;
+    }
+
+    /*  arrange elist into the array ends (with xends being the x values   */
+    /*  so that ends[2*i] is less than ends[2*i+1], and ends is sorted in  */
+    /*  increasing  order of ends[2*i]                                     */
+
+    perm = CC_SAFE_MALLOC (ecount, int);
+    eperm = CC_SAFE_MALLOC (ecount, int);
+    if (!perm || !eperm) {
+        fprintf (stderr, "out of memory in linsub\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++) {
+        eperm[i] = (elist[2*i] < elist[2*i+1] ? elist[2*i] : elist[2*i+1]);
+        perm[i] = i;
+    }
+    CCutil_int_perm_quicksort (perm, eperm, ecount);
+
+    ends = CC_SAFE_MALLOC (2*ecount, int);
+    xends = CC_SAFE_MALLOC (ecount, double);
+    if (!ends || !xends) {
+        fprintf (stderr, "out of memory in linsub\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++) {
+        j = perm[i];
+        if (elist[2*j] < elist[2*j+1]) {
+            ends[2*i] = elist[2*j];
+            ends[2*i+1] = elist[2*j+1];
+        } else {
+            ends[2*i] = elist[2*j+1];
+            ends[2*i+1] = elist[2*j];
+        }
+        xends[i] = x[j];
+    }
+    CC_FREE (perm, int);
+    CC_FREE (eperm, int);
+
+    for (i = ncount - 1, j = ecount - 1; i > 0; i--) {
+#ifdef NO_PATHS
+        sum_next = 0.0;
+#endif
+        while (j >= 0 && ends[2*j] == i) {
+            psh_add (&p, ends[2*j+1], -xends[j]);
+#ifdef NO_PATHS
+            if (ends[2*j+1] == i+1) {
+                sum_next += xends[j];
+            }
+#endif
+            j--;
+        }
+        v = psh_minval (&p);
+#ifdef NO_PATHS
+        if (sum_next < 0.999999)
+#endif
+        if (2.0 + v < cutoff) {
+            rval = add_the_cut (doit_fn, pass_param, 2.0 + v, i,
+                                psh_minloc (&p));
+            if (rval) {
+                fprintf (stderr, "add_the_cut failed\n"); goto CLEANUP;
+            }
+            count++;
+        }
+        psh_add (&p, i, 1.0);
+    }
+
+CLEANUP:
+
+    printf ("DONE (found %d cuts)\n", count);
+    fflush (stdout);
+
+    psh_free (&p);
+    CC_IFFREE (ends, int);
+    CC_IFFREE (xends, double);
+    CC_IFFREE (perm, int);
+    CC_IFFREE (eperm, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_the_cut (int (*doit_fn) (double, int, int, void *),
+        void *pass_param, double val, int a, int b)
+#else
+static int add_the_cut (doit_fn, pass_param, val, a, b)
+int (*doit_fn) ();
+void *pass_param;
+double val;
+int a, b;
+#endif
+{
+    int rval = 0;
+
+    rval = doit_fn (val, a, b, pass_param);
+    if (rval) {
+        fprintf (stderr, "doit_fn failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+/***************************************************************************/
+/*                                                                         */
+/*                      PREFIX SUM HEAP ROUTINES                           */
+/*                                                                         */
+/*                              TSP CODE                                   */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: July 25, 1995                                                    */
+/*  Thanks: Phil Gibbons, for the algorithm                                */
+/*                                                                         */
+/*  These routines implement a heap of prefix sums.  The routines are      */
+/*  self-contained, but unlikely to be useful outside of the linear        */
+/*  subtour separation code.                                               */
+/*                                                                         */
+/*  PREFIX SUM HEAP FUNCTIONS:                                             */
+/*    int psh_init (psh *p, int k)                                         */
+/*      -p should point to a psh struct.                                   */
+/*      -k is the number of elements in the psh.                           */
+/*      -this initializes the value of all k elements to 0.0.              */
+/*      -return value 0 means success, 1 means failure.                    */
+/*    void psh_free (psh *p)                                               */
+/*      -frees the spaces allocated by psh_init.                           */
+/*    void psh_add (psh *p, int i, double v)                               */
+/*      -adds v to the value of element i.                                 */
+/*    double psh_minval (psh *p)                                           */
+/*      -returns min_j sum_{i=0}^j value[i].                               */
+/*    int psh_minloc (psh *p)                                              */
+/*      -returns the smallest j which achieves psh_minval(p).              */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      A k-element heap will malloc 32k bytes of memory. If memory is     */
+/*  tight, using integer values (instead of doubles) brings it down to     */
+/*  16k bytes.                                                             */
+/*      psh_init takes O(k) time.  psh_add and psh_minloc take O(log k)    */
+/*  time.  psh_free and psh_minval take O(1) time.                         */
+/*                                                                         */
+/*      It is likely that using a ternary tree instead of binary would     */
+/*  improve performance.  Also, psh_add could take advantage of knowing    */
+/*  which child has changed.                                               */
+/*      psh_minloc could be changed to return all elements which achieve   */
+/*  the min, in time O(log k) per element returned.                        */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static int psh_init (psh *p, int k)
+#else
+static int psh_init (p, k)
+psh *p;
+int k;
+#endif
+{
+    int i;
+    int space;
+
+    p->size = k;
+    p->base = 1;
+    while (p->base < k) p->base *= 2;
+
+    space = p->base*2;
+
+    p->sum = CC_SAFE_MALLOC (space, double);
+    if (!p->sum)
+        return 1;
+    p->minpre = CC_SAFE_MALLOC (space, double);
+    if (!p->minpre) {
+        CC_FREE (p->sum, double);
+        return 1;
+    }
+    for (i=0; i<space; i++) {
+        p->sum[i] = 0.0;
+        p->minpre[i] = 0.0;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void psh_free (psh *p)
+#else
+static void psh_free (p)
+psh *p;
+#endif
+{
+    CC_FREE (p->minpre, double);
+    CC_FREE (p->sum, double);
+    p->size = 0;
+    p->base = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void psh_add (psh *p, int i, double v)
+#else
+static void psh_add (p, i, v)
+psh *p;
+int i;
+double v;
+#endif
+{
+    double *s = p->sum;
+    double *m = p->minpre;
+
+    i += p->base;
+    s[i] += v;
+    m[i] += v;
+    i /= 2;
+    while (i >= 1) {
+        s[i] += v;
+        if (m[2*i] < s[2*i] + m[2*i+1]) {
+            m[i] = m[2*i];
+        } else {
+            m[i] = s[2*i] + m[2*i+1];
+        }
+        i /= 2;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int psh_minloc (psh *p)
+#else
+static int psh_minloc (p)
+psh *p;
+#endif
+{
+    int i = 1;
+    double *m = p->minpre;
+
+    while (i < p->base) {
+        if (m[i] == m[2*i]) {
+            i = 2*i;
+        } else {
+            i = 2*i+1;
+        }
+    }
+    if (i - p->base < p->size) {
+        return i - p->base;
+    } else {
+        /* we're lost */
+        return p->size - 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double psh_minval (psh *p)
+#else
+static double psh_minval (p)
+psh *p;
+#endif
+{
+    return p->minpre[1];
+}
diff --git a/contrib/blossom/concorde97/CUT/shrink.c b/contrib/blossom/concorde97/CUT/shrink.c
new file mode 100644
index 0000000000000000000000000000000000000000..dac0eb0b615524398da2ff4bcc181dc1325a03ad
--- /dev/null
+++ b/contrib/blossom/concorde97/CUT/shrink.c
@@ -0,0 +1,1299 @@
+/***************************************************************************/
+/*                                                                         */
+/*                             SHRINK ROUTINES                             */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook (TSP Code)            */
+/*  Date: July 19, 1996                                                    */
+/*        October 21, 1996 (bico)                                          */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*                                                                         */
+/*   void CCcut_SRK_init_graph (CC_SRKgraph *G)                            */
+/*    INITIALIZES the fields of the CC_SRKgraph.                           */
+/*                                                                         */
+/*   void CCcut_SRK_free_graph (CC_SRKgraph *G)                            */
+/*    FREES the SRKgraph.                                                  */
+/*                                                                         */
+/*   int CCcut_SRK_grab_edges (CC_SRKgraph *G, int *oncount, int *oecount, */
+/*          int **olist, double **olen, CC_SRKexpinfo *expand)             */
+/*          int **omembers)                                                */
+/*    RETURNS the edges and member lists for the shrunk graph.             */
+/*     -G is a pointer to a shrunk graph                                   */
+/*     -oncount returns the number of nodes in the shrunk graph            */
+/*     -oecount returns the number of edges in the shrunk graph            */
+/*     -olist returns the edges in node node format                        */
+/*     -olen returns the edge lengths                                      */
+/*     -expand will be filled in with a memindex and members array;        */
+/*      memindex returns pointers into the members array, the              */
+/*      members of node i will be stored in from memindex[i] to            */
+/*      memindex[i+1] - 1, so memindex is ncount + 1 long; members         */
+/*      returns the nodes lists corresponding to each node in the          */
+/*      shrunk graph. (expand can be NULL)                                 */
+/*                                                                         */
+/*   int CCcut_SRK_grab_nodes (CC_SRKgraph *G, SRKexpinfo *expand          */
+/*    RETURNS the member lists for the shrunk graph (see above)            */
+/*                                                                         */
+/*  NOTE: Cyles of 1's will be shrunk into single nodes.                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "cut.h"
+
+#define ADD_TO_PR_QUEUE(n) {                                             \
+    if (!(n)->onqueue) {                                                 \
+        (n)->qnext = (CC_SRKnode *) NULL;                                \
+        if (qtail)                                                       \
+            qtail->qnext = (n);                                          \
+        else                                                             \
+            qhead = (n);                                                 \
+        qtail = (n);                                                     \
+        (n)->onqueue = 1;                                                \
+    }                                                                    \
+}
+
+#undef  PR_USE3   /* PR_USE3 and PR_USE4 cannot be defined in current code */
+#undef  PR_USE4
+#undef DEBUG_SHRINK
+#define CC_SRK_ZERO_EPSILON (1e-10)
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+#ifdef DEBUG_SHRINK
+    printgraph (CC_SRKgraph *G),
+#endif
+    count_ones (CC_SRKgraph *G),
+    merge_adj (CC_SRKgraph *G, CC_SRKnode *n, CC_SRKnode *m);
+
+static int
+    test_node (CC_SRKnode *n, double *minval, CC_SRKcallback *cb, int **cut,
+        int *cutcount),
+    expand_the_node (CC_SRKnode *n, int *cutcount, int **cut),
+    expand_and_pass (CC_SRKnode *n, int (*doit_fn) (double, int, int *,
+        void *), void *pass_param);
+
+#else
+
+static void
+#ifdef DEBUG_SHRINK
+    printgraph (),
+#endif
+    count_ones (),
+    merge_adj ();
+
+static int
+    test_node (),
+    expand_the_node (),
+    expand_and_pass ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_subtour_shrink (CC_SRKgraph *G, double *minval, double epsilon,
+        CC_SRKcallback *cb, int **cut, int *cutcount)
+#else
+int CCcut_SRK_subtour_shrink (G, minval, epsilon, cb, cut, cutcount)
+CC_SRKgraph *G;
+double *minval;
+double epsilon;
+CC_SRKcallback *cb;
+int **cut;
+int *cutcount;
+#endif
+{
+    int rval = 0;
+    int k, cnt = 0;
+    CC_SRKnode *n;
+
+    for (n = G->head; n; n = n->next) {
+        cnt++;
+    }
+
+    /* In the tsp, paths of 1's can be shrunk via a call to the function  */
+    /* CCcut_SRK_identify_paths.                                          */
+
+    /* Could call a version of CCcut_SRK_identify_ones */
+
+    printf ("Identify PR edges ....\n");
+    fflush (stdout);
+    rval = CCcut_SRK_identify_pr_edges (G, minval, &k, (CC_SRKnode *) NULL,
+                   epsilon, cb, cut, cutcount);
+    if (rval) {
+        fprintf (stderr, "SRK_identify_pr_edges failed\n"); goto CLEANUP;
+    }
+
+    cnt -= k;
+    printf ("Graph shrunk to %d nodes\n", cnt);
+    fflush (stdout);
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void count_ones (CC_SRKgraph *G)
+#else
+static void count_ones (G)
+CC_SRKgraph *G;
+#endif
+{
+    int k;
+    CC_SRKnode *n;
+    CC_SRKedge *e;
+
+    for (n = G->head; n; n = n->next) {
+        for (k = 0, e = n->adj; e; e = e->next) {
+            if (e->weight == 1.0)
+                k++;
+        }
+        n->onecnt = k;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_identify_paths (CC_SRKgraph *G, int *newcount, int onecnt_okay)
+#else
+void CCcut_SRK_identify_paths (G, newcount, onecnt_okay)
+CC_SRKgraph *G;
+int onecnt_okay;
+int *newcount;
+#endif
+{
+    CC_SRKnode *n, *m, *last;
+    CC_SRKedge *e, *f;
+    int dropcnt = 0;
+    double dropweight = 0.0;
+    int k;
+
+    printf ("Identify paths ...\n");
+    fflush (stdout);
+
+    if (!onecnt_okay)
+        count_ones (G);
+    for (n = G->head; n; n = n->next) {
+        if (n->onecnt == 1) {
+            e = n->adj;
+            while (e->weight != 1.0)
+                e = e->next;
+            last = n;
+            m = e->end;
+            while (m->onecnt != 1) {
+                m->parent = n;
+                m->members = n->members;
+                n->members = m;
+                e = m->adj;
+                while (e->weight != 1.0 || e->end == last)
+                    e = e->next;
+                last = m;
+                m = e->end;
+            }
+            m->parent = n;
+            m->members = n->members;
+            n->members = m;
+            m->onecnt = 3;
+        }
+    }
+
+    for (n = G->head; n->parent != n; n = n->next);
+    G->head = n;
+    G->head->prev = (CC_SRKnode *) NULL;
+    for (n = G->head->next; n; n = n->next) {
+        if (n->parent != n) {
+            n->prev->next = n->next;
+            if (n->next)
+               n->next->prev = n->prev;
+        }
+    }
+    for (k = 0, n = G->head; n; n = n->next) {
+        k++;
+        if (n->members) {
+            for (e = n->members->adj; e; e = e->next) {
+                e->other->end = n;
+            }
+            for (m = n->members->members; m; m = m->members) {
+                for (e = m->adj; e; e = e->next) {
+                    if (e->weight == 1.0) {
+                        e->other->end = n;
+                    } else {
+                        /* drop fluff edge */
+                        dropcnt++;
+                        dropweight += e->weight;
+                        f = e->other;
+                        if (f->prev) {
+                            f->prev->next = f->next;
+                        } else {
+                            e->end->adj = f->next;
+                        }
+                        if (f->next) {
+                            f->next->prev = f->prev;
+                        }
+                    }
+                }
+            }
+            n->weight = n->weight + n->members->weight;
+            merge_adj (G, n, n->members);
+        }
+    }
+
+    if (dropcnt > 0) {
+        printf ("dropped %d edges of total weight %f\n", dropcnt, dropweight);
+        fflush (stdout);
+    }
+
+    *newcount = k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_defluff (CC_SRKgraph *G)
+#else
+int CCcut_SRK_defluff (G)
+CC_SRKgraph *G;
+#endif
+{
+    CC_SRKnode *n;
+    CC_SRKedge *e, *enext;
+    int k;
+    int ndel = 0;
+    double delweight = 0.0;
+
+    for (n = G->head; n; n = n->next) {
+        for (k = 0, e = n->adj; e; e = e->next) {
+            if (e->weight >= 1.0 - CC_SRK_ZERO_EPSILON) {
+                e->weight = 1.0;
+                k++;
+            }
+        }
+        n->onecnt = k;
+    }
+
+    for (n = G->head; n; n = n->next) {
+        for (e = n->adj, n->adj = (CC_SRKedge *) NULL; e; e = enext) {
+            enext = e->next;
+            if (e->weight == 1.0 ||
+                (n->onecnt < 2 && e->end->onecnt < 2
+                 && e->weight > CC_SRK_ZERO_EPSILON)) {
+                if (n->adj) n->adj->prev = e;
+                e->next = n->adj;
+                n->adj = e;
+                e->prev = (CC_SRKedge *) NULL;
+            } else {
+                delweight += e->weight;
+                ndel++;
+            }
+        }
+    }
+
+    if (ndel & 1) {
+        fprintf (stderr, "Whoa, deleted %d (odd) endpoints in SRK_defluff\n",
+                 ndel);
+        return -1;
+    }
+    printf ("SRK_defluff deleted %d endpoints (weight %.6f)\n", ndel,
+            delweight);
+    fflush (stdout);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_identify_paths_to_edges (CC_SRKgraph *G, int *newcount,
+        int onecnt_okay)
+#else
+void CCcut_SRK_identify_paths_to_edges (G, newcount, onecnt_okay)
+CC_SRKgraph *G;
+int *newcount;
+int onecnt_okay;
+#endif
+{
+    CC_SRKnode *n, *p, *m, *last;
+    CC_SRKedge *e;
+    int k;
+
+    printf ("Identify paths to edges ...\n");
+    fflush (stdout);
+
+    /* NOTE: We should add in code to drop fluff edges */
+
+    if (!onecnt_okay)
+        count_ones (G);
+    for (n = G->head; n; n = n->next) {
+        if (n->onecnt == 1) {
+            e = n->adj;
+            while (e->weight != 1.0)
+                e = e->next;
+            m = e->end;
+            if (m->onecnt != 1) {
+                e = m->adj;
+                while (e->weight != 1.0 || e->end == n)
+                    e = e->next;
+                last = m;
+                p = e->end;
+                while (p->onecnt != 1) {
+                    p->parent = m;
+                    p->members = m->members;
+                    m->members = p;
+                    e = p->adj;
+                    while (e->weight != 1.0 || e->end == last)
+                         e = e->next;
+                    last = p;
+                    p = e->end;
+                }
+                p->parent = m;
+                p->members = m->members;
+                m->members = p;
+                p->onecnt = 3;
+            }
+        }
+    }
+
+
+    for (n = G->head; n->parent != n; n = n->next);
+    G->head = n;
+    G->head->prev = (CC_SRKnode *) NULL;
+    for (n = G->head->next; n; n = n->next) {
+        if (n->parent != n) {
+            n->prev->next = n->next;
+            if (n->next)
+               n->next->prev = n->prev;
+        }
+    }
+    for (k = 0, n = G->head; n; n = n->next) {
+        k++;
+        if (n->members) {
+            for (m = n->members; m; m = m->members) {
+                for (e = m->adj; e; e = e->next)
+                    e->other->end = n;
+            }
+            merge_adj (G, n, n->members);
+        }
+    }
+    *newcount = k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_identify_ones (CC_SRKgraph *G, int *count, double epsilon)
+#else
+void CCcut_SRK_identify_ones (G, count, epsilon)
+CC_SRKgraph *G;
+int *count;
+double epsilon;
+#endif
+{
+    CC_SRKnode *n;
+    CC_SRKedge *e;
+    double tol = 1.0 - epsilon;
+
+    printf ("Identify ones ....\n");
+    fflush (stdout);
+
+    *count = 0;
+
+    for (n = G->head; n; n = n->next) {
+        do {
+            for (e = n->adj; e; e = e->next) {
+                if (e->weight >= tol) {
+                    CCcut_SRK_identify_nodes (G, n, e->end);
+                    (*count)++;
+                    break;
+                }
+            }
+        } while (e);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_identify_pr_edges (CC_SRKgraph *G, double *minval, int *count,
+        CC_SRKnode *qstart, double epsilon, CC_SRKcallback *cb, int **cut,
+        int *cutcount)
+#else
+int CCcut_SRK_identify_pr_edges (G, minval, count, qstart, epsilon, cb, cut,
+        cutcount)
+CC_SRKgraph *G;
+double *minval;
+int *count;
+CC_SRKnode *qstart;
+double epsilon;
+CC_SRKcallback *cb;
+int **cut;
+int *cutcount;
+#endif
+{
+    int rval = 0;
+    CC_SRKnode *n;
+    CC_SRKedge *e, *f, *h;
+    double tol, tol1, tol2;
+    CC_SRKnode *qhead, *qtail;
+
+    /* Trivial PR Test: If w(uv) >= c(u)/2, then we can shrink edge uv.   */
+
+    /* First PR Test: If we have a triangle uv, uw, vw with               */
+    /* w(uv) + w(vw) >= c(v)/2 and w(uw) + w(vw) >= c(w)/2, then we can   */
+    /* shrink edge vw.                                                    */
+
+    /* Second PR Test: Compute a lower bound on any cut that separates    */
+    /* the ends of an edge by summing the minimum values of the edges to  */
+    /* common neighbors of the ends. If the bound is >= "2", then we can  */
+    /* shrink the edge.                                                   */
+
+    /* Third PR Test: Edge uv with common neighbors xy. If                */
+    /* w(ux) + w(uy) + w(uv) >= "1" and w(vx) + w(vy) + w(uv) >= "1" and  */
+    /* at least one of w(uy) + w(uv) and w(vx) + w(uv) is >= "1" and      */
+    /* at least one of w(ux) + w(uv) and w(vy) + w(uv) is >= "1" then we  */
+    /* can shrink the edge uv.                                            */
+
+    *count = 0;
+
+    if (cut && !cutcount) {
+        fprintf (stderr, "cut defined, but not cutcount\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    if (qstart) {
+        qhead = qstart;
+        for (n = qstart; n->next; n = n->next)
+            n->onqueue = 1;
+        qtail = n;
+        qtail->onqueue = 1;
+    } else {
+        for (n = G->head; n->next; n = n->next) {
+            n->qnext = n->next;
+            n->onqueue = 1;
+        }
+        qhead = G->head;
+        qtail = n;
+        qtail->onqueue = 1;
+        qtail->qnext = (CC_SRKnode *) NULL;
+    }
+
+    while (qhead) {
+        n = qhead;
+        qhead = qhead->qnext;
+        if (!qhead)
+            qtail = (CC_SRKnode *) NULL;
+        if (n->parent != n)
+            continue;
+        n->onqueue = 0;
+        tol = n->weight/2.0 - epsilon;
+
+        for (e = n->adj; e && e->weight < tol; e = e->next);
+        if (e) {
+            rval = test_node (n, minval, cb, cut, cutcount);
+            if (rval) { fprintf (stderr, "test_node failed\n"); goto CLEANUP; }
+            rval = test_node (e->end, minval, cb, cut, cutcount);
+            if (rval) { fprintf (stderr, "test_node failed\n"); goto CLEANUP; }
+            CCcut_SRK_identify_nodes (G, n, e->end);
+            (*count)++;
+            ADD_TO_PR_QUEUE(n);
+            for (h = n->adj; h; h = h->next) {
+                ADD_TO_PR_QUEUE(h->end);
+            }
+        } else {
+            for (e = n->adj; e; e = e->next)
+                e->end->prweight = e->weight;
+            for (e = n->adj; e; e = e->next) {
+                tol1 = (n->weight/2.0) - e->weight - epsilon;
+                tol2 = (e->end->weight/2.0) - e->weight - epsilon;
+                for (f = e->end->adj; f; f = f->next) {
+                    if (f->weight >= tol2 && f->end->prweight >= tol1) {
+                        rval = test_node (n, minval, cb, cut, cutcount);
+                        if (rval) {
+                            fprintf (stderr, "test_node failed\n");
+                            goto CLEANUP;
+                        }
+                        rval = test_node (e->end, minval, cb, cut, cutcount);
+                        if (rval) {
+                            fprintf (stderr, "test_node failed\n");
+                            goto CLEANUP;
+                        }
+                        CCcut_SRK_identify_nodes (G, n, e->end);
+                        (*count)++;
+                        ADD_TO_PR_QUEUE(n);
+                        for (h = n->adj; h; h = h->next) {
+                            ADD_TO_PR_QUEUE(h->end);
+                        }
+                        goto GET_OUT;
+                    }
+                }
+            }
+
+#ifdef PR_USE3
+    -Must modify to use node current min cut value.
+            for (e = n->adj; e; e = e->next) {
+                tol = e->weight;
+                for (f = e->end->adj; f; f = f->next) {
+                    if (f->end->prweight >= f->weight)
+                        tol += f->weight;
+                    else if (f->end->prweight > -2.0)
+                        tol += f->end->prweight;
+                }
+                if (tol >= 1.0 + onetol) {
+                    printf ("X"); fflush (stdout);
+                    CCcut_SRK_identify_nodes (G, n, e->end);
+                    (*count)++;
+                    ADD_TO_PR_QUEUE(n);
+                    for (h = n->adj; h; h = h->next) {
+                        ADD_TO_PR_QUEUE(h->end);
+                    }
+                    goto GET_OUT;
+                }
+            }
+#endif
+
+#ifdef PR_USE4
+    -Must modify to use node weights.
+            for (e = n->adj; e; e = e->next) {
+                tol = onetol - e->weight;
+                for (f = e->end->adj; f; f = f->next) {
+                    if (f->end->prweight > -2.0) {
+                        for (h = f->next; h; h = h->next) {
+                            if (h->end->prweight > -2.0) {
+                                if (f->weight + h->weight >= tol
+                       && f->end->prweight + h->end->prweight >= tol
+                       && (f->weight >= tol || h->end->prweight >= tol)
+                       && (h->weight >= tol || f->end->prweight >= tol)) {
+                                    CCcut_SRK_identify_nodes (G, n, e->end);
+                                    (*count)++;
+                                        ADD_TO_PR_QUEUE(n);
+                                    for (h = n->adj; h; h = h->next) {
+                                        ADD_TO_PR_QUEUE(h->end);
+                                    }
+                                    goto GET_OUT;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+#endif
+
+GET_OUT:
+            for (e = n->adj; e; e = e->next)
+                e->end->prweight = -2.0;
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_node (CC_SRKnode *n, double *minval, CC_SRKcallback *cb,
+        int **cut, int *cutcount)
+#else
+static int test_node (n, minval, cb, cut, cutcount)
+CC_SRKnode *n;
+double *minval;
+CC_SRKcallback *cb;
+int **cut;
+int *cutcount;
+#endif
+{
+    int rval = 0;
+
+    if (n->weight < *minval) {
+        *minval = n->weight;
+        /* printf ("New minimum: %f\n", *minval); */
+        if (cut) {
+            CC_IFFREE (*cut, int);
+            rval = expand_the_node (n, cutcount, cut);
+            if (rval) {
+                fprintf (stderr, "expand_the_node failed\n"); goto CLEANUP;
+            }
+        }
+    }
+    if (cb) {
+        if (n->weight <= cb->cutoff) {
+            rval = expand_and_pass (n, cb->doit_fn, cb->pass_param);
+            if (rval) {
+                fprintf (stderr,"expand_and_pass failed\n"); goto CLEANUP;
+            }
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int expand_and_pass (CC_SRKnode *n, int (*doit_fn) (double, int, int *,
+        void *), void *pass_param)
+#else
+static int expand_and_pass (n, doit_fn, pass_param)
+CC_SRKnode *n;
+int (*doit_fn) ();
+void *pass_param;
+#endif
+{
+    int rval = 0;
+    int cutcount;
+    int *cut = (int *) NULL;
+
+    if (!doit_fn) goto CLEANUP;
+
+    rval = expand_the_node (n, &cutcount, &cut);
+    if (rval) {
+        fprintf (stderr, "expand_the_node failed\n"); fflush (stdout);
+    }
+
+    rval = doit_fn (n->weight, cutcount, cut, pass_param);
+    if (rval) {
+        fprintf (stderr, "doit_fn failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (cut, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int expand_the_node (CC_SRKnode *n, int *cutcount, int **cut)
+#else
+static int expand_the_node (n, cutcount, cut)
+CC_SRKnode *n;
+int *cutcount;
+int **cut;
+#endif
+{
+    int rval = 0;
+    int cnt;
+    int *tcut = (int *) NULL;
+    CC_SRKnode *v;
+
+    *cutcount = 0;
+    *cut = (int *) NULL;
+
+    cnt = 1;
+    for (v = n->members; v; v = v->members) {
+        cnt++;
+    }
+    tcut = CC_SAFE_MALLOC (cnt, int);
+    if (!tcut) {
+        fprintf (stderr, "out of memory in expand_the_node\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    tcut[0] = n->num;
+    cnt = 1;
+    for (v = n->members; v; v = v->members) {
+        tcut[cnt++] = v->num;
+    }
+
+    *cutcount = cnt;
+    *cut = tcut;
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_identify_one_triangles (CC_SRKgraph *G, int *count,
+        CC_SRKnode *qstart, double epsilon)
+#else
+void CCcut_SRK_identify_one_triangles (G, count, qstart, epsilon)
+CC_SRKgraph *G;
+int *count;
+CC_SRKnode *qstart;
+double epsilon;
+#endif
+{
+    CC_SRKnode *n;
+    CC_SRKedge *e, *f, *h;
+    CC_SRKnode *qhead, *qtail;
+    double tol = 1.0 - epsilon;
+
+    printf ("Identify one edges in tight triangles ....\n");
+    fflush (stdout);
+
+    /* Identify any edge of weight one that is contained in a triangle of */
+    /* weight two.   */
+
+    *count = 0;
+    if (qstart) {
+        qhead = qstart;
+        for (n = qstart; n->next; n = n->next)
+            n->onqueue = 1;
+        qtail = n;
+        qtail->onqueue = 1;
+    } else {
+        for (n = G->head; n->next; n = n->next) {
+            n->qnext = n->next;
+            n->onqueue = 1;
+        }
+        qhead = G->head;
+        qtail = n;
+        qtail->onqueue = 1;
+        qtail->qnext = (CC_SRKnode *) NULL;
+    }
+
+    while (qhead) {
+        n = qhead;
+        qhead = qhead->qnext;
+        if (!qhead)
+            qtail = (CC_SRKnode *) NULL;
+        if (n->parent != n)
+            continue;
+        n->onqueue = 0;
+
+        for (e = n->adj; e && e->weight < tol; e = e->next);
+        if (e) {
+            for (f = n->adj; f; f = f->next)
+                f->end->prweight = f->weight;
+            for (f = e->end->adj; f; f = f->next) {
+                if (f->weight + f->end->prweight >= tol ||
+                   (f->weight >= tol && f->end != n)) {
+                    CCcut_SRK_identify_nodes (G, n, e->end);
+                    (*count)++;
+                    ADD_TO_PR_QUEUE(n);
+                    for (h = n->adj; h; h = h->next) {
+                        ADD_TO_PR_QUEUE(h->end);
+                    }
+                    goto GET_OUT;
+                }
+            }
+GET_OUT:
+            for (e = n->adj; e; e = e->next)
+                e->end->prweight = -2.0;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_identify_nodes (CC_SRKgraph *G, CC_SRKnode *n, CC_SRKnode *m)
+#else
+void CCcut_SRK_identify_nodes (G, n, m)
+CC_SRKgraph *G;
+CC_SRKnode *n, *m;
+#endif
+{
+    CC_SRKedge *e;
+
+    m->parent = n;
+    n->weight += m->weight;
+
+    if (!n->members) {
+        n->members = m;
+    } else if (!m->members) {
+        m->members = n->members;
+        n->members = m;
+    } else {
+        CC_SRKnode *t;
+        for (t = n->members; t->members; t = t->members);
+        t->members = m;
+    }
+
+    for (e = m->adj; e; e = e->next) {
+        e->other->end = n;
+    }
+
+    merge_adj (G, n, m);
+
+    if (m->prev)
+        m->prev->next = m->next;
+    else
+        G->head = m->next;
+    if (m->next)
+        m->next->prev = m->prev;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void merge_adj (CC_SRKgraph *G, CC_SRKnode *n, CC_SRKnode *m)
+#else
+static void merge_adj (G, n, m)
+CC_SRKgraph *G;
+CC_SRKnode *n, *m;
+#endif
+{
+    CC_SRKedge *e, *f, *last, *work;
+    CC_SRKedge **hit = G->hit;
+
+    /* String together the two lists */
+
+    if (n->adj) {
+        for (last = n->adj; last->next; last = last->next);
+        last->next = m->adj;
+        if (m->adj)
+            m->adj->prev = last;
+        work = n->adj;
+    } else {
+        work = m->adj;
+    }
+
+    /* Remove any edges that become loops */
+
+    while (work && work->end == n) {
+        n->weight -= work->weight;
+        work = work->next;
+    }
+
+    if (work) {
+        work->prev = (CC_SRKedge *) NULL;
+        for (e = work->next; e; e = e->next) {
+            if (e->end == n) {
+                n->weight -= e->weight;
+                e->prev->next = e->next;
+                if (e->next)
+                    e->next->prev = e->prev;
+            }
+        }
+    } else {
+        n->adj = (CC_SRKedge *) NULL;
+        return;
+    }
+
+    /* Remove the duplicate edges in the work list */
+
+    hit[work->end->num] = work;
+    for (e = work->next; e; e = e->next) {
+        if (hit[e->end->num]) {
+            /* A duplicate edge */
+
+            hit[e->end->num]->weight += e->weight;
+            hit[e->end->num]->other->weight = hit[e->end->num]->weight;
+            e->prev->next = e->next;
+            if (e->next)
+                e->next->prev = e->prev;
+
+            /* Fix the adj of the other end of the duplicate */
+
+            f = e->other;
+            if (f->prev) {
+                f->prev->next = f->next;
+            } else {
+                e->end->adj = f->next;
+            }
+            if (f->next) {
+                f->next->prev = f->prev;
+            }
+        } else {
+            hit[e->end->num] = e;
+        }
+    }
+
+    for (e = work; e; e = e->next)
+        hit[e->end->num] = (CC_SRKedge *) NULL;
+    n->adj = work;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_buildgraph (CC_SRKgraph *G, int ncount, int ecount, int *elist,
+        double *dlen)
+#else
+int CCcut_SRK_buildgraph (G, ncount, ecount, elist, dlen)
+CC_SRKgraph *G;
+int ncount, ecount;
+int *elist;
+double *dlen;
+#endif
+{
+    int i;
+    int *degree = (int *) NULL;
+    int newecount = 0;
+    CC_SRKnode *nodespace, *n, *n1, *n2;
+    CC_SRKedge *e, *adj1, *adj2;
+    CC_SRKedge **hit;
+
+    G->nodespace = CC_SAFE_MALLOC (ncount, CC_SRKnode);
+    G->hit = CC_SAFE_MALLOC (ncount, CC_SRKedge *);
+    if (!G->nodespace || !G->hit) {
+        fprintf (stderr, "out of memory in SRK_buildgraph\n");
+        CC_IFFREE (G->nodespace, CC_SRKnode);
+        CC_IFFREE (G->hit, CC_SRKedge *);
+        return 1;
+    }
+    nodespace = G->nodespace;
+    hit = G->hit;
+    G->head = nodespace;
+    G->original_ncount = ncount;
+    G->original_ecount = ecount;
+
+    degree = CC_SAFE_MALLOC (ncount, int);
+    if (!degree) {
+        fprintf (stderr, "out of memory in SRK_buildgraph\n");
+        CC_IFFREE (G->nodespace, CC_SRKnode);
+        CC_IFFREE (G->hit, CC_SRKedge *);
+        return 1;
+    }
+
+    for (i = 0, n = nodespace; i < ncount; i++, n++) {
+        n->prev = n - 1;
+        n->next = n + 1;
+        n->num = i;
+        n->members = (CC_SRKnode *) NULL;
+        n->parent = n;
+        n->prweight = -2.0;
+        n->weight = 0.0;
+        hit[i] = (CC_SRKedge *) NULL;
+        degree[i] = 0;
+        n->onecnt = 0;
+    }
+    nodespace[0].prev = (CC_SRKnode *) NULL;
+    nodespace[ncount - 1].next = (CC_SRKnode *) NULL;
+
+    for (i = 0; i < ecount; i++) {
+        if (dlen[i] > CC_SRK_ZERO_EPSILON) {
+            newecount++;
+            degree[elist[2*i]]++;
+            degree[elist[2*i+1]]++;
+        }
+    }
+    G->edgespace = CC_SAFE_MALLOC (2*newecount, CC_SRKedge);
+    if (!G->edgespace) {
+        fprintf (stderr, "out of memory in SRK_buildgraph\n");
+        CC_IFFREE (G->nodespace, CC_SRKnode);
+        CC_IFFREE (G->hit, CC_SRKedge *);
+        return 1;
+    }
+
+    for (e = G->edgespace, i = 0; i < ncount; i++) {
+        nodespace[i].adj = e;
+        e += degree[i];
+    }
+    for (i = 0; i < ecount; i++) {
+        if (dlen[i] > CC_SRK_ZERO_EPSILON) {
+            n1 = nodespace + elist[2 * i];
+            n2 = nodespace + elist[2 * i + 1];
+            adj1 = n1->adj;
+            adj2 = n2->adj;
+            adj1->end = n2;
+            adj1->weight = dlen[i];
+            adj1->next = adj1 + 1;
+            adj1->prev = adj1 - 1;
+            adj1->other = adj2;
+            adj2->end = n1;
+            adj2->weight = dlen[i];
+            adj2->next = adj2 + 1;
+            adj2->prev = adj2 - 1;
+            adj2->other = adj1;
+            n1->adj++;
+            n2->adj++;
+            if (dlen[i] == 1.0) {
+                n1->onecnt++;
+                n2->onecnt++;
+            }
+        }
+    }
+    for (e = G->edgespace, i = 0; i < ncount; i++) {
+        if (degree[i]) {
+            (nodespace[i].adj - 1)->next = (CC_SRKedge *) NULL;
+            nodespace[i].adj = e;
+            nodespace[i].adj->prev = (CC_SRKedge *) NULL;
+            e += degree[i];
+        } else {
+            nodespace[i].adj = (CC_SRKedge *) NULL;
+        }
+    }
+
+    for (i = 0, n = nodespace; i < ncount; i++, n++) {
+        for (e = n->adj; e; e = e->next) {
+            n->weight += e->weight;
+        }
+    }
+
+    CC_IFFREE(degree, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_grab_edges (CC_SRKgraph *G, int *oncount, int *oecount,
+        int **olist, double **olen, CC_SRKexpinfo *expand)
+#else
+int CCcut_SRK_grab_edges (G, oncount, oecount, olist, olen, expand)
+CC_SRKgraph *G;
+int *oncount, *oecount;
+int **olist;
+double **olen;
+CC_SRKexpinfo *expand;
+#endif
+{
+    int rval = 0;
+    int k, num;
+    int ncount = 0, ecount = 0;
+    CC_SRKnode *n;
+    CC_SRKedge *e;
+
+    *oncount = 0;
+    *oecount = 0;
+    *olist = (int *) NULL;
+    *olen = (double *) NULL;
+    if (expand) {
+        CCcut_SRK_init_expinfo (expand);
+    }
+
+    for (n = G->head; n; n = n->next) {
+        n->newnum = ncount;
+        for (e = n->adj; e; e = e->next)
+            ecount++;
+        ncount++;
+    }
+
+    if (ecount % 2) {
+        fprintf (stderr, "Error in grab_edges\n");
+        rval = 1; goto CLEANUP;
+    } else {
+        ecount /= 2;
+    }
+
+    if (ecount == 0) {
+        rval = 0; goto CLEANUP;
+    }
+
+    *olist = CC_SAFE_MALLOC (ecount * 2, int);
+    *olen  = CC_SAFE_MALLOC (ecount, double);
+    if (!(*olist) || !(*olen)) {
+        fprintf (stderr, "out of memory in grab_edges\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    k = 0;
+    for (n = G->head; n; n = n->next) {
+        num = n->newnum;
+        for (e = n->adj; e; e = e->next) {
+            if (num < e->end->newnum) {
+                (*olist)[2 * k] = num;
+                (*olist)[2 * k + 1] = e->end->newnum;
+                (*olen)[k++] = e->weight;
+            }
+        }
+    }
+    if (k != ecount) {
+        fprintf (stderr, "Error in grab_edges\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    *oncount = ncount;
+    *oecount = ecount;
+
+    if (expand) {
+        rval = CCcut_SRK_grab_nodes (G, expand);
+        if (rval) {
+            fprintf (stderr, "SRK_grab_nodes failed\n"); goto CLEANUP;
+        }
+    }
+
+CLEANUP:
+
+    if (rval) {
+        CC_IFFREE (*olist, int);
+        CC_IFFREE (*olen, double);
+        if (expand) {
+            CCcut_SRK_free_expinfo (expand);
+        }
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_grab_nodes (CC_SRKgraph *G, CC_SRKexpinfo *expand)
+#else
+int CCcut_SRK_grab_nodes (G, expand)
+CC_SRKgraph *G;
+CC_SRKexpinfo *expand;
+#endif
+{
+    int rval = 0;
+    int i;
+    CC_SRKnode *n, *m;
+    int total  = 0;
+    int ncount = 0;
+
+    if (!expand) {
+        fprintf (stderr, "SRK_grab_nodes called without an expand struct\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (n = G->head; n; n = n->next) {
+        ncount++;
+    }
+
+    CCcut_SRK_init_expinfo (expand);
+    expand->members  = CC_SAFE_MALLOC (G->original_ncount, int);
+    expand->memindex = CC_SAFE_MALLOC (ncount + 1, int);
+    if (!(expand->members) || !(expand->memindex)) {
+        fprintf (stderr, "out of memory in grab_nodes\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (n = G->head, i = 0; n; n = n->next, i++) {
+        expand->memindex[i] = total;
+        expand->members[total++] = n->num;
+        for (m = n->members; m; m = m->members)
+            expand->members[total++] = m->num;
+    }
+    expand->memindex[i] = total;
+
+CLEANUP:
+
+    if (rval) CCcut_SRK_free_expinfo (expand);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_init_graph (CC_SRKgraph *G)
+#else
+void CCcut_SRK_init_graph (G)
+CC_SRKgraph *G;
+#endif
+{
+    if (G) {
+        G->nodespace = (CC_SRKnode *) NULL;
+        G->edgespace = (CC_SRKedge *) NULL;
+        G->head      = (CC_SRKnode *) NULL;
+        G->hit       = (CC_SRKedge **) NULL;
+        G->original_ncount = 0;
+        G->original_ecount = 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_free_graph (CC_SRKgraph *G)
+#else
+void CCcut_SRK_free_graph (G)
+CC_SRKgraph *G;
+#endif
+{
+    if (G) {
+        CC_IFFREE (G->nodespace, CC_SRKnode);
+        CC_IFFREE (G->edgespace, CC_SRKedge);
+        CC_IFFREE (G->hit, CC_SRKedge *);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_init_callback (CC_SRKcallback *cb)
+#else
+void CCcut_SRK_init_callback (cb)
+CC_SRKcallback *cb;
+#endif
+{
+    if (cb) {
+        cb->cutoff     = 0.0;
+        cb->pass_param = (void *) NULL;
+#ifdef CC_PROTOTYPE_ANSI
+        cb->doit_fn    = (int (*) (double, int, int *, void *)) NULL;
+#else
+        cb->doit_fn    = (int (*) ()) NULL;
+#endif
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_trivial (int ncount, CC_SRKexpinfo *expand)
+#else
+int CCcut_SRK_trivial (ncount, expand)
+int ncount;
+CC_SRKexpinfo *expand;
+#endif
+{
+    int i;
+
+    expand->memindex = CC_SAFE_MALLOC (ncount+1, int);
+    if (!expand->memindex) {
+        fprintf (stderr, "Out of memory in SRK_trivial\n");
+        return -1;
+    }
+    expand->members = CC_SAFE_MALLOC (ncount, int);
+    if (!expand->members) {
+        fprintf (stderr, "Out of memory in SRK_trivial\n");
+        CC_FREE (expand->memindex, int);
+        return -1;
+    }
+    for (i=0; i<ncount; i++) {
+        expand->members[i] = i;
+        expand->memindex[i] = i;
+    }
+    expand->memindex[ncount] = ncount;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_init_expinfo (CC_SRKexpinfo *expand)
+#else
+void CCcut_SRK_init_expinfo (expand)
+CC_SRKexpinfo *expand;
+#endif
+{
+    expand->memindex = (int *) NULL;
+    expand->members = (int *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCcut_SRK_free_expinfo (CC_SRKexpinfo *expand)
+#else
+void CCcut_SRK_free_expinfo (expand)
+CC_SRKexpinfo *expand;
+#endif
+{
+    CC_IFFREE (expand->memindex, int);
+    CC_IFFREE (expand->members, int);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCcut_SRK_expand (CC_SRKexpinfo *expand, int *arr, int size, int **pnewarr,
+        int *pnewsize)
+#else
+int CCcut_SRK_expand (expand, arr, size, pnewarr, pnewsize)
+CC_SRKexpinfo *expand;
+int *arr;
+int size;
+int **pnewarr;
+int *pnewsize;
+#endif
+{
+    int newsize = 0;
+    int *newarr = (int *) NULL;
+    int i, j, jend;
+
+    *pnewsize = 0;
+    *pnewarr = (int *) NULL;
+    for (i=0; i<size; i++) {
+        newsize += expand->memindex[arr[i]+1] - expand->memindex[arr[i]];
+    }
+    newarr = CC_SAFE_MALLOC (newsize, int);
+    if (!newarr) {
+        fprintf (stderr, "Out of memory in SRK_expand\n");
+        return -1;
+    }
+    newsize = 0;
+    for (i=0; i<size; i++) {
+        for (j=expand->memindex[arr[i]], jend = expand->memindex[arr[i]+1];
+             j < jend; j++) {
+            newarr[newsize++] = expand->members[j];
+        }
+    }
+    *pnewarr = newarr;
+    *pnewsize = newsize;
+    return 0;
+}
+
+#ifdef DEBUG_SHRINK
+#ifdef CC_PROTOTYPE_ANSI
+static void printgraph (CC_SRKgraph *G)
+#else
+static void printgraph (G)
+CC_SRKgraph *G;
+#endif
+{
+    CC_SRKnode *n;
+    CC_SRKedge *e;
+
+    for (n = G->head; n; n = n->next) {
+        printf ("Node %d: ", n->num);
+        fflush (stdout);
+        for (e = n->adj; e; e = e->next) {
+            printf ("%d [%.2f] ", e->end->num, e->weight);
+            fflush (stdout);
+            if (e->other->end != n || e->other->weight != e->weight) {
+                printf ("(Whoops) ");
+                fflush (stdout);
+            }
+        }
+        printf ("\n");
+    }
+}
+#endif
diff --git a/contrib/blossom/concorde97/EDGEGEN/Makefile b/contrib/blossom/concorde97/EDGEGEN/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5dfbcc5d47608c63ead4d1734c0243e02d9523b6
--- /dev/null
+++ b/contrib/blossom/concorde97/EDGEGEN/Makefile
@@ -0,0 +1,34 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=edgegen.a
+LIBSRCS=edgegen.c  xnear.c
+ALLSRCS=eg_main.c  $(LIBSRCS)
+
+LIBS=$(ROOT)/KDTREE/kdtree.a   $(ROOT)/FMATCH/fmatch.a \
+     $(ROOT)/LINKERN/linkern.a $(ROOT)/UTIL/util.a
+
+all: edgegen $(LIB)
+
+edgegen: eg_main.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ -lm
+
+clean:
+	-rm -f *.$o $(LIB) edgegen
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+edgegen.$o:  edgegen.c  $(I)/machdefs.h $(I)/util.h     $(I)/edgegen.h  \
+        $(I)/kdtree.h   $(I)/linkern.h  $(I)/fmatch.h   
+eg_main.$o:  eg_main.c  $(I)/machdefs.h $(I)/util.h     $(I)/edgegen.h  
+xnear.$o:    xnear.c    $(I)/machdefs.h $(I)/util.h     $(I)/edgegen.h  
diff --git a/contrib/blossom/concorde97/EDGEGEN/edgegen.c b/contrib/blossom/concorde97/EDGEGEN/edgegen.c
new file mode 100644
index 0000000000000000000000000000000000000000..085789a70bb4b0240dceb46099d1278db14a08eb
--- /dev/null
+++ b/contrib/blossom/concorde97/EDGEGEN/edgegen.c
@@ -0,0 +1,1952 @@
+/***************************************************************************/
+/*                                                                         */
+/*                   COMPUTING INITIAL EDGE SETS                           */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 9, 1995                                                      */
+/*  Changes: 6.8.1996 (bico) fixed bug in f2match nearest                  */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCedgegen_read (char *egname, CCedgegengroup *plan)              */
+/*      READS an edgegen description from file egname.                     */
+/*        -egname the name of a file                                       */
+/*        -plan returns the description of the mix of edges (can be used   */
+/*         in a call to edgegen () to obtain the edgeset.                  */
+/*                                                                         */
+/*    int CCedgegen_edges (CCedgegengroup *plan, int ncount,               */
+/*            CCdatagroup *dat, double *wcoord, int *ecount, int **elist)  */
+/*      RETURNS the set of edges described in plan.                        */
+/*        -plan describes the mix of edges                                 */
+/*        -ncount is the number of nodes                                   */
+/*        -dat contains the info to generate edge lengths                  */
+/*        -wcoord are nodeweights for Held-Karp style edge lengths, using  */
+/*         len[i,j] + wcoord[i] + wcoord[j] (wcoord can be NULL)           */
+/*        -ecount returns the number of edges                              */
+/*        -elist returns the edges in end1 end2 format                     */
+/*                                                                         */
+/*    void CCedgegen_init_edgegengroup (CCedgegengroup *plan)              */
+/*      SETS the fields in plan to 0 (since there are so many fields to    */
+/*        to deal with)                                                    */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*       To use edgegen, look at the defintion of edgegengroup in          */
+/*    edgegen.h - you should be able to guess what the parmeters mean.     */
+/*    Note that wcoord is only used by a limited number of the generating  */
+/*    routines, for example nearest, but not linkern.                      */
+/*       The functions edgegen and edgegen_read will return nonzero values */
+/*    if they fail (for example, if they run out of memory.                */
+/*       The description file passed to edgegen_read should contain a list */
+/*    of some of the following commands:                                   */
+/*            EDGEGEN NEAREST #                                            */
+/*                    -find the nearest # edges                            */
+/*            EDGEGEN QUADNEAREST #                                        */
+/*                    -find the quadrant-nearest # edges                   */
+/*            EDGEGEN FRAC_TWOMATCH_NEAREST # [PRICED] [BASIC]             */
+/*                    -find the nearest # using the reduced costs of a     */
+/*                     fractional 2-matching as the edgelengths. If either */
+/*                     of the optional arguments PRICED or BASIC is        */
+/*                     specified then the 2-matching used will be either   */
+/*                     priced against the complete edgeset or converted to */
+/*                     a basic optimal solution (or both).                 */
+/*            EDGEGEN GREEDY_TOUR                                          */
+/*                    -find a greedy tour                                  */
+/*            EDGEGEN NN_TOUR #                                            */
+/*                    -find # nearest-neighbor tours                       */
+/*            EDGEGEN RANDOM_TOUR #                                        */
+/*                    -find # random tours                                 */
+/*            EDGEGEN TWOOPT_TOUR #                                        */
+/*                    -find # 2-opt tours                                  */
+/*            EDGEGEN TWOPT5_TOUR #                                        */
+/*                    -find # 2.5-opt tours                                */
+/*            EDGEGEN THREEOPT_TOUR #                                      */
+/*                    -find # 3-opt tours                                  */
+/*            EDGEGEN LINKERN #1 #2 [QUADNEAREST #3] [NEAREST #4]          */
+/*                              [GREEDY_START | NN_START | RANDOM_START]   */
+/*                    -find #1 Iterated Lin-Kernighan tours using #2 kicks.*/
+/*                     The good edgeset can be specified by the optional   */
+/*                     arguments QUADNEAREST and NEAREST (the two can be   */
+/*                     used together). The initial tours can be specfied   */
+/*                     by using one of GREEDY_START or NN_START or         */
+/*                     RANDOM_START.                                       */
+/*            EDGEGEN NN_TWOMATCH #                                        */
+/*                    -find # nearest-neighbor 2-matchings                 */
+/*            EDGEGEN TREE                                                 */
+/*                    -find a minimum weight spanning tree.                */
+/*            EDGEGEN FRAC_TWOMATCH [PRICED] [BASIC]                       */
+/*                    -find a minmum weight 2-matching (priced against the */
+/*                     complete edgeset) (that is a basic optimal solution)*/
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "edgegen.h"
+#include "kdtree.h"
+#include "linkern.h"
+#include "fmatch.h"
+
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+
+typedef struct intptr {
+    int this;
+    struct intptr *next;
+} intptr;
+
+static intptr **table = (intptr **) NULL;
+static int      tabletotal = 0;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    call_kdtree_build (CCkdtree *kt, int ncount, CCdatagroup *dat,
+        double *wcoord, int *built_a_tree),
+    call_nearest (int ncount, CCdatagroup *dat, double *wcoord, int nearnum,
+        CCkdtree *kt),
+    work_nearest (CCkdtree *kt, int ncount, int nearnum, CCdatagroup *dat,
+        double *wcoord, int *ecount, int **elist),
+    call_quadnearest (int ncount, CCdatagroup *dat, double *wcoord, int nearnum,
+        CCkdtree *kt),
+    work_quadnearest (CCkdtree *kt, int ncount, int nearnum, CCdatagroup *dat,
+        double *wcoord, int *ecount, int **elist),
+    call_random_tour (int ncount, CCdatagroup *dat, int number),
+    call_nearest_tour (int ncount, CCdatagroup *dat, int number, CCkdtree *kt),
+    work_nearest_tour (CCkdtree *kt, int ncount, int start, CCdatagroup *dat,
+        int *tour, double *val),
+    call_greedy_tour (int ncount, CCdatagroup *dat, CCkdtree *kt),
+    call_twoopt_tour (int ncount, CCdatagroup *dat, CCkdtree *kt, int number,
+        int two_and_a_half, int use_3opt),
+    call_linkern (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        CCedgegengroup *plan),
+    call_nearest_twomatch (int ncount, CCdatagroup *dat, int number,
+        CCkdtree *kt),
+    call_f2match (int ncount, CCdatagroup *dat, CCkdtree *kt, int priceit,
+        int basic),
+    call_f2match_nearest (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        int number, int priceit, int basic),
+    call_spanning_tree (int ncount, CCdatagroup *dat, double *wcoord,
+        CCkdtree *kt),
+    f2match_initial_edgeset (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        int *ecount, int **elist, int **elen),
+    put_tour_in_table (int ncount, int *tour),
+    put_in_table (int i, int j),
+    general_put_in_table (int i, int j, int *added, intptr **tab);
+
+static void
+    randcycle (int ncount, int *cyc, CCdatagroup *dat, double *val);
+
+#else
+
+static int
+    call_kdtree_build (),
+    call_nearest (),
+    work_nearest (),
+    call_quadnearest (),
+    work_quadnearest (),
+    call_random_tour (),
+    call_nearest_tour (),
+    work_nearest_tour (),
+    call_greedy_tour (),
+    call_twoopt_tour (),
+    call_linkern (),
+    call_nearest_twomatch (),
+    call_f2match (),
+    call_f2match_nearest (),
+    call_spanning_tree (),
+    f2match_initial_edgeset (),
+    put_tour_in_table (),
+    put_in_table (),
+    general_put_in_table ();
+
+static void
+    randcycle ();
+
+#endif /* CC_PROTOTYPE_ANSI */
+
+CC_PTR_ALLOC_ROUTINE (intptr, intptralloc, intptrchunklist, intptrfreelist)
+CC_PTR_FREE_ROUTINE (intptr, intptrfree, intptrfreelist)
+CC_PTR_FREE_WORLD_ROUTINE (intptr, intptrfree_world, intptrchunklist,
+        intptrfreelist)
+CC_PTR_LEAKS_ROUTINE (intptr, intptr_check_leaks, intptrchunklist,
+        intptrfreelist, this, int)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_edges (CCedgegengroup *plan, int ncount, CCdatagroup *dat,
+        double *wcoord, int *ecount, int **elist)
+#else
+int CCedgegen_edges (plan, ncount, dat, wcoord, ecount, elist)
+CCedgegengroup *plan;
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+int *ecount;
+int **elist;
+#endif
+{
+    int rval = 0;
+    int i;
+    int total, onlist;
+    CCkdtree kt;
+    int built_a_tree = 0;
+    double szeit = CCutil_zeit ();
+
+    *ecount = 0;
+    *elist = (int *) NULL;
+
+    if (ncount < 3) {
+        fprintf (stderr, "Cannot run edgegen in an %d node graph\n", ncount);
+        return 1;
+    }
+
+    table = CC_SAFE_MALLOC (ncount, intptr *);
+    if (!table) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++)
+        table[i] = (intptr *) NULL;
+    tabletotal = 0;
+
+    if (plan->nearest) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_nearest (ncount, dat, wcoord, plan->nearest, &kt)) {
+            fprintf (stderr, "call_nearest failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->quadnearest) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_quadnearest (ncount, dat, wcoord, plan->quadnearest, &kt)) {
+            fprintf (stderr, "call_quadnearest failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->tour.random_count) {
+        if (call_random_tour (ncount, dat, plan->tour.random_count)) {
+            fprintf (stderr, "call_random_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->tour.nearest_count) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_nearest_tour (ncount, dat, plan->tour.nearest_count, &kt)) {
+            fprintf (stderr, "call_nearest_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->tour.greedy) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_greedy_tour (ncount, dat, &kt)) {
+            fprintf (stderr, "call_greedy_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->tour.twoopt_count) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_twoopt_tour (ncount, dat, &kt, plan->tour.twoopt_count,
+                              0, 0)) {
+            fprintf (stderr, "call_twoopt_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->tour.twoopt5_count) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_twoopt_tour (ncount, dat, &kt, plan->tour.twoopt5_count,
+                              1, 0)) {
+            fprintf (stderr, "call_twoopt_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->tour.threeopt_count) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_twoopt_tour (ncount, dat, &kt, plan->tour.threeopt_count,
+                              0, 1)) {
+            fprintf (stderr, "call_threeopt_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->linkern.count) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_linkern (ncount, dat, &kt, plan)) {
+            fprintf (stderr, "call_linkern failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->want_tree) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_spanning_tree (ncount, dat, wcoord, &kt)) {
+            fprintf (stderr, "call_spanning_tree failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->nearest_twomatch_count) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_nearest_twomatch (ncount, dat, plan->nearest_twomatch_count,
+                                   &kt)) {
+            fprintf (stderr, "call_nearest_twomatch failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->f2match.wantit) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_f2match (ncount, dat, &kt, plan->f2match.priced,
+                          plan->f2match.basic)) {
+            fprintf (stderr, "call_f2match failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (plan->f2match_nearest.number) {
+        if (!built_a_tree) {
+            if (call_kdtree_build (&kt, ncount, dat, wcoord, &built_a_tree)) {
+                fprintf (stderr, "call_kdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (call_f2match_nearest (ncount, dat, &kt,
+               plan->f2match_nearest.number, plan->f2match_nearest.priced,
+               plan->f2match_nearest.basic)) {
+            fprintf (stderr, "call f2match_nearest failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    printf ("Edgegen total edges: %d (%.2f seconds)\n", tabletotal,
+                                             CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    if (tabletotal) {
+        int j = 0;
+        intptr *ip, *ipnext;
+
+        *elist = CC_SAFE_MALLOC (2 * tabletotal, int);
+        if (!(*elist)) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        *ecount = tabletotal;
+        for (i = 0; i < ncount; i++) {
+            for (ip = table[i]; ip; ip = ipnext) {
+                ipnext =  ip->next;
+                (*elist)[j++] = i;
+                (*elist)[j++] = ip->this;
+                intptrfree (ip);
+            }
+            table[i] = (intptr *) NULL;
+        }
+    }
+
+    if (intptr_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding intptrs in kdnear\n",
+                 total - onlist);
+    }
+
+
+CLEANUP:
+
+    if (built_a_tree)
+        CCkdtree_free (&kt);
+    intptrfree_world ();
+    CC_IFFREE (table, intptr *);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_kdtree_build (CCkdtree *kt, int ncount, CCdatagroup *dat,
+        double *wcoord, int *built_a_tree)
+#else
+static int call_kdtree_build (kt, ncount, dat, wcoord, built_a_tree)
+CCkdtree *kt;
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+int *built_a_tree;
+#endif
+{
+    double tzeit;
+
+    *built_a_tree = 0;
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        tzeit = CCutil_zeit ();
+        if (CCkdtree_build (kt, ncount, dat, wcoord)) {
+            fprintf (stderr, "CCkdtree_build failed\n");
+            return 1;
+        }
+        printf ("Built CCkdtree: %.2f (seconds)\n", CCutil_zeit () - tzeit);
+        *built_a_tree = 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCedgegen_init_edgegengroup (CCedgegengroup *plan)
+#else
+void CCedgegen_init_edgegengroup (plan)
+CCedgegengroup *plan;
+#endif
+{
+    plan->linkern.count = 0;
+    plan->linkern.quadnearest = 0;
+    plan->linkern.nearest = 0;
+    plan->linkern.greedy_start = 0;
+    plan->linkern.random_start = 0;
+    plan->linkern.nearest_start = 0;
+    plan->linkern.nkicks = 0;
+
+    plan->tour.twoopt_count = 0;
+    plan->tour.twoopt5_count = 0;
+    plan->tour.threeopt_count = 0;
+    plan->tour.greedy = 0;
+    plan->tour.nearest_count = 0;
+    plan->tour.random_count = 0;
+
+    plan->f2match.wantit = 0;
+    plan->f2match.basic = 0;
+    plan->f2match.priced = 0;
+
+    plan->f2match_nearest.number = 0;
+    plan->f2match_nearest.basic = 0;
+    plan->f2match_nearest.priced = 0;
+
+    plan->nearest = 0;
+    plan->quadnearest = 0;
+    plan->want_tree = 0;
+    plan->nearest_twomatch_count = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_nearest (int ncount, CCdatagroup *dat, double *wcoord,
+        int nearnum, CCkdtree *kt)
+#else
+static int call_nearest (ncount, dat, wcoord, nearnum, kt)
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+int nearnum;
+CCkdtree *kt;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    int current = tabletotal;
+    int tcount = 0;
+    int *tlist = (int *) NULL;
+    int i;
+
+
+    if (work_nearest (kt, ncount, nearnum, dat, wcoord, &tcount, &tlist)) {
+        fprintf (stderr, "work_nearest failed\n");
+        return 1;
+    }
+    for (i = 0; i < tcount; i++) {
+        if (put_in_table (tlist[2 * i], tlist[(2 * i) + 1])) {
+            fprintf (stderr, "put_in_table failed\n");
+            CC_IFFREE (tlist, int);
+            return 1;
+        }
+    }
+
+    printf ("Nearest added %d edges (%.2f seconds)\n",
+                 tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    CC_IFFREE (tlist, int);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int work_nearest (CCkdtree *kt, int ncount, int nearnum,
+         CCdatagroup *dat, double *wcoord, int *ecount, int **elist)
+#else
+static int work_nearest (kt, ncount, nearnum, dat, wcoord, ecount, elist)
+CCkdtree *kt;
+int ncount, nearnum;
+CCdatagroup *dat;
+double *wcoord;
+int *ecount, **elist;
+#endif
+{
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        if (CCkdtree_k_nearest (kt, ncount, nearnum, dat, wcoord,
+                               1, ecount, elist)) {
+            fprintf (stderr, "CCkdtree_k-nearest failed\n");
+            return 1;
+        }
+    } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        if (CCedgegen_x_k_nearest (ncount, nearnum, dat, wcoord, 1, ecount,
+                                   elist)) {
+            fprintf (stderr, "CCedgegen_x_k_nearest failed\n");
+            return 1;
+        }
+    } else {
+        if (CCedgegen_junk_k_nearest (ncount, nearnum, dat, wcoord, 1, ecount,
+                                      elist)) {
+            fprintf (stderr, "CCedgegen_junk_k_nearest failed\n");
+            return 1;
+        }
+    }
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_quadnearest (int ncount, CCdatagroup *dat, double *wcoord,
+        int nearnum, CCkdtree *kt)
+#else
+static int call_quadnearest (ncount, dat, wcoord, nearnum, kt)
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+int nearnum;
+CCkdtree *kt;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    int current = tabletotal;
+    int tcount = 0;
+    int *tlist = (int *) NULL;
+    int i;
+
+    if (work_quadnearest (kt, ncount, nearnum, dat, wcoord, &tcount, &tlist)) {
+        fprintf (stderr, "work_nearest failed\n");
+        return 1;
+    }
+
+    for (i = 0; i < tcount; i++) {
+        if (put_in_table (tlist[2 * i], tlist[(2 * i) + 1])) {
+            fprintf (stderr, "put_in_table failed\n");
+            CC_IFFREE (tlist, int);
+            return 1;
+        }
+    }
+
+    printf ("Quad Nearest added %d edges (%.2f seconds)\n",
+                 tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    CC_IFFREE (tlist, int);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int work_quadnearest (CCkdtree *kt, int ncount, int nearnum,
+        CCdatagroup *dat, double *wcoord, int *ecount, int **elist)
+#else
+static int work_quadnearest (kt, ncount, nearnum, dat, wcoord, ecount, elist)
+CCkdtree *kt;
+int ncount, nearnum;
+CCdatagroup *dat;
+double *wcoord;
+int *ecount, **elist;
+#endif
+{
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        if (CCkdtree_quadrant_k_nearest (kt, ncount, nearnum, dat, wcoord,
+                               1, ecount, elist)) {
+            fprintf (stderr, "CCkdtree_k-nearest failed\n");
+            return 1;
+        }
+    } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        if (CCedgegen_x_quadrant_k_nearest (ncount, nearnum, dat, wcoord, 1,
+                                  ecount, elist)) {
+            fprintf (stderr, "CCedgegen_x_k_nearest failed\n");
+            return 1;
+        }
+    } else {
+        printf ("Cannot run quadrant nearest with JUNK norms\n");
+        printf ("Trying %d-nearest instead\n", 2 * nearnum);
+        fflush (stdout);
+        if (CCedgegen_junk_k_nearest (ncount, 2 * nearnum, dat, wcoord, 1,
+                            ecount, elist)) {
+            fprintf (stderr, "CCedgegen_junk_k_nearest failed\n");
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_random_tour (int ncount, CCdatagroup *dat, int number)
+#else
+static int call_random_tour (ncount, dat, number)
+int ncount;
+CCdatagroup *dat;
+int number;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    int current = tabletotal;
+    int round;
+    int *tour = (int *) NULL;
+    double tzeit, val;
+    int k;
+
+    printf ("Generate %d Random Tours\n", number);
+    fflush (stdout);
+
+    tour = CC_SAFE_MALLOC (ncount, int);
+    if (!tour)
+        return 1;
+
+    for (round = 0; round < number; round++) {
+        k = tabletotal;
+        tzeit = CCutil_zeit ();
+        randcycle (ncount, tour, dat, &val);
+        if (put_tour_in_table (ncount, tour)) {
+            fprintf (stderr, "put_tour_in_table failed\n");
+            CC_FREE (tour, int);
+            return 1;
+        }
+        printf ("  Random tour %d: %.0f, added %d edges (%.2f seconds)\n",
+                 round, val, tabletotal - k, CCutil_zeit () - tzeit);
+        fflush (stdout);
+    }
+
+    printf ("  TOTAL: Random tours added %d edges (%.2f seconds)\n",
+                 tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    CC_IFFREE (tour, int);
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_nearest_tour (int ncount, CCdatagroup *dat, int number,
+        CCkdtree *kt)
+#else
+static int call_nearest_tour (ncount, dat, number, kt)
+int ncount;
+CCdatagroup *dat;
+int number;
+CCkdtree *kt;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    int current = tabletotal;
+    int round;
+    int *tour = (int *) NULL;
+    double tzeit, val;
+    int k;
+
+    printf ("Generate %d Nearest Neighbor Tours\n", number);
+    fflush (stdout);
+
+    tour = CC_SAFE_MALLOC (ncount, int);
+    if (!tour)
+        return 1;
+
+    for (round = 0; round < number; round++) {
+        k = tabletotal;
+        tzeit = CCutil_zeit ();
+        if (work_nearest_tour (kt, ncount, CCutil_lprand () % ncount,
+                                        dat, tour, &val)) {
+            fprintf (stderr, "work_nearest_tour failed\n");
+            CC_FREE (tour, int);
+            return 1;
+        }
+        if (put_tour_in_table (ncount, tour)) {
+            fprintf (stderr, "put_tour_in_table failed\n");
+            CC_FREE (tour, int);
+            return 1;
+        }
+        printf ("  NN tour %d: %.0f, added %d edges (%.2f seconds)\n",
+                 round, val, tabletotal - k, CCutil_zeit () - tzeit);
+        fflush (stdout);
+    }
+
+    printf ("  TOTAL: Nearest tours added %d edges (%.2f seconds)\n",
+                 tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    CC_IFFREE (tour, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int work_nearest_tour (CCkdtree *kt, int ncount, int start,
+        CCdatagroup *dat, int *tour, double *val)
+#else
+static int work_nearest_tour (kt, ncount, start, dat, tour, val)
+CCkdtree *kt;
+int ncount, start;
+CCdatagroup *dat;
+int *tour;
+double *val;
+#endif
+{
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        if (CCkdtree_nearest_neighbor_tour (kt, ncount, start, dat, tour, val)) {
+            fprintf (stderr, "CCkdtree_nearest_neighbor_tour failed\n");
+            return 1;
+        }
+    } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        if (CCedgegen_x_nearest_neighbor_tour (ncount, start, dat, tour, val)) {
+            fprintf (stderr, "CCedgegen_x_nearest_neighbor_tour failed\n");
+            return 1;
+        }
+    } else {
+        if (CCedgegen_junk_nearest_neighbor_tour (ncount, start, dat, tour,
+                                                  val)) {
+            fprintf (stderr, "CCedgegen_junk_nearest_neighbor_tour failed\n");
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_greedy_tour (int ncount, CCdatagroup *dat, CCkdtree *kt)
+#else
+static int call_greedy_tour (ncount, dat, kt)
+int ncount;
+CCdatagroup *dat;
+CCkdtree *kt;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    int current = tabletotal;
+    int *tour = (int *) NULL;
+    double val;
+
+    tour = CC_SAFE_MALLOC (ncount, int);
+    if (!tour)
+        return 1;
+
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        if (CCkdtree_greedy_tour (kt, ncount, dat, tour, &val)) {
+            fprintf (stderr, "CCkdtree_greedy_tour failed\n");
+            CC_FREE (tour, int);
+            return 1;
+        }
+        if (put_tour_in_table (ncount, tour)) {
+            fprintf (stderr, "put_tour_in_table failed\n");
+            CC_FREE (tour, int);
+            return 1;
+        }
+        printf ("Greedy tour: %.0f, added %d edges (%.2f seconds)\n",
+                     val, tabletotal - current, CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        printf ("No X_NORM greedy tours, using nearest neighbor\n");
+        CC_FREE (tour, int);
+        return call_nearest_tour (ncount, dat, 1, kt);
+    } else {
+        printf ("No JUNK_NORM greedy tours, using nearest neighbor\n");
+        CC_FREE (tour, int);
+        return call_nearest_tour (ncount, dat, 1, kt);
+    }
+
+    CC_IFFREE (tour, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_twoopt_tour (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        int number, int two_and_a_half, int use_3opt)
+#else
+static int call_twoopt_tour (ncount, dat, kt, number, two_and_a_half,
+        use_3opt)
+int ncount;
+CCdatagroup *dat;
+CCkdtree *kt;
+int number;
+int two_and_a_half;
+int use_3opt;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    double ival, val, tzeit;
+    int k, round, current = tabletotal;
+    int *tour1 = (int *) NULL, *tour2 = (int *) NULL;
+
+    if (use_3opt)
+        printf ("Generate %d 3OPT Tours from Nearest Neighbor\n", number);
+    else if (two_and_a_half)
+        printf ("Generate %d 2.5OPT Tours from Nearest Neighbor\n", number);
+    else
+        printf ("Generate %d 2OPT Tours from Nearest Neighbor\n", number);
+    fflush (stdout);
+
+    tour1 = CC_SAFE_MALLOC (ncount, int);
+    if (!tour1)
+        return 1;
+    tour2 = CC_SAFE_MALLOC (ncount, int);
+    if (!tour2) {
+        CC_FREE (tour1, int);
+        return 1;
+    }
+
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        for (round = 0; round < number; round++) {
+            k = tabletotal;
+            tzeit = CCutil_zeit ();
+            if (work_nearest_tour (kt, ncount, CCutil_lprand () % ncount,
+                                        dat, tour1, &val)) {
+                fprintf (stderr, "work_nearest_tour failed\n");
+                CC_FREE (tour1, int);
+                CC_FREE (tour2, int);
+                return 1;
+            }
+            ival = val;
+            if (use_3opt) {
+                if (CCkdtree_3opt_tour (kt, ncount, dat, tour1, tour2, &val,
+                                      1)) {
+                    fprintf (stderr, "CCkdtree_3opt_tour failed\n");
+                    CC_FREE (tour1, int);
+                    CC_FREE (tour2, int);
+                    return 1;
+                }
+
+            } else {
+                if (CCkdtree_twoopt_tour (kt, ncount, dat, tour1, tour2, &val,
+                                        two_and_a_half, 1)) {
+                    fprintf (stderr, "CCkdtree_twoopt_tour failed\n");
+                    CC_FREE (tour1, int);
+                    CC_FREE (tour2, int);
+                    return 1;
+                }
+            }
+            if (put_tour_in_table (ncount, tour2)) {
+                fprintf (stderr, "put_tour_in_table failed\n");
+                CC_FREE (tour1, int);
+                CC_FREE (tour2, int);
+                return 1;
+            }
+            if (use_3opt)
+                printf ("  3OPT tour %d (from %.0f): %.0f, added %d edges (%.2f sec)\n",
+                 round, ival, val, tabletotal - k, CCutil_zeit () - tzeit);
+            else if (two_and_a_half)
+                printf ("  2.5OPT tour %d (from %.0f): %.0f, added %d edges (%.2f sec)\n",
+                 round, ival, val, tabletotal - k, CCutil_zeit () - tzeit);
+            else
+                printf ("  2OPT tour %d (from %.0f): %.0f, added %d edges (%.2f sec)\n",
+                 round, ival, val, tabletotal - k, CCutil_zeit () - tzeit);
+            fflush (stdout);
+        }
+    } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        if (use_3opt)
+            printf ("No X_NORM three-opt, using nearest neighbor\n");
+        else
+            printf ("No X_NORM two-opt, using nearest neighbor\n");
+        fflush (stdout);
+        CC_FREE (tour1, int);
+        CC_FREE (tour2, int);
+        return call_nearest_tour (ncount, dat, number, kt);
+    } else {
+        if (use_3opt)
+            printf ("No JUNK_NORM three-opt, using nearest neighbor\n");
+        else
+            printf ("No JUNK_NORM two-opt, using nearest neighbor\n");
+        fflush (stdout);
+        CC_FREE (tour1, int);
+        CC_FREE (tour2, int);
+        return call_nearest_tour (ncount, dat, number, kt);
+    }
+
+    if (use_3opt)
+        printf ("  TOTAL: 3-opt tours added %d edges (%.2f seconds)\n",
+                     tabletotal - current, CCutil_zeit () - szeit);
+    else if (two_and_a_half)
+        printf ("  TOTAL: 2.5-opt tours added %d edges (%.2f seconds)\n",
+                    tabletotal - current, CCutil_zeit () - szeit);
+    else
+        printf ("  TOTAL: 2-opt tours added %d edges (%.2f seconds)\n",
+                     tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    CC_IFFREE (tour1, int);
+    CC_IFFREE (tour2, int);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_linkern (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        CCedgegengroup *plan)
+#else
+static int call_linkern (ncount, dat, kt, plan)
+int ncount;
+CCdatagroup *dat;
+CCkdtree *kt;
+CCedgegengroup *plan;
+#endif
+{
+    int *tour = (int *) NULL, *gtour = (int *) NULL, *itour = (int *) NULL;
+    double val, gval, ival;
+    double szeit = CCutil_zeit ();
+    double tzeit;
+    int i, k, round;
+    int current = tabletotal;
+    int ecount = 0, *elist = (int *) NULL;
+    int rval = 0;
+
+    printf ("Generate %d Linkern Tours (", plan->linkern.count);
+    if (plan->linkern.greedy_start)
+        printf ("Greedy, ");
+    else if (plan->linkern.random_start)
+        printf ("Random, ");
+    else
+        printf ("Nneigh, ");
+    printf ("%d kicks, ", plan->linkern.nkicks);
+    if (plan->linkern.nearest == 0) {
+        printf ("Quad-%d Edgeset)\n", (plan->linkern.quadnearest ?
+                               plan->linkern.quadnearest : 3));
+    } else {
+        if (plan->linkern.quadnearest == 0) {
+            printf ("Near-%d Edgeset)\n", plan->linkern.nearest);
+        } else {
+            printf ("Quad-%d + Near-%d Edgeset)\n",
+                plan->linkern.quadnearest, plan->linkern.nearest);
+        }
+    }
+
+    /* Build an initial edgeset */
+
+    if (plan->linkern.nearest == 0 && plan->linkern.quadnearest == 0) {
+        if (work_quadnearest (kt, ncount, 3, dat, (double *) NULL,
+                              &ecount, &elist)) {
+            fprintf (stderr, "work_quadnearest failed\n");
+            return 1;
+        }
+    } else {
+        if (plan->linkern.nearest == 0) {
+            if (work_quadnearest (kt, ncount, plan->linkern.quadnearest,
+                                  dat, (double *) NULL, &ecount, &elist)) {
+                fprintf (stderr, "work_quadnearest failed\n");
+                return 1;
+            }
+        } else if (plan->linkern.quadnearest == 0) {
+            if (work_nearest (kt, ncount, plan->linkern.nearest,
+                              dat, (double *) NULL, &ecount, &elist)) {
+                fprintf (stderr, "work_nearest failed\n");
+                return 1;
+            }
+        } else {
+            intptr **tab = (intptr **) NULL;
+            int tcount, *tlist = (int *) NULL;
+            int j, added;
+            intptr *ip, *ipnext;
+
+            tab = CC_SAFE_MALLOC (ncount, intptr *);
+            if (!tab)
+                return 1;
+            for (i = 0; i < ncount; i++)
+                tab[i] = (intptr *) NULL;
+            ecount = 0;
+
+            if (work_quadnearest (kt, ncount, plan->linkern.quadnearest,
+                                  dat, (double *) NULL, &tcount, &tlist)) {
+                fprintf (stderr, "work_quadnearest failed\n");
+                return 1;
+            }
+            for (i = 0; i < tcount; i++) {
+                if (general_put_in_table (tlist[2 * i], tlist[(2 * i) + 1],
+                                          &added, tab)) {
+                    fprintf (stderr, "general_put_in_table failed\n");
+                    CC_FREE (tab, intptr *);
+                    return 1;
+                }
+                ecount += added;
+            }
+            CC_IFFREE (tlist, int);
+
+            if (work_nearest (kt, ncount, plan->linkern.nearest,
+                                  dat, (double *) NULL, &tcount, &tlist)) {
+                fprintf (stderr, "work_quadnearest failed\n");
+                return 1;
+            }
+            for (i = 0; i < tcount; i++) {
+                if (general_put_in_table (tlist[2 * i], tlist[(2 * i) + 1],
+                                          &added, tab)) {
+                    fprintf (stderr, "general_put_in_table failed\n");
+                    CC_FREE (tab, intptr *);
+                    return 1;
+                }
+                ecount += added;
+            }
+            CC_IFFREE (tlist, int);
+
+            elist = CC_SAFE_MALLOC (2 * ecount, int);
+            if (!elist) {
+                CC_FREE (tab, intptr *);
+                return 1;
+            }
+            for (j = 0, i = 0; i < ncount; i++) {
+                for (ip = tab[i]; ip; ip = ipnext) {
+                    ipnext =  ip->next;
+                    elist[j++] = i;
+                    elist[j++] = ip->this;
+                    intptrfree (ip);
+                }
+                tab[i] = (intptr *) NULL;
+            }
+            CC_FREE (tab, intptr *);
+        }
+    }
+    printf ("Initial Edgeset: %d\n", ecount);
+    fflush (stdout);
+
+    if (plan->linkern.greedy_start &&
+       ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE)) {
+        gtour = CC_SAFE_MALLOC (ncount, int);
+        if (!gtour) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        tzeit = CCutil_zeit ();
+        if (CCkdtree_greedy_tour (kt, ncount, dat, gtour, &gval)) {
+            fprintf (stderr, "CCkdtree_greedy_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Greedy tour: %.0f (%.2f seconds)\n",
+                     gval, CCutil_zeit () - tzeit);
+        fflush (stdout);
+    }
+
+    tour = CC_SAFE_MALLOC (ncount, int);
+    if (!tour) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    itour = CC_SAFE_MALLOC (ncount, int);
+    if (!itour) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (round = 0; round < plan->linkern.count; round++) {
+        tzeit = CCutil_zeit ();
+        k = tabletotal;
+        if (gtour != (int *) NULL) {
+            for (i = 0; i < ncount; i++)
+                itour[i] = gtour[i];
+            val = gval;
+            ival = gval;
+        } else if (plan->linkern.random_start) {
+            randcycle (ncount, itour, dat, &val);
+            ival = val;
+        } else {
+            if (work_nearest_tour (kt, ncount, CCutil_lprand () % ncount,
+                                        dat, itour, &val)) {
+                fprintf (stderr, "work_nearest_tour failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            ival = val;
+        }
+
+        if (CClinkern_tour (ncount, dat, ecount, elist, 100000000,
+             plan->linkern.nkicks, itour, tour, &val, 1, -1.0, -1.0,
+            (char *) NULL)) {
+            fprintf (stderr, "CClinkern_tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+
+        if (put_tour_in_table (ncount, tour)) {
+            fprintf (stderr, "put_tour_in_table failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("  LK tour %d (from %.0f): %.0f, added %d edges (%.2f sec)\n",
+                 round, ival, val, tabletotal - k, CCutil_zeit () - tzeit);
+        fflush (stdout);
+    }
+
+    printf ("  TOTAL: Linkern tours added %d edges (%.2f seconds)\n",
+                 tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (tour, int);
+    CC_IFFREE (itour, int);
+    CC_IFFREE (gtour, int);
+    CC_IFFREE (elist, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_f2match (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        int priceit, int basic)
+#else
+static int call_f2match (ncount, dat, kt, priceit, basic)
+int ncount;
+CCdatagroup *dat;
+CCkdtree *kt;
+int priceit, basic;
+#endif
+{
+    int *mat = (int *) NULL;
+    int ecount;
+    int *elist = (int *) NULL;
+    int *elen = (int *) NULL;
+    int i;
+    double val;
+
+    if (f2match_initial_edgeset (ncount, dat, kt, &ecount, &elist, &elen)) {
+        fprintf (stderr, "f2match_initial_edgeset failed\n");
+        return 1;
+    }
+
+    mat = CC_SAFE_MALLOC((6 * ncount) + 1, int);
+    if (!mat) {
+        CC_FREE (elist, int);
+        CC_FREE (elen, int);
+        return 1;
+    }
+
+    if (priceit)
+        i = CCfmatch_fractional_2match (ncount, ecount, elist, elen, dat, &val,
+                    mat, (int *) NULL, (int *) NULL, basic);
+    else
+        i = CCfmatch_fractional_2match (ncount, ecount, elist, elen,
+                   (CCdatagroup *) NULL, &val, mat, (int *) NULL,
+                   (int *) NULL, basic);
+    if (i) {
+        fprintf (stderr, "CCfmatch_fractional_2match failed\n");
+        CC_FREE (mat, int);
+        CC_FREE (elist, int);
+        CC_FREE (elen, int);
+        return 1;
+    }
+
+    i = 0;
+    while (mat[i] != -1) {
+        if (put_in_table (mat[i], mat[i + 1])) {
+            fprintf (stderr, "put_in_table failed\n");
+            CC_FREE (mat, int);
+            CC_FREE (elist, int);
+            CC_FREE (elen, int);
+            return 1;
+        }
+        i += 3;
+    }
+
+    CC_IFFREE (mat, int);
+    CC_IFFREE (elist, int);
+    CC_IFFREE (elen, int);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_f2match_nearest (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        int number, int priceit, int basic)
+#else
+static int call_f2match_nearest (ncount, dat, kt, number, priceit, basic)
+int ncount;
+CCdatagroup *dat;
+CCkdtree *kt;
+int number, priceit, basic;
+#endif
+{
+    int ecount;
+    int *elist = (int *) NULL;
+    int *elen = (int *) NULL;
+    int *dual = (int *) NULL;
+    int dualmax, i;
+    double *dcoord = (double *) NULL;
+    double val;
+    int rval = 0;
+    int current = tabletotal;
+    double szeit = CCutil_zeit ();
+
+    if (f2match_initial_edgeset (ncount, dat, kt, &ecount, &elist, &elen)) {
+        fprintf (stderr, "f2match_initial_edgeset failed\n");
+        return 1;
+    }
+
+    dual = CC_SAFE_MALLOC (ncount, int);
+    if (!dual) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (priceit)
+        i = CCfmatch_fractional_2match (ncount, ecount, elist, elen, dat, &val,
+                    (int *) NULL, dual, (int *) NULL, basic);
+    else
+        i = CCfmatch_fractional_2match (ncount, ecount, elist, elen,
+                    (CCdatagroup *) NULL, &val, (int *) NULL, dual,
+                    (int *) NULL, basic);
+    if (i) {
+        fprintf (stderr, "CCfmatch_fractional_2match failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+    CC_FREE (elist, int);
+    CC_FREE (elen, int);
+    ecount = 0;
+
+    dualmax = dual[0];
+    for (i = 1; i < ncount; i++) {
+        if (dual[i] > dualmax)
+            dualmax = dual[i];
+    }
+
+    dcoord = CC_SAFE_MALLOC (ncount, double);
+    if (!dcoord) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++)
+        dcoord[i] = (dualmax - dual[i]) * 0.5;
+    CC_FREE (dual, int);
+
+    if (work_nearest (kt, ncount, number, dat, dcoord, &ecount, &elist)) {
+        fprintf (stderr, "work_nearest failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++) {
+        if (put_in_table (elist[2 * i], elist[(2 * i) + 1])) {
+            fprintf (stderr, "put_in_table failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    printf ("Fractional 2-match Nearest-%d added %d edges (%.2f seconds)\n",
+                 number, tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+
+CLEANUP:
+
+    CC_IFFREE (elist, int);
+    CC_IFFREE (elen, int);
+    CC_IFFREE (dual, int);
+    CC_IFFREE (dcoord, double);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int f2match_initial_edgeset (int ncount, CCdatagroup *dat, CCkdtree *kt,
+        int *ecount, int **elist, int **elen)
+#else
+static int f2match_initial_edgeset (ncount, dat, kt, ecount, elist, elen)
+int ncount;
+CCdatagroup *dat;
+CCkdtree *kt;
+int *ecount;
+int **elist, **elen;
+#endif
+{
+    intptr **tab = (intptr **) NULL;
+    int tcount, *tlist = (int *) NULL;
+    int *ttour = (int *) NULL;
+    int i, j, added;
+    intptr *ip, *ipnext;
+    double tval;
+    int count;
+
+    *ecount = 0;
+    *elist = (int *) NULL;
+    *elen = (int *) NULL;
+
+    tab = CC_SAFE_MALLOC (ncount, intptr *);
+    if (!tab)
+        return 1;
+    for (i = 0; i < ncount; i++)
+        tab[i] = (intptr *) NULL;
+    count = 0;
+
+    if (work_quadnearest (kt, ncount, 3, dat, (double *) NULL, &tcount,
+                          &tlist)) {
+        fprintf (stderr, "work_quadnearest failed\n");
+        CC_FREE (tab, intptr *);
+        return 1;
+    }
+    for (i = 0; i < tcount; i++) {
+        if (general_put_in_table (tlist[2 * i], tlist[(2 * i) + 1],
+                                  &added, tab)) {
+            fprintf (stderr, "general_put_in_table failed\n");
+            CC_FREE (tab, intptr *);
+            return 1;
+        }
+        count += added;
+    }
+    CC_IFFREE (tlist, int);
+
+    ttour = CC_SAFE_MALLOC (ncount, int);
+    if (!ttour) {
+        CC_FREE (tab, intptr *);
+        return 1;
+    }
+    if (work_nearest_tour (kt, ncount, CCutil_lprand () % ncount, dat, ttour,
+                           &tval)) {
+        fprintf (stderr, "work_nearest_tour failed\n");
+        CC_FREE (ttour, int);
+        return 1;
+    }
+    for (i = 1; i < ncount; i++) {
+        if (general_put_in_table (ttour[i-1], ttour[i], &added, tab)) {
+            fprintf (stderr, "general_put_in_table failed\n");
+            CC_FREE (tab, intptr *);
+            CC_FREE (ttour, int);
+            return 1;
+        }
+        count += added;
+    }
+    if (general_put_in_table (ttour[ncount - 1], ttour[0], &added, tab)) {
+        fprintf (stderr, "general_put_in_table failed\n");
+        CC_FREE (tab, intptr *);
+        CC_FREE (ttour, int);
+        return 1;
+    }
+    count += added;
+    CC_FREE (ttour, int);
+
+    *elist = CC_SAFE_MALLOC (2 * count, int);
+    if (!elist) {
+        CC_FREE (tab, intptr *);
+        return 1;
+    }
+    *elen = CC_SAFE_MALLOC (count, int);
+    if (!elen) {
+        CC_FREE (tab, intptr *);
+        CC_FREE (*elist, int);
+    }
+    *ecount = count;
+    for (j = 0, i = 0; i < ncount; i++) {
+        for (ip = tab[i]; ip; ip = ipnext) {
+            ipnext =  ip->next;
+            (*elist)[2 * j] = i;
+            (*elist)[(2 * j) + 1] = ip->this;
+            (*elen)[j++] = CCutil_dat_edgelen (i, ip->this, dat);
+            intptrfree (ip);
+        }
+        tab[i] = (intptr *) NULL;
+    }
+    CC_FREE (tab, intptr *);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_spanning_tree (int ncount, CCdatagroup *dat, double *wcoord,
+        CCkdtree *kt)
+#else
+static int call_spanning_tree (ncount, dat, wcoord, kt)
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+CCkdtree *kt;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    int current = tabletotal;
+    int *tree = (int *) NULL;
+    int i;
+    double val;
+
+    tree = CC_SAFE_MALLOC ((2 * ncount) - 2, int);
+    if (!tree)
+        return 1;
+
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        if (CCkdtree_prim_spanningtree (kt, ncount, dat, wcoord, tree, &val)) {
+            fprintf (stderr, "CCkdtree_prim_spanningtree failed\n");
+            CC_FREE (tree, int);
+            return 1;
+        }
+    } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        printf ("No X_NORM spanning tree\n");
+        CC_FREE (tree, int);
+        return 0;
+    } else {
+        printf ("No JUNK_NORM spanning tree\n");
+        CC_FREE (tree, int);
+        return 0;
+    }
+
+    for (i = 0; i < (ncount - 1); i++) {
+        if (put_in_table (tree[2 * i], tree[(2 * i) + 1])) {
+            fprintf (stderr, "put_in_table failed\n");
+            CC_FREE (tree, int);
+            return 0;
+        }
+    }
+    printf ("Spanning tree: %.0f, added %d edges (%.2f seconds)\n",
+             val, tabletotal - current, CCutil_zeit () - szeit);
+
+    CC_IFFREE (tree, int);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_nearest_twomatch (int ncount, CCdatagroup *dat, int number,
+        CCkdtree *kt)
+#else
+static int call_nearest_twomatch (ncount, dat, number, kt)
+int ncount;
+CCdatagroup *dat;
+int number;
+CCkdtree *kt;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    int current = tabletotal;
+    int round;
+    int *mat = (int *) NULL;
+    double tzeit, val;
+    int i, k;
+
+    printf ("Generate %d Nearest Neighbor 2-matchings\n", number);
+    fflush (stdout);
+
+    mat = CC_SAFE_MALLOC (2 * ncount, int);
+    if (!mat)
+        return 1;
+
+    if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        for (round = 0; round < number; round++) {
+            k = tabletotal;
+            tzeit = CCutil_zeit ();
+            if (CCkdtree_nearest_neighbor_2match (kt, ncount,
+                            CCutil_lprand () % ncount, dat, mat, &val)) {
+                fprintf (stderr, "CCkdtree_nearest_neighbor_2match failed\n");
+                CC_FREE (mat, int);
+                return 1;
+            }
+            for (i = 0; i < ncount; i++) {
+                if (put_in_table (mat[2 * i], mat[(2 * i) + 1])) {
+                    fprintf (stderr, "put_in_table failed\n");
+                    CC_FREE (mat, int);
+                    return 1;
+                }
+            }
+            printf ("  NN 2-mat %d: %.0f, added %d edges (%.2f seconds)\n",
+                     round, val, tabletotal - k, CCutil_zeit () - tzeit);
+            fflush (stdout);
+        }
+    } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        printf ("No X_NORM NN-2match, using NN-tour instead\n");
+        fflush (stdout);
+        CC_FREE (mat, int);
+        return call_nearest_tour (ncount, dat, number, kt);
+    } else {
+        printf ("No JUNK_NORM NN-2match, using NN-tour instead\n");
+        fflush (stdout);
+        CC_FREE (mat, int);
+        return call_nearest_tour (ncount, dat, number, kt);
+    }
+
+    printf ("  TOTAL: Nearest 2-matchings added %d edges (%.2f seconds)\n",
+                 tabletotal - current, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    CC_IFFREE (mat, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int put_tour_in_table (int ncount, int *tour)
+#else
+static int put_tour_in_table (ncount, tour)
+int ncount;
+int *tour;
+#endif
+{
+    int i;
+
+    for (i = 1; i < ncount; i++) {
+        if (put_in_table (tour[i-1], tour[i])) {
+            fprintf (stderr, "put_in_table failed\n");
+            return 1;
+        }
+    }
+    if (put_in_table (tour[ncount - 1], tour[0])) {
+        fprintf (stderr, "put_in_table failed\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int put_in_table (int i, int j)
+#else
+static int put_in_table (i, j)
+int i, j;
+#endif
+{
+    intptr *ip;
+
+    if (j < i) {
+        int temp;
+        SWAP(i, j, temp);
+    }
+
+    for (ip = table[i]; ip; ip = ip->next) {
+        if (ip->this == j) {
+            return 0;
+        }
+    }
+    ip = intptralloc ();
+    if (!ip) {
+        return 1;
+    }
+    ip->this = j;
+    ip->next = table[i];
+    table[i] = ip;
+    tabletotal++;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int general_put_in_table (int i, int j, int *added, intptr **tab)
+#else
+static int general_put_in_table (i, j, added, tab)
+int i, j;
+int *added;
+intptr **tab;
+#endif
+{
+    intptr *ip;
+
+    if (j < i) {
+        int temp;
+        SWAP(i, j, temp);
+    }
+
+    for (ip = tab[i]; ip; ip = ip->next) {
+        if (ip->this == j) {
+            *added = 0;
+            return 0;
+        }
+    }
+    ip = intptralloc ();
+    if (!ip) {
+        *added = 0;
+        return 1;
+    }
+    ip->this = j;
+    ip->next = tab[i];
+    tab[i] = ip;
+    *added = 1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void randcycle (int ncount, int *cyc, CCdatagroup *dat, double *val)
+#else
+static void randcycle (ncount, cyc, dat, val)
+int ncount;
+int *cyc;
+CCdatagroup *dat;
+double *val;
+#endif
+{
+    int i, k, temp;
+
+    for (i = 0; i < ncount; i++)
+        cyc[i] = i;
+
+    for (i = ncount; i > 1; i--) {
+        k = CCutil_lprand () % i;
+        SWAP (cyc[i - 1], cyc[k], temp);
+    }
+
+    *val = CCutil_dat_edgelen (cyc[ncount - 1], cyc[0], dat);
+    for (i = 1; i < ncount; i++)
+        (*val) += CCutil_dat_edgelen (cyc[i - 1], cyc[i], dat);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_read (char *egname, CCedgegengroup *plan)
+#else
+int CCedgegen_read (egname, plan)
+char *egname;
+CCedgegengroup *plan;
+#endif
+{
+    char buf[256];
+    char area[256];
+    char key[256];
+    char field[256];
+    char *p;
+    FILE *in;
+
+    CCedgegen_init_edgegengroup (plan);
+
+    in = fopen (egname, "r");
+    if (!in) {
+        perror (egname);
+        fprintf (stderr, "can't open %s for input\n", egname);
+        return 1;
+    }
+
+    while (fgets (buf, 254, in) != (char *) NULL) {
+        p = buf;
+        while (*p != '\0') {
+            if (*p == ':')
+                *p = ' ';
+             p++;
+        }
+        p = buf;
+        if (sscanf (p, "%s", area) != EOF) {
+            p += strlen (area);
+            while (*p == ' ')
+                p++;
+            if (!strcmp (area, "EDGEGEN")) {
+                if (sscanf (p, "%s", key) == EOF) {
+                    fprintf (stderr, "ERROR in EDGEGEN LINE - no keyword\n");
+                    return 1;
+                }
+                if (!strcmp (key, "NEAREST")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->nearest = atoi (field);
+                    } else {
+                        printf ("NEAREST count not given, using 1\n");
+                        plan->nearest = 1;
+                    }
+                } else if (!strcmp (key, "QUADNEAREST")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->quadnearest = atoi (field);
+                    } else {
+                        printf ("QUADNEAREST count not given, using 1\n");
+                        plan->quadnearest = 1;
+                    }
+                } else if (!strcmp (key, "TREE")) {
+                    plan->want_tree = 1;
+                } else if (!strcmp (key, "NN_TWOMATCH")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->nearest_twomatch_count = atoi (field);
+                    } else {
+                        printf ("NN_TWOMATCH count not given, using 1\n");
+                        plan->nearest_twomatch_count = 1;
+                    }
+                } else if (!strcmp (key, "GREEDY_TOUR")) {
+                    plan->tour.greedy = 1;
+                } else if (!strcmp (key, "NN_TOUR")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->tour.nearest_count = atoi (field);
+                    } else {
+                        printf ("NN_TOUR count not given, using 1\n");
+                        plan->tour.nearest_count = 1;
+                    }
+                } else if (!strcmp (key, "RANDOM_TOUR")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->tour.random_count = atoi (field);
+                    } else {
+                        printf ("RANDOM_TOUR count not given, using 1\n");
+                        plan->tour.random_count = 1;
+                    }
+                } else if (!strcmp (key, "TWOOPT_TOUR")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->tour.twoopt_count = atoi (field);
+                    } else {
+                        printf ("TWOOPT_TOUR count not given, using 1\n");
+                        plan->tour.twoopt_count = 1;
+                    }
+                } else if (!strcmp (key, "TWOOPT5_TOUR")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->tour.twoopt5_count = atoi (field);
+                    } else {
+                        printf ("TWOOPT5_TOUR count not given, using 1\n");
+                        plan->tour.twoopt5_count = 1;
+                    }
+                } else if (!strcmp (key, "THREEOPT_TOUR")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->tour.threeopt_count = atoi (field);
+                    } else {
+                        printf ("THREEOPT_TOUR count not given, using 1\n");
+                        plan->tour.threeopt_count = 1;
+                    }
+                } else if (!strcmp (key, "FRAC_TWOMATCH")) {
+                    plan->f2match.wantit = 1;
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    while (sscanf (p, "%s", field) != EOF) {
+                        if (!strcmp (field, "BASIC"))
+                            plan->f2match.basic = 1;
+                        else if (!strcmp (field, "PRICED"))
+                            plan->f2match.priced = 1;
+                        else
+                            printf ("Unknown option in FRAC_TWOMATCH\n");
+                        p += strlen (field);
+                        while (*p == ' ')
+                            p++;
+                    }
+                } else if (!strcmp (key, "FRAC_TWOMATCH_NEAREST")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    while (sscanf (p, "%s", field) != EOF) {
+                        if (!strcmp (field, "BASIC"))
+                            plan->f2match_nearest.basic = 1;
+                        else if (!strcmp (field, "PRICED"))
+                            plan->f2match_nearest.priced = 1;
+                        else
+                            plan->f2match_nearest.number = atoi (field);
+                        p += strlen (field);
+                        while (*p == ' ')
+                            p++;
+                    }
+                    if (plan->f2match_nearest.number == 0) {
+                        printf ("FRAC_TWOMATCH_NEAREST count not given, using 1\n");
+                        plan->f2match_nearest.number = 1;
+                    }
+                } else if (!strcmp (key, "LINKERN")) {
+                    p += strlen (key);
+                    while (*p == ' ')
+                        p++;
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->linkern.count = atoi (field);
+                        p += strlen (field);
+                        while (*p == ' ')
+                            p++;
+                    } else {
+                        printf ("LINKERN count not given, using 1\n");
+                        plan->linkern.count = 1;
+                    }
+                    if (sscanf (p, "%s", field) != EOF) {
+                        plan->linkern.nkicks = atoi (field);
+                        p += strlen (field);
+                        while (*p == ' ')
+                            p++;
+                    } else {
+                        printf ("LINKERN nkicks not given, using 10\n");
+                        plan->linkern.nkicks = 10;
+                    }
+                    while (sscanf (p, "%s", field) != EOF) {
+                        if (!strcmp (field, "GREEDY_START"))
+                            plan->linkern.greedy_start = 1;
+                        else if (!strcmp (field, "RANDOM_START"))
+                            plan->linkern.random_start = 1;
+                        else if (!strcmp (field, "NN_START"))
+                            plan->linkern.nearest_start = 1;
+                        else if (!strcmp (field, "NEAREST")) {
+                            p += strlen (field);
+                            while (*p == ' ')
+                                p++;
+                            if (sscanf (p, "%s", field) != EOF) {
+                                plan->linkern.nearest = atoi (field);
+                            } else {
+                                printf ("LINKERN NEAREST COUNT not given, using 5\n");
+                                plan->linkern.nearest = 5;
+                                break;
+                            }
+                        } else if (!strcmp (field, "QUADNEAREST")) {
+                            p += strlen (field);
+                            while (*p == ' ')
+                                p++;
+                            if (sscanf (p, "%s", field) != EOF) {
+                                plan->linkern.quadnearest = atoi (field);
+                            } else {
+                                printf ("LINKERN QUADNEAREST COUNT not given, using 3\n");
+                                plan->linkern.quadnearest = 3;
+                                break;
+                            }
+                        } else {
+                            printf ("Unknown EDGEGEN LINKERN command %s\n",
+                                    field);
+                            fflush (stdout);
+                        }
+                        p += strlen (field);
+                        while (*p == ' ')
+                            p++;
+                    }
+                } else {
+                    printf ("Unknown EDGEGEN command: %s\n", key);
+                    fflush (stdout);
+                }
+            } else {
+                printf ("Cannot parse command line: %s\n", area);
+                fflush (stdout);
+            }
+        }
+    }
+    fclose (in);
+    printf ("\n");
+
+    if (plan->linkern.count) {
+        if (!plan->linkern.quadnearest && !plan->linkern.nearest)
+            plan->linkern.quadnearest = 3;
+        if (!plan->linkern.greedy_start && !plan->linkern.random_start)
+            plan->linkern.nearest_start = 1;
+        if (!plan->linkern.nkicks)
+            plan->linkern.nkicks = 10;
+    }
+
+    printf ("Edgegen Request:\n");
+    if (plan->nearest)
+        printf ("  Nearest %d\n", plan->nearest);
+    if (plan->quadnearest)
+        printf ("  Quad-Nearest %d\n", plan->quadnearest);
+    if (plan->f2match_nearest.number) {
+        printf ("  Frac 2-match Nearest %d (", plan->f2match_nearest.number);
+        if (plan->f2match_nearest.basic)
+            printf ("Basic ");
+        if (plan->f2match_nearest.priced)
+            printf ("Priced)\n");
+        else
+            printf ("Not Priced)\n");
+    }
+    if (plan->want_tree)
+        printf ("  Minimum Spanning Tree\n");
+    if (plan->nearest_twomatch_count)
+        printf ("  NN 2-matchings: %d\n", plan->nearest_twomatch_count);
+    if (plan->tour.random_count)
+        printf ("  Random Tours: %d\n", plan->tour.random_count);
+    if (plan->tour.nearest_count)
+        printf ("  NN Tours: %d\n", plan->tour.nearest_count);
+    if (plan->tour.greedy)
+        printf ("  Greedy Tour\n");
+    if (plan->tour.twoopt_count)
+        printf ("  2OPT Tours: %d\n", plan->tour.twoopt_count);
+    if (plan->tour.twoopt5_count)
+        printf ("  2.5OPT Tours: %d\n", plan->tour.twoopt5_count);
+    if (plan->tour.threeopt_count)
+        printf ("  3OPT Tours: %d\n", plan->tour.threeopt_count);
+    if (plan->linkern.count) {
+        printf ("  LK Tours: %d (", plan->linkern.count);
+        if (plan->linkern.greedy_start)
+            printf ("Greedy, ");
+        else if (plan->linkern.random_start)
+            printf ("Random, ");
+        else
+            printf ("NN, ");
+        if (!plan->linkern.nearest) {
+            printf ("Quad-%d, ", plan->linkern.quadnearest);
+        } else {
+            if (!plan->linkern.quadnearest) {
+                printf ("Near-%d, ", plan->linkern.nearest);
+            } else {
+                printf ("Quad-%d + Near-%d, ", plan->linkern.quadnearest,
+                                               plan->linkern.nearest);
+            }
+        }
+        printf ("%d Kicks)\n", plan->linkern.nkicks);
+    }
+    if (plan->f2match.wantit) {
+        printf ("  Frac 2-matching (");
+        if (plan->f2match.basic)
+            printf ("Basic ");
+        if (plan->f2match.priced)
+            printf ("Priced)\n");
+        else
+            printf ("Not Priced)\n");
+    }
+    printf ("\n");
+    fflush (stdout);
+
+    return 0;
+}
diff --git a/contrib/blossom/concorde97/EDGEGEN/eg_main.c b/contrib/blossom/concorde97/EDGEGEN/eg_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..b619011cdf5dcf415b1962212c808b0df524d496
--- /dev/null
+++ b/contrib/blossom/concorde97/EDGEGEN/eg_main.c
@@ -0,0 +1,405 @@
+/***************************************************************************/
+/*                                                                         */
+/*               CODE FOR TESTING EDGE GENERATION ROUTINES                 */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 25, 1995                                                */
+/*                                                                         */
+/*  For a short describtion see usage ()                                   */
+/*                                                                         */
+/*  Link with:                                                             */
+/*   edg_main.o xnear.o                                                    */
+/*   edgelen.o  allocrus.o urandom.o safe_io.o zeit.o bgetopt.o            */
+/*   edg2cyc.o  fastread.o getdata.o                                       */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "edgegen.h"
+
+static int norm = CC_EUCLIDEAN;
+static int seed = 0;
+static int nnodes_want = 0;
+static int nearnum = 0;
+static int quadnearnum = 0;
+static int f2match_nearnum = 0;
+static int usenodeweights = 0;
+static int random_weight_limit = 0;
+static int random_tour_count = 0;
+static int nearest_tour_count = 0;
+static int linkern_tour_count = 0;
+static int linkern_kicks = 100;
+static int use_greedy_in_linkern = 0;
+static int use_random_in_linkern = 0;
+static int linkern_nearnum = 0;
+static int linkern_quadnum = 0;
+static int twoopt_tour_count = 0;
+static int twoopt5_tour_count = 0;
+static int threeopt_tour_count = 0;
+static int nearest_twomatch_count = 0;
+static int find_greedy_tour = 0;
+static int find_fractional_2match = 0;
+static int find_spanning_tree = 0;
+static int find_delaunay_edges = 0;
+static int find_mlinkern_edges = 0;
+static int binary_in = 0;
+static int tsplib_in = 0;
+
+static char *nodefile = (char *) NULL;
+static char *weightfile = (char *) NULL;
+static char *outfile = (char *) NULL;
+static char *describefile = (char *) NULL;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+static void
+    usage (char *f);
+static int
+    parseargs (int ac, char **av);
+
+#else
+
+int
+    main ();
+static void
+    usage ();
+static int
+    parseargs ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    double szeit;
+    double *wcoord = (double *) NULL;
+    int ncount;
+    int rval = 0;
+    int ecount = 0;
+    int *elist = (int *) NULL;
+    CCdatagroup dat;
+    CCedgegengroup plan;
+
+
+    dat.x = (double *) NULL;
+    dat.y = (double *) NULL;
+    dat.z = (double *) NULL;
+    dat.adj = (int **) NULL;
+
+    seed = (int) CCutil_real_zeit();
+    if (parseargs (ac, av))
+        return 1;
+    CCutil_sprand (seed);
+
+    if ((!nnodes_want && !nodefile) || (tsplib_in && !nodefile)) {
+        usage (av[0]);
+        return 1;
+    }
+
+    if (tsplib_in) {
+        if (CCutil_gettsplib (nodefile, &ncount, &dat)) {
+            fprintf (stderr, "could not read the TSPLIB file\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        norm = dat.norm;
+    } else {
+        ncount = nnodes_want;
+        if (CCutil_getdata (nodefile, binary_in, norm, &ncount, &dat)) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (CCutil_init_dat_edgelen (&dat)) {
+        fprintf (stderr, "CCutil_init_dat_edgelen failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (usenodeweights) {
+        if (CCutil_getnodeweights (weightfile, ncount, random_weight_limit, &wcoord)) {
+            fprintf (stderr, "could not read the nodeweight file\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (describefile) {
+        if (CCedgegen_read (describefile, &plan)) {
+            fprintf (stderr, "CCedgegen_read failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    } else {
+        CCedgegen_init_edgegengroup (&plan);
+
+        plan.nearest = nearnum;
+        plan.quadnearest = quadnearnum;
+        plan.delaunay = find_delaunay_edges;
+        plan.mlinkern = find_mlinkern_edges;
+        plan.tour.random_count = random_tour_count;
+        plan.tour.nearest_count = nearest_tour_count;
+        plan.tour.greedy = find_greedy_tour;
+        plan.want_tree = find_spanning_tree;
+        plan.tour.twoopt_count = twoopt_tour_count;
+        plan.tour.twoopt5_count = twoopt5_tour_count;
+        plan.tour.threeopt_count = threeopt_tour_count;
+        if (linkern_tour_count) {
+            plan.linkern.count = linkern_tour_count;
+            if (!linkern_quadnum && !linkern_nearnum) {
+                linkern_quadnum = 3;
+            } else {
+                plan.linkern.quadnearest = linkern_quadnum;
+                plan.linkern.nearest = linkern_nearnum;
+            }
+            if (!use_greedy_in_linkern && !use_random_in_linkern) {
+                plan.linkern.nearest_start = 1;
+            } else {
+                plan.linkern.greedy_start = use_greedy_in_linkern;
+                plan.linkern.random_start = use_random_in_linkern;
+            }
+            plan.linkern.nkicks = linkern_kicks;
+        }
+        plan.nearest_twomatch_count = nearest_twomatch_count;
+        plan.f2match.wantit = find_fractional_2match;
+        if (f2match_nearnum) {
+            plan.f2match_nearest.number = f2match_nearnum;
+            plan.f2match_nearest.basic = 0;
+            plan.f2match_nearest.priced = 1;
+        }
+    }
+
+    szeit = CCutil_zeit ();
+
+    if (CCedgegen_edges (&plan, ncount, &dat, wcoord, &ecount, &elist)) {
+        fprintf (stderr, "CCedgegen_edges failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Edgegen running time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    if (outfile && ecount) {
+        if (CCutil_writeedges (ncount, outfile, ecount, elist, &dat)) {
+            fprintf (stderr, "Could not write the edge set\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+
+CLEANUP:
+
+    CCutil_freedatagroup (ncount, &dat);
+    CC_IFFREE (wcoord, double);
+    CC_IFFREE (elist, int);
+
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: CCutil_bigcunk free world failed\n");
+        return 1;
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "A:bB:C:dD:f:FGk:L:s:m:M:n:N:o:q:R:STuU:vw:W:x:y:0123456789?"))
+            != EOF)
+        switch (c) {
+        case 'A':
+            twoopt_tour_count = atoi (CCutil_bix_optarg);
+            break;
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'B':
+            twoopt5_tour_count = atoi (CCutil_bix_optarg);
+            break;
+        case 'C':
+            threeopt_tour_count = atoi (CCutil_bix_optarg);
+            break;
+        case 'd':
+            find_delaunay_edges = 1;
+            break;
+        case 'D':
+            describefile = CCutil_bix_optarg;
+            break;
+        case 'f':
+            f2match_nearnum = atoi (CCutil_bix_optarg);
+            break;
+        case 'F':
+            find_fractional_2match = 1;
+            break;
+        case 'G':
+            find_greedy_tour = 1;
+            break;
+        case 'k':
+            nnodes_want = atoi (CCutil_bix_optarg);
+            break;
+        case 'L':
+            linkern_tour_count = atoi (CCutil_bix_optarg);
+            break;
+        case 'm':
+            find_mlinkern_edges = atoi (CCutil_bix_optarg);
+            break;
+        case 'M':
+            nearest_twomatch_count = atoi (CCutil_bix_optarg);
+            break;
+        case 'n':
+            nearnum = atoi (CCutil_bix_optarg);
+            break;
+        case 'N':
+            nearest_tour_count = atoi (CCutil_bix_optarg);
+            break;
+        case 'o':
+            outfile = CCutil_bix_optarg;
+            break;
+        case 'q':
+            quadnearnum = atoi (CCutil_bix_optarg);
+            break;
+        case 'R':
+            linkern_kicks = atoi (CCutil_bix_optarg);
+            break;
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 'S':
+            find_spanning_tree = 1;
+            break;
+        case 'T':
+            tsplib_in = 1;
+            break;
+        case 'u':
+            use_greedy_in_linkern = 1;
+            use_random_in_linkern = 0;
+            break;
+        case 'U':
+            random_tour_count = atoi (CCutil_bix_optarg);
+            break;
+        case 'v':
+            use_random_in_linkern = 1;
+            use_greedy_in_linkern = 0;
+            break;
+        case 'w':
+            usenodeweights = 1;
+            weightfile = CCutil_bix_optarg;
+            break;
+        case 'W':
+            usenodeweights = 1;
+            random_weight_limit = atoi (CCutil_bix_optarg);
+            break;
+        case 'x':
+            linkern_quadnum = atoi (CCutil_bix_optarg);
+            break;
+        case 'y':
+            linkern_nearnum = atoi (CCutil_bix_optarg);
+            break;
+        case '0':
+            norm = CC_MAXNORM;
+            break;
+        case '1':
+            norm = CC_EUCLIDEAN_CEIL;
+            break;
+        case '2':
+            norm = CC_EUCLIDEAN;
+            break;
+        case '3':
+            norm = CC_EUCLIDEAN_3D;
+            break;
+        case '4':
+            norm = CC_IBM;
+            break;
+        case '5':
+            norm = CC_ATT;
+            break;
+        case '6':
+            norm = CC_GEOGRAPHIC;
+            break;
+        case '7':
+            norm = CC_MATRIXNORM;
+            break;
+        case '8':
+            norm = CC_DSJRANDNORM;
+            break;
+        case '9':
+            norm = CC_CRYSTAL;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+        default:
+            usage (av[0]);
+            return 1;
+        }
+    if (CCutil_bix_optind < ac)
+        nodefile = av[CCutil_bix_optind++];
+
+    if (CCutil_bix_optind > ac) {
+        usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "Usage: %s [- see below -] [dat file]\n", f);
+    fprintf (stderr, "   -b    dat file in binary-ints\n");
+    fprintf (stderr, "   -w f  node weight file\n");
+    fprintf (stderr, "   -W #  use random node weights, from 0 to # - 1\n");
+    fprintf (stderr, "   -k #  number of nodes for random problem\n");
+    fprintf (stderr, "   -s #  random seed\n");
+    fprintf (stderr, "   -D f  description file\n");
+    fprintf (stderr, "   -n #  find # nearest graph\n");
+    fprintf (stderr, "   -q #  find quadrant # nearest graph\n");
+    fprintf (stderr, "   -d    find Delaunay triangulation\n");
+    fprintf (stderr, "   -f #  find # nearest using f2match reduced costs\n");
+    fprintf (stderr, "   -U #  find # random tours\n");
+    fprintf (stderr, "   -N #  find # nearest neighbor tours\n");
+    fprintf (stderr, "   -G    find greedy tour\n");
+    fprintf (stderr, "   -(A B C) #  find # (2opt, 2.5opt, 3opt) tours\n");
+    fprintf (stderr, "   -L #  find # linkern tours\n");
+    fprintf (stderr, "   -m #  find # linkern matchings\n");
+    fprintf (stderr, "   -R #  use # kicks in linkern (default: 100)\n");
+    fprintf (stderr, "   -u    use greedy starting tour for linkern\n");
+    fprintf (stderr, "   -v    use random starting tours for linkern\n");
+    fprintf (stderr, "   -x #  use # quadnearest in linkern\n");
+    fprintf (stderr, "   -y #  use # nearest in linkern (can use x & y)\n");
+    fprintf (stderr, "   -M #  find # nearest neighbor 2-matchings\n");
+    fprintf (stderr, "   -S    find min spanning tree\n");
+    fprintf (stderr, "   -F    find fractional twomatch (not priced)\n");
+    fprintf (stderr, "   -o f  write the cycle or edge set to f\n");
+    fprintf (stderr, "   -T    the dat file is a TSPLIB file\n");
+    fprintf (stderr, "   -0    Max norm for edge lengths\n");
+    fprintf (stderr, "   -1    Ceiling Euclidean norm - from DSJ\n");
+    fprintf (stderr, "   -2    Rounded Euclidean norm (default)\n");
+    fprintf (stderr, "   -3    Rounded Euclidean 3D norm\n");
+    fprintf (stderr, "   -(4 5 6 7 8 9) IBM ATT GEO MATRIX DSJRAND CRYSTAL norm\n");
+}
diff --git a/contrib/blossom/concorde97/EDGEGEN/xnear.c b/contrib/blossom/concorde97/EDGEGEN/xnear.c
new file mode 100644
index 0000000000000000000000000000000000000000..2ad2284362152766c05cfa77c4c6f369384ea527
--- /dev/null
+++ b/contrib/blossom/concorde97/EDGEGEN/xnear.c
@@ -0,0 +1,1051 @@
+/***************************************************************************/
+/*                                                                         */
+/*              NEAREST NEIGHBORS FOR X-NORMS AND JUNK-NORMS               */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 2, 1995                                                    */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CCedgegen_x_k_nearest (int ncount, int k, CCdatagroup *dat,       */
+/*           double *wcoord, int wantlist, int *ecount, int **elist)       */
+/*      RETURNS the k_nearest neighbor graph (for X-Norms)                 */
+/*        -ncount is the number of nodes                                   */
+/*        -k is the number of nearest neighbors wanted                     */
+/*        -dat contains the info to generate edge lengths                  */
+/*        -wcoord are nodeweights for Held-Karp style edge lengths, using  */
+/*         len[i,j] + wcoord[i] + wcoord[j] (wcoord can be NULL)           */
+/*        -wantlist should be set to 0 if you don't want the edges         */
+/*        -ecount returns the number of edges if wantlist is 1             */
+/*        -elist returns the edges in end1 end2 format if wantlist is 1    */
+/*                                                                         */
+/*   int CCedgegen_x_quadrant_k_nearest (int ncount, int k,                */
+/*           CCdatagroup *dat, double *wcoord, int wantlist, int *ecount,  */
+/*           int **elist)                                                  */
+/*      RETURNS the quadrant k_nearest_graph (for X-Norms)                 */
+/*                                                                         */
+/*   int CCedgegen_x_node_k_nearest (CCxnear *xn, int n, int k,            */
+/*               int ncount, int *list)                                    */
+/*      RETURNS the k nearest neighbors from node n (for X-Norms           */
+/*        -xn is a structure built by a call to xnear_build ()             */
+/*        -list returns the neighbors of n. The calling routine should     */
+/*         be sure that list points to an array of length at least num.    */
+/*                                                                         */
+/*   int CCedgegen_x_node_quadrant_k_nearest (CCxnear *xn, int n, int k,   */
+/*           int ncount, int *list)                                        */
+/*      RETURNS the quadrant k nearest to node n (for X-Norms)             */
+/*        -xn is a structure built by a call to xnear_build ()             */
+/*        -list returns the neighbors of n. The calling routine should     */
+/*         be sure that list points to a sufficiently large array (4*num   */
+/*         for D2_SIZE norms and 8*num for D3_SIZE norms)                  */
+/*                                                                         */
+/*   int CCedgegen_x_node_nearest (CCxnear *xn, int ncount, int ni,        */
+/*           char *marks)                                                  */
+/*      RETURNS the nearest unmarked node to node n (as the return value)  */
+/*        -marks is an array. The entries that are nonzero correspond to   */
+/*         nodes that will not be looked at in the search.                 */
+/*                                                                         */
+/*   int CCedgegen_x_nearest_neighbor_tour (int ncount, int start,         */
+/*           CCdatagroup *dat, int *outcycle, double *val)                 */
+/*      RETURNS a nearest neighbor tour, starting at node start.           */
+/*        -outcycle will contain the tour if it is not NULL (the calling   */
+/*         routine should be sure it points to an array of length at       */
+/*         least ncount if it is not set to NULL)                          */
+/*        -val will return the length of the tour.                         */
+/*                                                                         */
+/*   int CCedgegen_junk_k_nearest (int ncount, int k, CCdatagroup *dat,    */
+/*             double *wcoord, int wantlist, int *ecount, int **elist)     */
+/*      RETURNS the k-nearest graph (for JUNK-Norms)                       */
+/*        -see x_k_nearest (above) for the variables                       */
+/*                                                                         */
+/*   int CCedgegen_junk_node_k_nearest (CCdatagroup *dat, double *wcoord,  */
+/*           int n, int k, int ncount, int *list)                          */
+/*      RETURNS the k nearest neighbors to node n (for JUNK-Norms)         */
+/*        -list returns the neighbors of n. The calling routine should     */
+/*         be sure that list points to an array of length at least num.    */
+/*                                                                         */
+/*   int CCedgegen_junk_node_nearest (CCdatagroup *dat, double *wcoord,    */
+/*           int ncount, int n, char *marks)                               */
+/*      RETURNS the nearest unmarked node to node n (as the return value)  */
+/*        -marks is an array, the nodes with marks[i] nonzero are ignored. */
+/*                                                                         */
+/*   int CCedgegen_junk_nearest_neighbor_tour (int ncount, int start,      */
+/*           CCdatagroup *dat, int *outcycle, double *val)                 */
+/*      RETURNS a nearest neighbor tour starting at node start. Note that  */
+/*        this will be slow for large problems (it is a quadratic routine) */
+/*        -see the describtion of x_nearest_neighbor_tour above            */
+/*                                                                         */
+/*   int CCedgegen_xnear_build (int ncount, CCdatagroup *dat,              */
+/*           double *wcoord, CCxnear *xn)                                  */
+/*      RETURNS the structure needed for calls to x_node_k_nearest and     */
+/*        x_quadrant_node_k_nearest (the calling routine should            */
+/*        be sure that xn points to such a structure). All this            */
+/*        routine does is permute the data so that the x coordinates       */
+/*        are in nonincreasing order.                                      */
+/*                                                                         */
+/*   void CCedgegen_xnear_free (int ncount, CCxnear *xn)                   */
+/*      FREES the xnear structure pointed to by xn                         */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*       All routines other than CCedgegen_xnear_free and                  */
+/*    CCedgegen_x_node_nearest return 0 on success and 1 on failure        */
+/*    (normally due to running out of memory).                             */
+/*       The X-Norm functions will also work for KD-Norms, but they are    */
+/*    much slower than the KD-Norm functions.                              */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "edgegen.h"
+
+#define BIGDOUBLE (1e30)
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+#define NEAR_HEAP_CUTOFF 100  /* When to switch from list to heap       */
+
+typedef struct shortedge {
+    double length;
+    int end;
+} shortedge;
+
+typedef struct intptr {
+    int this;
+    struct intptr *next;
+} intptr;
+
+static intptr **table = (intptr **) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    add_to_list_and_reset (int *list, int *lcount, shortedge *nearlist,
+        int nearnum, int *nodenames),
+    insert (int n, int m, shortedge *nearlist, CCdatagroup *dat,
+        double *wcoord),
+    x_quicksort (int *list, double *x, int l, int u);
+static int
+    run_x_k_nearest (int ncount, int num, CCdatagroup *dat, double *wcoord,
+        int wantlist, int *ecount, int **elist, int doquad),
+    put_in_table (int i, int j, int *added);
+
+#else
+
+static void
+    add_to_list_and_reset (),
+    insert (),
+    x_quicksort ();
+static int
+    run_x_k_nearest (),
+    put_in_table ();
+
+#endif
+
+
+CC_PTR_ALLOC_ROUTINE (intptr, intptralloc, intptrchunklist, intptrfreelist)
+CC_PTR_FREE_ROUTINE (intptr, intptrfree, intptrfreelist)
+CC_PTR_FREE_WORLD_ROUTINE (intptr, intptrfree_world, intptrchunklist,
+        intptrfreelist)
+CC_PTR_LEAKS_ROUTINE (intptr, intptr_check_leaks, intptrchunklist,
+        intptrfreelist, this, int)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_x_k_nearest (int ncount, int num, CCdatagroup *dat,
+       double *wcoord, int wantlist, int *ecount, int **elist)
+#else
+int CCedgegen_x_k_nearest (ncount, num, dat, wcoord, wantlist, ecount, elist)
+int ncount, num;
+CCdatagroup *dat;
+double *wcoord;
+int wantlist, *ecount, **elist;
+#endif
+{
+    return run_x_k_nearest (ncount, num, dat, wcoord, wantlist, ecount,
+                            elist, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_x_quadrant_k_nearest (int ncount, int num, CCdatagroup *dat,
+       double *wcoord, int wantlist, int *ecount, int **elist)
+#else
+int CCedgegen_x_quadrant_k_nearest (ncount, num, dat, wcoord, wantlist,
+       ecount, elist)
+int ncount, num;
+CCdatagroup *dat;
+double *wcoord;
+int wantlist, *ecount, **elist;
+#endif
+{
+    return run_x_k_nearest (ncount, num, dat, wcoord, wantlist, ecount,
+                            elist, 1);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_junk_k_nearest (int ncount, int num, CCdatagroup *dat,
+       double *wcoord, int wantlist, int *ecount, int **elist)
+#else
+int CCedgegen_junk_k_nearest (ncount, num, dat, wcoord, wantlist, ecount, elist)
+int ncount, num;
+CCdatagroup *dat;
+double *wcoord;
+int wantlist, *ecount, **elist;
+#endif
+{
+    return run_x_k_nearest (ncount, num, dat, wcoord, wantlist, ecount,
+                            elist, 0);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int run_x_k_nearest (int ncount, int num, CCdatagroup *dat,
+       double *wcoord, int wantlist, int *ecount, int **elist, int doquad)
+#else
+static int run_x_k_nearest (ncount, num, dat, wcoord, wantlist, ecount, elist,
+       doquad)
+int ncount, num;
+CCdatagroup *dat;
+double *wcoord;
+int wantlist, *ecount, **elist;
+int doquad;
+#endif
+{
+    int rval = 0;
+    int i, n;
+    intptr *ip, *ipnext;
+    int total, onlist;
+    int added, ntotal = 0;
+    int *list = (int *) NULL;
+    int goal, usex;
+    CCxnear xn;
+
+    xn.nodenames = (int *) NULL;
+    xn.invnames = (int *) NULL;
+    xn.w = (double *) NULL;
+    xn.dat.x = (double *) NULL;
+    xn.dat.y = (double *) NULL;
+    xn.dat.z = (double *) NULL;
+    xn.dat.adj = (int **) NULL;
+
+    if (wantlist) {
+        *ecount = 0;
+        *elist = (int *) NULL;
+    }
+
+    if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE ||
+        (dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        printf ("Using x-norm nearest code\n");
+        usex = 1;
+    } else {
+        printf ("Using junk-norm nearest code\n");
+        usex = 0;
+    }
+
+    if (wcoord != (double *) NULL) {
+        for (i = 0; i < ncount; i++) {
+            if (wcoord[i] < -0.00000001) {
+                fprintf (stderr, "Cannot use xnear with negative weights\n");
+                return 1;
+            }
+        }
+    }
+
+    if (doquad && dat->z != (double *) NULL)
+        goal = 8 * num;
+    else if (doquad)
+        goal = 4 * num;
+    else
+        goal = num;
+
+    if (usex) {
+        if (CCedgegen_xnear_build (ncount, dat, wcoord, &xn)) {
+            fprintf (stderr, "build_nodes failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    table = CC_SAFE_MALLOC (ncount, intptr *);
+    if (!table) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++)
+        table[i] = (intptr *) NULL;
+    list = CC_SAFE_MALLOC (goal, int);
+    if (!list) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (!usex && doquad) {
+        printf ("NOTE: Cannot run quadrant nearest with a JUNK norm.\n");
+        printf ("      Running nearest instead.\n");
+        fflush (stdout);
+    }
+
+    for (n = 0; n < ncount; n++) {
+        if (usex) {
+            if (doquad) {
+                if (CCedgegen_x_node_quadrant_k_nearest (&xn, n, num, ncount,
+                                                         list)) {
+                    fprintf (stderr, "x_node_quadrant_k_nearest failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+            } else {
+                if (CCedgegen_x_node_k_nearest (&xn, n, num, ncount, list)) {
+                    fprintf (stderr, "x_node_k_nearest failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+            }
+        } else {
+            if (CCedgegen_junk_node_k_nearest (dat, wcoord, n, num, ncount,
+                                               list)) {
+                fprintf (stderr, "junk_node_k_nearest_failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        for (i = 0; i < goal; i++) {
+            if (list[i] != -1) {
+                if (put_in_table (n, list[i], &added))  {
+                    fprintf (stderr, "put_in_table failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                } else {
+                    ntotal += added;
+                }
+            }
+        }
+        if (n % 1000 == 999) {
+            printf (".");
+            fflush (stdout);
+        }
+    }
+    printf (" %d edges\n", ntotal);
+    fflush (stdout);
+
+    if (wantlist) {
+        int j = 0;
+        *elist = CC_SAFE_MALLOC (2 * ntotal, int);
+        if (!(*elist)) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        *ecount = ntotal;
+        for (i = 0; i < ncount; i++) {
+            for (ip = table[i]; ip; ip = ipnext) {
+                ipnext =  ip->next;
+                (*elist)[j++] = i;
+                (*elist)[j++] = ip->this;
+                intptrfree (ip);
+            }
+            table[i] = (intptr *) NULL;
+        }
+    } else {
+        for (i = 0; i < ncount; i++) {
+            for (ip = table[i]; ip; ip = ipnext) {
+                ipnext =  ip->next;
+                intptrfree (ip);
+            }
+            table[i] = (intptr *) NULL;
+        }
+    }
+
+    if (intptr_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding intptrs in kdnear\n",
+                 total - onlist);
+    }
+
+CLEANUP:
+
+    intptrfree_world ();
+    CC_IFFREE (list, int);
+    CC_IFFREE (table, intptr *);
+    if (usex)
+        CCedgegen_xnear_free (ncount, &xn);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_x_node_quadrant_k_nearest (CCxnear *xn, int ni, int nearnum,
+       int ncount, int *list)
+#else
+int CCedgegen_x_node_quadrant_k_nearest (xn, ni, nearnum, ncount, list)
+CCxnear *xn;
+int ni, nearnum, ncount;
+int *list;
+#endif
+{
+    int i, j, ntotal = 0;
+    shortedge *nearlist = (shortedge *) NULL;
+    double scale;
+    int goal = (xn->dat.z == (double *) NULL ? 4 * nearnum : 8 * nearnum);
+    int n = xn->invnames[ni];
+
+    nearlist = CC_SAFE_MALLOC (nearnum + 1, shortedge);
+    if (!nearlist)
+        return 1;
+    for (i = 0; i < nearnum; i++)
+        nearlist[i].length = BIGDOUBLE;
+    nearlist[nearnum].length = -BIGDOUBLE;
+
+    if (xn->dat.norm == CC_GEOGRAPHIC)
+        scale = CC_GEOGRAPHIC_SCALE;
+    else if (xn->dat.norm == CC_ATT)
+        scale = CC_ATT_SCALE;
+    else
+    scale = 1.0;
+    if ((xn->dat.norm & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+        double ny = xn->dat.y[n];
+        double nz = xn->dat.z[n];
+        for (j = n - 1; j >= 0 &&
+                    (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+                    < nearlist[0].length; --j)  {
+            if (xn->dat.y[j] <= ny && xn->dat.z[j] <= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n - 1; j >= 0 &&
+                    (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+                    < nearlist[0].length; --j)  {
+            if (xn->dat.y[j] <= ny && xn->dat.z[j] >= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n - 1; j >= 0 &&
+                    (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+                    < nearlist[0].length; --j)  {
+            if (xn->dat.y[j] >= ny && xn->dat.z[j] <= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n - 1; j >= 0 &&
+                    (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+                    < nearlist[0].length; --j)  {
+            if (xn->dat.y[j] >= ny && xn->dat.z[j] >= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n + 1; j < ncount &&
+                    (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+                        < nearlist[0].length; j++) {
+            if (xn->dat.y[j] <= ny && xn->dat.z[j] <= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n + 1; j < ncount &&
+                    (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+                    < nearlist[0].length; j++) {
+            if (xn->dat.y[j] <= ny && xn->dat.z[j] >= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n + 1; j < ncount &&
+                    (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+                    < nearlist[0].length; j++) {
+            if (xn->dat.y[j] >= ny && xn->dat.z[j] <= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n + 1; j < ncount &&
+                    (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+                    < nearlist[0].length; j++) {
+            if (xn->dat.y[j] >= ny && xn->dat.z[j] >= nz)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+    } else {
+        double ny = xn->dat.y[n];
+        for (j = n - 1; j >= 0 &&
+                    (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+                    < nearlist[0].length; --j)  {
+            if (xn->dat.y[j] <= ny)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+            for (j = n - 1; j >= 0 &&
+                    (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+                    < nearlist[0].length; --j)  {
+            if (xn->dat.y[j] >= ny)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n + 1; j < ncount &&
+                    (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+                    < nearlist[0].length; j++) {
+            if (xn->dat.y[j] <= ny)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+        for (j = n + 1; j < ncount &&
+                    (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+                    < nearlist[0].length; j++) {
+            if (xn->dat.y[j] >= ny)
+                insert (n, j, nearlist, &(xn->dat), xn->w);
+        }
+        add_to_list_and_reset (list, &ntotal, nearlist, nearnum,
+                               xn->nodenames);
+    }
+
+    if (ntotal < goal) {
+        for (i = ntotal; i < goal; i++)
+            list[i] = -1;
+    }
+    CC_IFFREE (nearlist, shortedge);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void add_to_list_and_reset (int *list, int *lcount, shortedge *nearlist,
+        int nearnum, int *nodenames)
+#else
+static void add_to_list_and_reset (list, lcount, nearlist, nearnum, nodenames)
+int *list, *lcount;
+shortedge *nearlist;
+int nearnum;
+int *nodenames;
+#endif
+{
+    int i;
+
+    for (i = 0; i < nearnum; i++) {
+        if (nearlist[i].length < BIGDOUBLE) {
+            list[(*lcount)++] = nodenames[nearlist[i].end];
+            nearlist[i].length = BIGDOUBLE;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_x_node_k_nearest (CCxnear *xn, int ni, int nearnum, int ncount,
+        int *list)
+#else
+int CCedgegen_x_node_k_nearest (xn, ni, nearnum, ncount, list)
+CCxnear *xn;
+int ni, nearnum, ncount;
+int *list;
+#endif
+{
+    int i, j, ntotal;
+    shortedge *nearlist = (shortedge *) NULL;
+    double scale;
+    int n = xn->invnames[ni];
+
+    nearlist = CC_SAFE_MALLOC (nearnum + 1, shortedge);
+    if (!nearlist)
+        return 1;
+    for (i = 0; i < nearnum; i++)
+        nearlist[i].length = BIGDOUBLE;
+    nearlist[nearnum].length = -BIGDOUBLE;
+
+    if (xn->dat.norm == CC_GEOGRAPHIC)
+        scale = CC_GEOGRAPHIC_SCALE;
+    else if (xn->dat.norm == CC_ATT)
+        scale = CC_ATT_SCALE;
+    else
+        scale = 1.0;
+    for (j = n - 1; j >= 0 &&
+               (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+               < nearlist[0].length; --j)
+        insert (n, j, nearlist, &(xn->dat), xn->w);
+    for (j = n + 1; j < ncount &&
+               (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+               < nearlist[0].length; j++)
+        insert (n, j, nearlist, &(xn->dat), xn->w);
+
+    ntotal = 0;
+    for (i = 0; i < nearnum; i++) {
+        if (nearlist[i].length < BIGDOUBLE)
+            list[ntotal++] = xn->nodenames[nearlist[i].end];
+    }
+    if (ntotal < nearnum) {
+        fprintf (stderr, "WARNING: There do not exist %d neighbors\n", nearnum);
+        for (i = ntotal; i < nearnum; i++)
+            list[i] = -1;
+        return 1;
+    }
+
+    CC_IFFREE (nearlist, shortedge);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_x_node_nearest (CCxnear *xn, int ncount, int ni, char *marks)
+#else
+int CCedgegen_x_node_nearest (xn, ncount, ni, marks)
+CCxnear *xn;
+int ncount, ni;
+char *marks;
+#endif
+{
+    int n = xn->invnames[ni];
+    int j, bestnode = 0;
+    double scale, thisdist, bestdist = BIGDOUBLE;
+
+    if (xn->dat.norm == CC_GEOGRAPHIC)
+        scale = CC_GEOGRAPHIC_SCALE;
+    else if (xn->dat.norm == CC_ATT)
+        scale = CC_ATT_SCALE;
+    else
+        scale = 1.0;
+    for (j = n - 1; j >= 0 &&
+               (double) ((int)((xn->dat.x[n] - xn->dat.x[j]) * scale))
+               < bestdist; --j) {
+        if (!marks[xn->nodenames[j]]) {
+            thisdist = CCutil_dat_edgelen (n, j, &(xn->dat));
+            if (xn->w)
+                thisdist += (xn->w[n] + xn->w[j]);
+            if (thisdist < bestdist) {
+                bestdist = thisdist;
+                bestnode = j;
+            }
+        }
+    }
+    for (j = n + 1; j < ncount &&
+               (double) ((int)((xn->dat.x[j] - xn->dat.x[n]) * scale))
+               < bestdist; j++) {
+        if (!marks[xn->nodenames[j]]) {
+            thisdist = CCutil_dat_edgelen (n, j, &(xn->dat));
+            if (xn->w)
+                thisdist += (xn->w[n] + xn->w[j]);
+            if (thisdist < bestdist) {
+                bestdist = thisdist;
+                bestnode = j;
+            }
+        }
+    }
+    return xn->nodenames[bestnode];
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void insert (int n, int m, shortedge *nearlist, CCdatagroup *dat,
+        double *wcoord)
+#else
+static void insert (n, m, nearlist, dat, wcoord)
+int n, m;
+shortedge *nearlist;
+CCdatagroup *dat;
+double *wcoord;
+#endif
+{
+    int i;
+    int thisdist;
+
+    thisdist = CCutil_dat_edgelen (n, m, dat);
+
+    if (wcoord != (double *) NULL)
+        thisdist += (wcoord[n] + wcoord[m]);
+
+    if (thisdist < nearlist[0].length) {
+        for (i = 0; nearlist[i+1].length > thisdist; i++) {
+            nearlist[i].end = nearlist[i + 1].end;
+            nearlist[i].length = nearlist[i + 1].length;
+        }
+        nearlist[i].length = thisdist;
+        nearlist[i].end = m;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_junk_node_k_nearest (CCdatagroup *dat, double *wcoord, int n,
+        int nearnum, int ncount, int *list)
+#else
+int CCedgegen_junk_node_k_nearest (dat, wcoord, n, nearnum, ncount, list)
+CCdatagroup *dat;
+double *wcoord;
+int n, nearnum, ncount;
+int *list;
+#endif
+{
+    int i, j, ntotal;
+    shortedge *nearlist = (shortedge *) NULL;
+
+    nearlist = CC_SAFE_MALLOC (nearnum + 1, shortedge);
+    if (!nearlist)
+        return 1;
+    for (i = 0; i < nearnum; i++)
+        nearlist[i].length = BIGDOUBLE;
+    nearlist[nearnum].length = -BIGDOUBLE;
+
+    for (j = n - 1; j >= 0; j--) {
+        insert (n, j, nearlist, dat, wcoord);
+    }
+    for (j = n + 1; j < ncount; j++) {
+        insert (n, j, nearlist, dat, wcoord);
+    }
+
+    ntotal = 0;
+    for (i = 0; i < nearnum; i++) {
+        if (nearlist[i].length < BIGDOUBLE)
+            list[ntotal++] = nearlist[i].end;
+    }
+    if (ntotal < nearnum) {
+        fprintf (stderr, "WARNING: There do not exist %d neighbors\n", nearnum);
+        for (i = ntotal; i < nearnum; i++)
+            list[i] = -1;
+        return 1;
+    }
+
+    CC_IFFREE (nearlist, shortedge);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_junk_node_nearest (CCdatagroup *dat, double *wcoord, int ncount,
+        int n, char *marks)
+#else
+int CCedgegen_junk_node_nearest (dat, wcoord, ncount, n, marks)
+CCdatagroup *dat;
+double *wcoord;
+int ncount, n;
+char *marks;
+#endif
+{
+    int j, bestnode = 0;
+    double thisdist, bestdist = BIGDOUBLE;
+
+
+    if (wcoord) {
+        for (j = n - 1; j >= 0; j--) {
+            if (!marks[j]) {
+                thisdist = CCutil_dat_edgelen (n, j, dat) +
+                                       (wcoord[n] + wcoord[j]);
+                if (thisdist < bestdist) {
+                    bestdist = thisdist;
+                    bestnode = j;
+                }
+            }
+        }
+        for (j = n + 1; j < ncount; j++) {
+            if (!marks[j]) {
+                thisdist = CCutil_dat_edgelen (n, j, dat) +
+                                       (wcoord[n] + wcoord[j]);
+                if (thisdist < bestdist) {
+                    bestdist = thisdist;
+                    bestnode = j;
+                }
+            }
+        }
+    } else {
+        for (j = n - 1; j >= 0; j--) {
+            if (!marks[j]) {
+                thisdist = CCutil_dat_edgelen (n, j, dat);
+                if (thisdist < bestdist) {
+                    bestdist = thisdist;
+                    bestnode = j;
+                }
+            }
+        }
+        for (j = n + 1; j < ncount; j++) {
+            if (!marks[j]) {
+                thisdist = CCutil_dat_edgelen (n, j, dat);
+                if (thisdist < bestdist) {
+                    bestdist = thisdist;
+                    bestnode = j;
+                }
+            }
+        }
+    }
+
+    return bestnode;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_x_nearest_neighbor_tour (int ncount, int start, CCdatagroup *dat,
+        int *outcycle, double *val)
+#else
+int CCedgegen_x_nearest_neighbor_tour (ncount, start, dat, outcycle, val)
+int ncount, start;
+CCdatagroup *dat;
+int *outcycle;
+double *val;
+#endif
+{
+    double len;
+    int i, current, next;
+    CCxnear xn;
+    char *marks;
+
+    /*
+        printf ("Grow nearest neighbor tour from node %d\n", start);
+        fflush (stdout);
+    */
+
+    if (ncount < 3) {
+        fprintf (stderr, "Cannot find tour in an %d node graph\n", ncount);
+        return 1;
+    }
+    if ((dat->norm & CC_NORM_BITS) != CC_X_NORM_TYPE &&
+        (dat->norm & CC_NORM_BITS) != CC_KD_NORM_TYPE) {
+        fprintf (stderr, "Cannot run x_nearest with norm %d\n", dat->norm);
+        return 1;
+    }
+
+    if (CCedgegen_xnear_build (ncount, dat, (double *) NULL, &xn)) {
+        fprintf (stderr, "Unable to build xnear\n");
+        return 1;
+    }
+
+    marks = CC_SAFE_MALLOC (ncount, char );
+    if (!marks) {
+        CCedgegen_xnear_free (ncount, &xn);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++)
+        marks[i] = 0;
+
+
+    len = 0.0;
+    current = start;
+    if (outcycle != (int *) NULL)
+        outcycle[0] = start;
+
+    for (i = 1; i < ncount; i++) {
+        marks[current] = 1;
+        next = CCedgegen_x_node_nearest (&xn, ncount, current, marks);
+        if (outcycle != (int *) NULL)
+            outcycle [i] = next;
+        len += (double) CCutil_dat_edgelen (current, next, dat);
+        current = next;
+    }
+    len += (double) CCutil_dat_edgelen (current, start, dat);
+    *val = len;
+    CCedgegen_xnear_free (ncount, &xn);
+    CC_IFFREE (marks, char);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_junk_nearest_neighbor_tour (int ncount, int start,
+        CCdatagroup *dat, int *outcycle, double *val)
+#else
+int CCedgegen_junk_nearest_neighbor_tour (ncount, start, dat, outcycle, val)
+int ncount, start;
+CCdatagroup *dat;
+int *outcycle;
+double *val;
+#endif
+{
+    double len;
+    int i, current, next;
+    char *marks;
+
+    printf ("Grow nearest neighbor tour from node %d\n", start);
+    printf ("This is a JUNK norm, so expect a quadratic running time\n");
+    fflush (stdout);
+
+    if (ncount < 3) {
+        fprintf (stderr, "Cannot find tour in an %d node graph\n", ncount);
+        return 1;
+    }
+
+    marks = CC_SAFE_MALLOC (ncount, char );
+    if (!marks) {
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++)
+        marks[i] = 0;
+
+    len = 0.0;
+    current = start;
+    if (outcycle != (int *) NULL)
+        outcycle[0] = start;
+
+    for (i = 1; i < ncount; i++) {
+        marks[current] = 1;
+        next = CCedgegen_junk_node_nearest (dat, (double *) NULL, ncount,
+                                            current, marks);
+        if (outcycle != (int *) NULL)
+            outcycle [i] = next;
+        len += (double) CCutil_dat_edgelen (current, next, dat);
+        current = next;
+    }
+    len += (double) CCutil_dat_edgelen (current, start, dat);
+    *val = len;
+    CC_IFFREE (marks, char);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int put_in_table (int i, int j, int *added)
+#else
+static int put_in_table (i, j, added)
+int i, j;
+int *added;
+#endif
+{
+    intptr *ip;
+
+    if (j < i) {
+        int temp;
+        SWAP(i, j, temp);
+    }
+
+    for (ip = table[i]; ip; ip = ip->next)
+        if (ip->this == j) {
+            *added = 0;
+            return 0;
+        }
+    ip = intptralloc ();
+    if (!ip) {
+        *added = 0;
+        return 1;
+    }
+    ip->this = j;
+    ip->next = table[i];
+    table[i] = ip;
+    *added = 1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCedgegen_xnear_build (int ncount, CCdatagroup *dat, double *wcoord,
+        CCxnear *xn)
+#else
+int CCedgegen_xnear_build (ncount, dat, wcoord, xn)
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+CCxnear *xn;
+#endif
+{
+    int i;
+
+    xn->nodenames = (int *) NULL;
+    xn->invnames = (int *) NULL;
+    xn->w = (double *) NULL;
+    xn->dat.x = (double *) NULL;
+    xn->dat.y = (double *) NULL;
+    xn->dat.z = (double *) NULL;
+    xn->dat.adj = (int **) NULL;
+
+    xn->dat.norm = dat->norm;
+
+    xn->nodenames = CC_SAFE_MALLOC (ncount, int);
+    if (!xn->nodenames)
+        return 1;
+    for (i = 0; i < ncount; i++)
+        xn->nodenames[i] = i;
+    xn->dat.x = CC_SAFE_MALLOC (ncount, double);
+    if (!xn->dat.x) {
+        CC_FREE (xn->nodenames, int);
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        xn->dat.x[i] = dat->x[i];
+
+    for (i = 1; i < ncount && dat->x[i] >= dat->x[i - 1]; i++);
+    if (i < ncount) {
+        x_quicksort (xn->nodenames, xn->dat.x, 0, ncount - 1);
+    }
+
+    xn->invnames = CC_SAFE_MALLOC (ncount, int);
+    if (!xn->invnames) {
+        CC_FREE (xn->nodenames, int);
+        CCutil_freedatagroup (ncount, &(xn->dat));
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        xn->invnames[xn->nodenames[i]] = i;
+
+    xn->dat.y = CC_SAFE_MALLOC (ncount, double);
+    if (!xn->dat.y) {
+        CC_FREE (xn->nodenames, int);
+        CC_FREE (xn->invnames, int);
+        CCutil_freedatagroup (ncount, &(xn->dat));
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        xn->dat.y[i] = dat->y[xn->nodenames[i]];
+    if (dat->z != (double *) NULL) {
+        xn->dat.z = CC_SAFE_MALLOC (ncount, double);
+        if (!xn->dat.z) {
+            CC_FREE (xn->nodenames, int);
+            CC_FREE (xn->invnames, int);
+            CCutil_freedatagroup (ncount, &(xn->dat));
+            return 1;
+        }
+        for (i = 0; i < ncount; i++)
+            xn->dat.z[i] = dat->z[xn->nodenames[i]];
+    }
+    if (wcoord != (double *) NULL) {
+        xn->w = CC_SAFE_MALLOC (ncount, double);
+        if (!xn->w) {
+            CC_FREE (xn->nodenames, int);
+            CC_FREE (xn->invnames, int);
+            CCutil_freedatagroup (ncount, &(xn->dat));
+            return 1;
+        }
+        for (i = 0; i < ncount; i++)
+            xn->w[i] = wcoord[xn->nodenames[i]];
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCedgegen_xnear_free (int ncount, CCxnear *xn)
+#else
+void CCedgegen_xnear_free (ncount, xn)
+int ncount;
+CCxnear *xn;
+#endif
+{
+    CC_IFFREE (xn->nodenames, int);
+    CC_IFFREE (xn->invnames, int);
+    CC_IFFREE (xn->w, double);
+    CCutil_freedatagroup (ncount, &(xn->dat));
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void x_quicksort (int *list, double *x, int l, int u)
+#else
+static void x_quicksort (list, x, l, u)
+int *list;
+double *x;
+int l, u;
+#endif
+{
+    int i, j, itemp;
+    double t, dtemp;
+
+    if (l >= u)
+        return;
+
+    SWAP (x[l], x[(l+u)/2], dtemp);
+    SWAP (list[l], list[(l+u)/2], itemp);
+
+    i = l;
+    j = u + 1;
+    t = x[l];
+
+    while (1) {
+        do i++; while (i <= u && x[i] < t);
+        do j--; while (x[j] > t);
+        if (j < i) break;
+        SWAP (x[i], x[j], dtemp);
+        SWAP (list[i], list[j], itemp);
+    }
+    SWAP (x[l], x[j], dtemp);
+    SWAP (list[l], list[j], itemp);
+    x_quicksort (list, x, l, j - 1);
+    x_quicksort (list, x, i, u);
+}
diff --git a/contrib/blossom/concorde97/FMATCH/Makefile b/contrib/blossom/concorde97/FMATCH/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5279d1ed337adc0edb48f2ee37f524d6501ca218
--- /dev/null
+++ b/contrib/blossom/concorde97/FMATCH/Makefile
@@ -0,0 +1,33 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=fmatch.a
+LIBSRCS=fmatch.c
+LIBS=$(ROOT)/EDGEGEN/edgegen.a $(ROOT)/KDTREE/kdtree.a \
+     $(ROOT)/LINKERN/linkern.a $(ROOT)/UTIL/util.a
+ALLSRCS=fm_main.c $(LIBSRCS)
+
+all: fmatch $(LIB)
+
+fmatch: fm_main.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ -lm
+
+clean:
+	-rm -f *.$o $(LIB) fmatch
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+fm_main.$o:  fm_main.c  $(I)/machdefs.h $(I)/util.h     $(I)/fmatch.h   \
+        $(I)/kdtree.h   $(I)/edgegen.h  
+fmatch.$o:   fmatch.c   $(I)/machdefs.h $(I)/util.h     $(I)/fmatch.h   \
+        $(I)/kdtree.h   
diff --git a/contrib/blossom/concorde97/FMATCH/fm_main.c b/contrib/blossom/concorde97/FMATCH/fm_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..0800e5d11fd9cd7c7eb8b9a7bcca48d5abb43bd0
--- /dev/null
+++ b/contrib/blossom/concorde97/FMATCH/fm_main.c
@@ -0,0 +1,549 @@
+/***************************************************************************/
+/*                                                                         */
+/*                TEST PROGRAM FOR FRACTIONAL MATCHINGS                    */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 24, 1995  (cofeb24)                                     */
+/*                                                                         */
+/*  SEE short decsribtion in usage ().                                     */
+/*                                                                         */
+/*  Link with:                                                             */
+/*    SEE fmmake.grs                                                       */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "fmatch.h"
+#include "kdtree.h"
+#include "edgegen.h"
+
+static int norm = CC_EUCLIDEAN;
+static int wantbasic = 0;
+static char *edgefilename = (char *) NULL;
+static char *datfilename = (char *) NULL;
+static char *edgegenfname = (char *) NULL;
+static int dumpmatch = 0;
+static int dumpdual = 0;
+static int dumpbasis = 0;
+static int binary_in = 0;
+static int tsplib_in = 0;
+static int nnodes_want = 0;
+static int seed = 0;
+static int usenn2match = 0;
+static int quadtry = 2;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+
+static void
+    usage (char *f),
+    dump_match (int *thematching),
+    dump_dual (int *thedual, int ncount),
+    dump_basis (int *thebasis, int ncount);
+
+static int
+    parseargs (int ac, char **av),
+    getgraph (char *edgefile, CCdatagroup *dat, int *ncount, int *ecount,
+                     int **elist, int **elen);
+
+#else
+
+int
+    main ();
+
+static void
+    usage (),
+    dump_match (),
+    dump_dual (),
+    dump_basis ();
+
+static int
+    parseargs (),
+    getgraph ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    double v, szeit;
+    int ncount, ecount;
+    int *elist = (int *) NULL, *elen = (int *) NULL;
+    int *thematching = (int *) NULL, *thedual = (int *) NULL;
+    int *thebasis = (int *) NULL;
+    CCdatagroup dat, *mydat = (CCdatagroup *) NULL;
+    int rval = 0;
+
+    seed = (int) CCutil_real_zeit ();
+    if (parseargs (ac, av))
+        return 0;
+    CCutil_sprand (seed);
+
+    if (edgefilename == (char *) NULL && datfilename == (char *) NULL &&
+                                         nnodes_want == 0) {
+        usage (av[0]);
+        return 0;
+    }
+    ncount = nnodes_want;
+
+    szeit = CCutil_zeit ();
+    if (tsplib_in && datfilename != (char *) NULL) {
+        if (CCutil_gettsplib (datfilename, &ncount, &dat)) {
+            fprintf (stderr, "could not read the TSPLIB file\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        norm = dat.norm;
+        mydat = &dat;
+    } else if (edgefilename == (char *) NULL || datfilename != (char *) NULL) {
+        if (CCutil_getdata (datfilename, binary_in, norm, &ncount, &dat)) {
+            fprintf (stderr, "Could not create data set\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        mydat = &dat;
+    } else {
+        mydat = (CCdatagroup *) NULL;
+    }
+
+    if (mydat) {
+        if (CCutil_init_dat_edgelen (&dat)) {
+            fprintf (stderr, "CCutil_init_dat_edgelen failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (getgraph (edgefilename, &dat, &ncount, &ecount, &elist, &elen)) {
+        fprintf (stderr, "getgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+    printf ("Initial edgeset: %d edges (%d nodes)\n", ecount, ncount);
+    printf ("Time to generate graph: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    if (dumpmatch) {
+        thematching = CC_SAFE_MALLOC((6 * ncount) + 1, int);
+        if (!thematching)
+            goto CLEANUP;
+    }
+    if (dumpdual) {
+        thedual = CC_SAFE_MALLOC(ncount, int);
+        if (!thedual)
+            goto CLEANUP;
+    }
+    if (dumpbasis) {
+        thebasis = CC_SAFE_MALLOC(2 * ncount, int);
+        if (!thebasis)
+            goto CLEANUP;
+    }
+
+
+    szeit = CCutil_zeit ();
+    if (CCfmatch_fractional_2match (ncount, ecount, elist, elen, mydat,
+          &v, thematching, thedual, thebasis, wantbasic)) {
+        fprintf (stderr, "Fractional matching routine failed\n");
+        printf ("Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+        goto CLEANUP;
+    }
+
+    printf ("Total Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    printf ("Final matching weight: %.1f\n", v);
+    fflush (stdout);
+
+    if (dumpmatch)
+        dump_match (thematching);
+    if (dumpdual)
+        dump_dual (thedual, ncount);
+    if (dumpbasis)
+        dump_basis (thebasis, ncount);
+
+
+CLEANUP:
+
+    CC_IFFREE (thematching, int);
+    CC_IFFREE (thedual, int);
+    CC_IFFREE (thebasis, int);
+    CC_IFFREE (elist, int);
+    CC_IFFREE (elen, int);
+
+    if (mydat != (CCdatagroup *) NULL) {
+        CCutil_freedatagroup (ncount, mydat);
+    }
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: CCutil_bigchunk_free_world failed\n");
+        return 1;
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "BbD:e:k:mn:q:s:Txyz0123456789")) != EOF)
+        switch (c) {
+        case 'B':
+            wantbasic = 1;
+            break;
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'D':
+            edgegenfname = CCutil_bix_optarg;
+            break;
+        case 'e':
+            edgefilename = CCutil_bix_optarg;
+            break;
+        case 'k':
+            nnodes_want = atoi (CCutil_bix_optarg);
+            break;
+        case 'm':
+            usenn2match = 1;
+             break;
+        case 'n':
+            datfilename = CCutil_bix_optarg;
+            break;
+        case 'q':
+            quadtry = atoi (CCutil_bix_optarg);
+            break;
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 'T':
+            tsplib_in = 1;
+            break;
+        case 'x':
+            dumpmatch = 1;
+            break;
+        case 'y':
+            dumpdual = 1;
+            break;
+        case 'z':
+            dumpbasis = 1;
+            wantbasic = 1;
+            break;
+        case '0':
+            norm = CC_MAXNORM;
+            break;
+        case '1':
+            norm = CC_EUCLIDEAN_CEIL;
+            break;
+        case '2':
+            norm = CC_EUCLIDEAN;
+            break;
+        case '3':
+            norm = CC_EUCLIDEAN_3D;
+            break;
+        case '4':
+            norm = CC_IBM;
+            break;
+        case '5':
+            norm = CC_ATT;
+            break;
+        case '6':
+            norm = CC_GEOGRAPHIC;
+            break;
+        case '7':
+            norm = CC_MATRIXNORM;
+            break;
+        case '8':
+            norm = CC_DSJRANDNORM;
+            break;
+        case '9':
+            norm = CC_CRYSTAL;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+        default:
+            usage (av[0]);
+            return 1;
+        }
+    if (CCutil_bix_optind != ac) {
+        usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "Usage: %s [-see below-]\n", f);
+    fprintf (stderr, "   -B    find basic optimal solution\n");
+    fprintf (stderr, "   -b    datfile in integer binary format\n");
+    fprintf (stderr, "   -D f  edgegen file for initial edge set\n");
+    fprintf (stderr, "   -e f  edge file - initial edge set\n");
+    fprintf (stderr, "   -k #  number of nodes for random problem\n");
+    fprintf (stderr, "   -m    NN 2-matching as initial edge set\n");
+    fprintf (stderr, "   -n f  dat file - for fmatch on complete graph\n");
+    fprintf (stderr, "   -q #  quad-nearest # as initial edge set (default 2)\n");
+    fprintf (stderr, "   -s #  random seed\n");
+    fprintf (stderr, "   -T    the dat file is a TSPLIB file\n");
+    fprintf (stderr, "   -x    dump matching to match.out\n");
+    fprintf (stderr, "   -y    dump dual solution to dual.out\n");
+    fprintf (stderr, "   -z    dump basic edges to basis.out\n");
+    fprintf (stderr, "   -0    price out using MAX norm\n");
+    fprintf (stderr, "   -1    price out using JOHNSON norm\n");
+    fprintf (stderr, "   -2    price out using EUCLIDEAN norm (default)\n");
+    fprintf (stderr, "   -3    price out using Rounded Euclidean 3D norm\n");
+    fprintf (stderr, "   -(4 5 6 7 8 9) IBM ATT GEO MATRIX DSJRAND CRYSTAL norm\n");
+}
+
+#define QUAD_TRY 2
+
+#ifdef CC_PROTOTYPE_ANSI
+static int getgraph (char *edgefile, CCdatagroup *dat, int *ncount, int *ecount,
+                     int **elist, int **elen)
+#else
+static int getgraph (edgefile, dat, ncount, ecount, elist, elen)
+char *edgefile;
+CCdatagroup *dat;
+int *ncount, *ecount, **elist, **elen;
+#endif
+{
+    FILE *in;
+    int i, k;
+
+
+    *elist = (int *) NULL;
+    *elen = (int *) NULL;
+
+    if (edgefile != (char *) NULL) {
+        if ((in = fopen (edgefile, "r")) == (FILE *) NULL) {
+            perror (edgefile);
+            fprintf (stderr, "Unable to open %s for input\n", edgefile);
+            return 1;
+        }
+
+        k = CCutil_readint (in);
+        if (*ncount != 0 && k != *ncount) {
+            fprintf (stderr, "Edge file does not match dat file\n");
+            fclose (in);
+            return 1;
+        }
+        *ncount = k;
+        *ecount = CCutil_readint (in);
+
+        *elist = CC_SAFE_MALLOC(2 * (*ecount), int);
+        if (!(*elist)) {
+            fclose (in);
+            return 1;
+        }
+        *elen = CC_SAFE_MALLOC(*ecount, int);
+        if (!(*elen)) {
+            fclose (in);
+            CC_FREE (*elist, int);
+            return 1;
+        }
+
+        for (i = 0, k = 0; i < *ecount; i++) {
+            (*elist)[k++] = CCutil_readint (in);
+            (*elist)[k++] = CCutil_readint (in);
+            (*elen)[i] = CCutil_readint (in);
+        }
+        fclose (in);
+    } else if (edgegenfname) {
+        CCedgegengroup plan;
+        if (CCedgegen_read (edgegenfname, &plan)) {
+            fprintf (stderr, "CCedgegen_read failed\n");
+            return 1;
+        }
+        if (CCedgegen_edges (&plan, *ncount, dat, (double *) NULL, ecount,
+                             elist)) {
+            fprintf (stderr, "CCedgegen_edges failed\n");
+            return 1;
+        }
+        *elen = CC_SAFE_MALLOC(*ecount, int);
+        if (!(*elen)) {
+            CC_FREE (*elist, int);
+            return 1;
+        }
+        for (i = 0; i < *ecount; i++) {
+            (*elen)[i] = CCutil_dat_edgelen ((*elist)[2*i], (*elist)[(2*i) + 1], dat);
+        }
+    } else {
+        if (usenn2match) {
+            double val;
+            *ecount = *ncount;
+            *elist = CC_SAFE_MALLOC(2 * (*ecount), int);
+            if (!(*elist))
+                return 1;
+            if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+                printf ("Using nearest neighbor 2-matching graph\n");
+                fflush (stdout);
+                if (CCkdtree_nearest_neighbor_2match ((CCkdtree *) NULL,
+                        *ncount, CCutil_lprand () % (*ncount), dat,
+                        *elist, &val)) {
+                    fprintf (stderr, "nearest 2-matching code failed\n");
+                    CC_FREE (*elist, int);
+                    return 1;
+                }
+            } else {
+                int *cyc = (int *) NULL;
+                printf ("Not setup for nearest 2-match with x or junk norms\n");
+                printf ("Using nearest neighbour tour graph\n");
+                fflush (stdout);
+                cyc = CC_SAFE_MALLOC (*ncount, int);
+                if (!cyc) {
+                    CC_FREE (*elist, int);
+                    return 1;
+                }
+                if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+                    if (CCedgegen_x_nearest_neighbor_tour (*ncount,
+                            CCutil_lprand () % (*ncount), dat, cyc, &val)) {
+                        CC_FREE (*elist, int);
+                        CC_FREE (cyc, int);
+                        return 1;
+                    }
+                } else {
+                    if (CCedgegen_junk_nearest_neighbor_tour (*ncount,
+                            CCutil_lprand () % (*ncount), dat, cyc, &val)) {
+                        CC_FREE (*elist, int);
+                        CC_FREE (cyc, int);
+                        return 1;
+                    }
+                }
+                for (i = 0; i < *ncount - 1; i++) {
+                    (*elist)[2 * i] = cyc[i];
+                    (*elist)[(2 * i) + 1] = cyc[i + 1];
+                }
+                (*elist)[2 * i] = cyc[i];
+                (*elist)[(2 * i) + 1] = cyc[0];
+                CC_FREE (cyc, int);
+            }
+        } else {
+            if ((dat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+                printf ("Using quadrant nearest %d graph\n", quadtry);
+                fflush (stdout);
+                if (CCkdtree_quadrant_k_nearest ((CCkdtree *) NULL, *ncount,
+                       quadtry, dat, (double *) NULL, 1, ecount, elist)) {
+                    fprintf (stderr, "CCkdtree-quad nearest code failed\n");
+                    CC_FREE (*elist, int);
+                    return 1;
+                }
+            } else if ((dat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+                printf ("Using quadrant nearest %d graph\n", quadtry);
+                fflush (stdout);
+                if (CCedgegen_x_quadrant_k_nearest (*ncount, quadtry, dat,
+                       (double *) NULL, 1, ecount, elist)) {
+                    fprintf (stderr, "CCedgegen_x-quad nearest code failed\n");
+                    CC_FREE (*elist, int);
+                    return 1;
+                }
+            } else {
+                printf ("No junk quad nearest, using %d nearest graph\n",
+                         4 * quadtry);
+                fflush (stdout);
+                if (CCedgegen_junk_k_nearest (*ncount, 4 * quadtry, dat,
+                       (double *) NULL, 1, ecount, elist)) {
+                    fprintf (stderr, "CCedgegen_junk-nearest code failed\n");
+                    CC_FREE (*elist, int);
+                    return 1;
+                }
+            }
+        }
+
+        *elen = CC_SAFE_MALLOC(*ecount, int);
+        if (!(*elen)) {
+            CC_FREE (*elist, int);
+            return 1;
+        }
+        for (i = 0; i < *ecount; i++) {
+            (*elen)[i] = CCutil_dat_edgelen ((*elist)[2*i], (*elist)[(2*i) + 1], dat);
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_match (int *thematching)
+#else
+static void dump_match (thematching)
+int *thematching;
+#endif
+{
+    FILE *out = fopen ("match.out", "w");
+    int k;
+
+    if (out == (FILE *) NULL) {
+        perror ("match.out");
+        fprintf (stderr, "Unable to open match.out for output\n");
+        return;
+    }
+
+    k = 0;
+    while (thematching[k] != -1) {
+        fprintf (out, "%d %d %d\n", thematching[k], thematching[k + 1],
+                       thematching[k + 2]);
+        k += 3;
+    }
+}
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_dual (int *thedual, int ncount)
+#else
+static void dump_dual (thedual, ncount)
+int *thedual;
+int ncount;
+#endif
+{
+    FILE *out = fopen ("dual.out", "w");
+    int k;
+
+    if (out == (FILE *) NULL) {
+        perror ("dual.out");
+        fprintf (stderr, "Unable to open dual.out for output\n");
+        return;
+    }
+
+    for (k = 0; k < ncount; k++)
+        fprintf (out, "%d\n", thedual[k]);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_basis (int *thebasis, int ncount)
+#else
+static void dump_basis (thebasis, ncount)
+int *thebasis;
+int ncount;
+#endif
+{
+    FILE *out = fopen ("basis.out", "w");
+    int k;
+
+    if (out == (FILE *) NULL) {
+        perror ("basis.out");
+        fprintf (stderr, "Unable to open basis.out for output\n");
+        return;
+    }
+
+    for (k = 0; k < ncount; k++)
+        fprintf (out, "%d %d\n", thebasis[2 * k], thebasis[(2 * k) + 1]);
+}
diff --git a/contrib/blossom/concorde97/FMATCH/fmatch.c b/contrib/blossom/concorde97/FMATCH/fmatch.c
new file mode 100644
index 0000000000000000000000000000000000000000..dec846c5d8966dfef8a0065472f3781eb779907f
--- /dev/null
+++ b/contrib/blossom/concorde97/FMATCH/fmatch.c
@@ -0,0 +1,2324 @@
+/***************************************************************************/
+/*                                                                         */
+/*                 MIN WEIGHT FRACTIONAL 2-MATCHINGS                       */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 24, 1995 - Modified 10/4/95 (Bico)                      */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCfmatch_fractional_2match (int ncount, int ecount, int *elist,  */
+/*           int *elen, CCdatagroup *dat, double *val, int *thematching,   */
+/*           int *thedual, int *thebasis, int wantbasic)                   */
+/*       int ncount (the number of nodes in the graph)                     */
+/*       int ecount (the number of edges)                                  */
+/*       int *elist (the edgelist in end1 end2 format)                     */
+/*       int *elen (the weights on the edges)                              */
+/*       CCdatagroup *dat (the info to price edges - NULL if no pricing)   */
+/*       double *xcoord (the x-coordinates for geometric problems - this   */
+/*                       field can be NULL)                                */
+/*       double *ycoord (the y-coordinates)                                */
+/*       int innorm (the NORM for pricing the complete edgeset)            */
+/*       double *val (returns the optimal weight)                          */
+/*       int *thematching (if non-NULL, then returns the optimal matching  */
+/*                         in end1 end2 value format, where value is 1 if  */
+/*                         edge gets assigned 0.5 and value is 2 if edge   */
+/*                         gets 1.0 - note that the array should be        */
+/*                         allocated by the calling routine, and should    */
+/*                         be 6 * nnodes + 1 long - it is terminated by a  */
+/*                         -1)                                             */
+/*       int *thedual (if non-NULL, then returns the optimal dual solution */
+/*                     with values twice their actual value (so they will  */
+/*                     be integers - the array should be alloced by the    */
+/*                     calling routine, and should be nnodes long)         */
+/*       int *thebasis (if non-NULL, then returns the edges in the optimal */
+/*                      basis in end1 end2 format)                         */
+/*       int wantbasis (if nonzero, then the optimal basic solution will   */
+/*                      be found)                                          */
+/*                                                                         */
+/*                                                                         */
+/*    NOTES:                                                               */
+/*       Use to find an optimal basis for the initial tsp LP. By changing  */
+/*    MATCHDEGREE to 1, it should find min-wieght fractional matchings.    */
+/*       The nodes should be numbered from 0 up to ncount - 1. If dat      */
+/*    is specified, then the code will use a price-repair loop to solve    */
+/*    the problem over the complete graph.                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "fmatch.h"
+#include "kdtree.h"
+
+#define MATCHDEGREE 2    /* Only set up for 1 or 2? */
+#define MAXWEIGHT 1000000000
+
+#define ZERO ((unsigned char) 0)
+#define ONE ((unsigned char) 1)
+#define TWO ((unsigned char) 2)
+#ifdef FALSE
+#undef FALSE
+#endif
+#define FALSE ((unsigned char) 0)
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE ((unsigned char) 1)
+
+#define OTHEREND(e,n) (e->ends[0] == n ? e->ends[1] : e->ends[0])
+
+typedef struct edgeptr {
+    struct edge *this;
+    struct node *other;
+    struct edgeptr *next;
+} edgeptr;
+
+typedef struct edge {
+    struct edge *next;
+    struct edge *pnext;
+    struct node *ends[2];
+    int weight;
+    int z;
+    unsigned char x;
+    unsigned char basic;
+} edge;
+
+typedef struct shortedge {
+    struct node *ends[2];
+    struct shortedge *next;
+} shortedge;
+
+typedef struct node {
+    struct node *next;
+    struct node *pnext;
+    edgeptr *adj;
+    edge *parentedge;
+    int name;
+    int y;
+    int label;
+    struct {
+        int order;
+        struct node *next;
+        struct node **prev;
+    } sort;
+    unsigned char flag;
+    unsigned char matchcnt;
+} node;
+
+static int norm = CC_EUCLIDEAN;
+
+static node *nodellist = (node *) NULL;
+static node **nodenames = (node **) NULL;
+static edge *edgellist = (edge *) NULL;
+static int nnodes;
+static int nedges;
+static int PLUS = 1, MINUS = 2;
+
+static CCdatagroup *gdat = (CCdatagroup *) NULL;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    free_graph (void),
+    basic_grab_basic (node *n, int parity),
+    basic_mark_component_as_done (node *n),
+    basic_expand (node *n, int *hit_odd_circuit),
+    basic_minalpha (node *n, node **new, int *alpha, int flip_plus_and_minus),
+    basic_subalpha (node *n, int alpha, int flip_plus_and_minus),
+    initmat (void),
+    initlist (node *head, node *tail, node *head2, node *tail2),
+    expand (node *n, int *found_one),
+    minalpha (node *n, node **new, int *alpha),
+    subalpha (node *n, int alpha),
+    augmentpath (node *n),
+    augmentpath1 (node *n),
+    augmentplushalf (node *n, edge *e),
+    augmentminushalf (node *n, edge *e),
+    flipcycle (node *n, edge *e, unsigned char v),
+    augmentpair (node *n, node *n1, edge *e),
+    setflag (node *n, unsigned char v),
+    flipseg (node *n, node *n2),
+    stringup (node *n, node *n1, node *n2, edge *e),
+    y_quicksort (node **list, int *y, int l, int u),
+    free_linked_world (void);
+
+static int
+    buildgraph (int ncount, int ecount, int *elist, int *elen),
+    basicrun (void),
+    basicscan (node *n),
+    basic_check_scan (node *n),
+    basicgrow (node *n),
+    basic_grab_ones (node *n, int parity, edge **odd_circuit),
+    basic_checkout_basic (node *n, int parity, edge **odd_circuit),
+    twomatch (void),
+    chkmat (double *val),
+    fixmatch (int *radded),
+    kd_fixmatch (int *radded),
+    x_fixmatch (int *radded),
+    junk_fixmatch (int *radded),
+    checkoutedge (node *n1, node *n2, int *hit),
+    precheckoutedge (node *n1, node *n2, shortedge **list),
+    addbadedge (node *n1, node *n2, int w),
+    augment (node *n);
+
+static node
+    *basic_dualchange (node *n),
+    *dualchange (node *n),
+    *findflag (node *n),
+    *findhole (node *n, node *n2);
+
+static edge
+    *newedge (node *n1, node *n2),
+    *findedge (node *n1, node *n2);
+
+
+#else  /* CC_PROTOTYPE_ANSI */
+
+static void
+    free_graph (),
+    basic_grab_basic (),
+    basic_mark_component_as_done (),
+    basic_expand (),
+    basic_minalpha (),
+    basic_subalpha (),
+    initmat (),
+    initlist (),
+    expand (),
+    minalpha (),
+    subalpha (),
+    augmentpath (),
+    augmentpath1 (),
+    augmentplushalf (),
+    augmentminushalf (),
+    flipcycle (),
+    augmentpair (),
+    setflag (),
+    flipseg (),
+    stringup (),
+    y_quicksort (),
+    free_linked_world ();
+
+static int
+    buildgraph (),
+    basicrun (),
+    basicscan (),
+    basic_check_scan (),
+    basicgrow (),
+    basic_grab_ones (),
+    basic_checkout_basic (),
+    twomatch (),
+    chkmat (),
+    fixmatch (),
+    kd_fixmatch (),
+    x_fixmatch (),
+    junk_fixmatch (),
+    checkoutedge (),
+    precheckoutedge (),
+    addbadedge (),
+    augment ();
+
+static node
+    *basic_dualchange (),
+    *dualchange (),
+    *findflag (),
+    *findhole ();
+
+static edge
+    *newedge (),
+    *findedge ();
+
+
+#endif /* CC_PROTOTYPE_ANSI */
+
+
+/********** Allocation routines **********/
+
+
+CC_PTR_ALLOC_ROUTINE (node, nodealloc, node_bigchunklist, node_freelist)
+CC_PTR_FREE_ROUTINE (node, nodefree, node_freelist)
+CC_PTR_FREE_WORLD_ROUTINE (node, nodefree_world, node_bigchunklist,
+        node_freelist)
+CC_PTR_LEAKS_ROUTINE (node, node_check_leaks, node_bigchunklist, node_freelist,
+        flag, unsigned char)
+
+CC_PTR_ALLOC_ROUTINE (edge, edgealloc, edge_bigchunklist, edge_freelist)
+CC_PTR_FREE_ROUTINE (edge, edgefree, edge_freelist)
+CC_PTR_FREE_WORLD_ROUTINE (edge, edgefree_world, edge_bigchunklist,
+        edge_freelist)
+CC_PTR_LEAKS_ROUTINE (edge, edge_check_leaks, edge_bigchunklist, edge_freelist,
+        basic, unsigned char)
+
+CC_PTR_ALLOC_ROUTINE (edgeptr, edgeptralloc, edgeptr_bigchunklist,
+        edgeptr_freelist)
+CC_PTR_FREE_ROUTINE (edgeptr, edgeptrfree, edgeptr_freelist)
+CC_PTR_FREE_LIST_ROUTINE (edgeptr, edgeptrfree_list, edgeptrfree)
+CC_PTR_FREE_WORLD_ROUTINE (edgeptr, edgeptrfree_world, edgeptr_bigchunklist,
+        edgeptr_freelist)
+CC_PTR_LEAKS_ROUTINE (edgeptr, edgeptr_check_leaks, edgeptr_bigchunklist,
+        edgeptr_freelist, this, edge *)
+
+CC_PTR_ALLOC_ROUTINE (shortedge, shortedgealloc, shortedge_bigchunklist,
+        shortedge_freelist)
+CC_PTR_FREE_ROUTINE (shortedge, shortedgefree, shortedge_freelist)
+CC_PTR_FREE_WORLD_ROUTINE (shortedge, shortedgefree_world,
+        shortedge_bigchunklist, shortedge_freelist)
+CC_PTR_LEAKS_ROUTINE (shortedge, shortedge_check_leaks, shortedge_bigchunklist,
+        shortedge_freelist, ends[0], node *)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_linked_world (void)
+#else
+static void free_linked_world ()
+#endif
+{
+    nodefree_world ();
+    edgefree_world ();
+    edgeptrfree_world ();
+    shortedgefree_world ();
+}
+
+
+/********** main routines **********/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int buildgraph (int ncount, int ecount, int *elist, int *elen)
+#else
+static int buildgraph (ncount, ecount, elist, elen)
+int ncount, ecount, *elist, *elen;
+#endif
+{
+    int i;
+    node *n;
+    edge *e;
+
+    nnodes = ncount;
+    nedges = 0;
+
+    nodenames = CC_SAFE_MALLOC(nnodes, node *);
+    if (!nodenames)
+        return 1;
+
+    for (i = 0; i < nnodes; i++) {
+        n = nodealloc ();
+        if (!n)
+            return 1;
+        n->name = i;
+        n->adj = (edgeptr *) NULL;
+        n->next = nodellist;
+        nodellist = n;
+        nodenames[i] = n;
+    }
+    for (i = 0; i < ecount; i++) {
+        e = newedge (nodenames[elist[2 * i]], nodenames[elist[(2 * i) + 1]]);
+        if (!e)
+            return 1;
+        e->weight = elen[i] + elen[i];
+    }
+
+    if (nedges != ecount) {
+        fprintf (stderr, "Should have %d edges, not %d\n", ecount, nedges);
+        free_graph ();
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_graph (void)
+#else
+static void free_graph ()
+#endif
+{
+    node *n, *nnext;
+    edge *e, *enext;
+
+    for (n = nodellist; n; n = nnext) {
+        nnext = n->next;
+        edgeptrfree_list (n->adj);
+        nodefree (n);
+    }
+    nodellist = (node *) NULL;
+    for (e = edgellist; e; e = enext) {
+        enext = e->next;
+        edgefree (e);
+    }
+    edgellist = (edge *) NULL;
+    CC_IFFREE (nodenames, node *);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static edge *newedge (node *n1, node *n2)
+#else
+static edge *newedge (n1, n2)
+node *n1, *n2;
+#endif
+{
+    edge *e;
+    edgeptr *ep;
+
+    e = edgealloc ();
+    if (!e)
+        return (edge *) NULL;
+    e->ends[0] = n1;
+    e->ends[1] = n2;
+    e->next = edgellist;
+    edgellist = e;
+    nedges++;
+
+    ep = edgeptralloc ();
+    if (!ep) {
+        edgefree (e);
+        return (edge *) NULL;
+    }
+    ep->this = e;
+    ep->other = n2;
+    ep->next = n1->adj;
+    n1->adj = ep;
+
+    ep = edgeptralloc ();
+    if (!ep) {
+        edgefree (e);
+        return (edge *) NULL;
+    }
+    ep->this = e;
+    ep->other = n1;
+    ep->next = n2->adj;
+    n2->adj = ep;
+
+    return e;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCfmatch_fractional_2match (int ncount, int ecount, int *elist, int *elen,
+        CCdatagroup *dat, double *val, int *thematching, int *thedual,
+        int *thebasis, int wantbasic)
+#else
+int CCfmatch_fractional_2match (ncount, ecount, elist, elen, dat, val,
+        thematching, thedual, thebasis, wantbasic)
+int ncount, ecount;
+int *elist, *elen;
+CCdatagroup *dat;
+double *val;
+int *thematching, *thedual, *thebasis;
+int wantbasic;
+#endif
+{
+    int ntotal, nreserve;
+    double v, vbasic, szeit, tzeit;
+    int added;
+    int rval = 0;
+
+    tzeit = CCutil_zeit ();
+
+    if (dat)
+        norm = dat->norm;
+    else
+        norm = 2;
+    gdat = dat;
+    if (buildgraph (ncount, ecount, elist, elen)) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    initmat ();
+    if (twomatch ()) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    if (chkmat (&v)) {
+        fprintf (stderr, "Chkmat found error in matching\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+    printf ("Fractional Matching: %.1f\n", v);
+    printf ("Initial Running Time: %.2f (seconds)\n", CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    if (wantbasic) {
+        szeit = CCutil_zeit ();
+        if (basicrun ()) {
+            fprintf (stderr, "Did not find a basic optimal solution\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (chkmat (&vbasic)) {
+            fprintf (stderr, "Chkmat found error in matching\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (vbasic != v) {
+            fprintf (stderr, "ERROR: Basis routine altered objective\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Basis Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+        fflush (stdout);
+    }
+
+    if (dat != (CCdatagroup *) NULL) {
+        printf ("Price-Repair ...\n");
+        fflush (stdout);
+        szeit = CCutil_zeit ();
+        if (fixmatch(&added)) {
+            fprintf (stderr, "fixmatch failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (chkmat (&v)) {
+            fprintf (stderr, "Chkmat found error in matching\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (wantbasic) {
+            do  {
+                printf ("Find basis ...\n");
+                fflush (stdout);
+                if (basicrun ()) {
+                    fprintf (stderr, "Did not find a basic solution\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                if (chkmat (&vbasic)) {
+                    fprintf (stderr, "Chkmat found error in matching\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                if (vbasic != v) {
+                    fprintf (stderr, "ERROR: Basis routine altered obj\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+
+                printf ("Price-repair basic solution ...\n");
+                fflush (stdout);
+                if (fixmatch(&added)) {
+                    fprintf (stderr, "fixmatch failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                if (chkmat (&v)) {
+                    fprintf (stderr, "Chkmat found error in matching\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+            } while (added);
+        }
+        printf ("Running Time for Price-Repair: %.2f\n",
+                                         CCutil_zeit () - szeit);
+        printf ("Fractional Matching on Complete Graph: %.1f\n",v);
+        fflush (stdout);
+    }
+
+    *val = v;
+
+    if (thematching != (int *) NULL) {
+        int k = 0;
+        edge *e;
+        for (e = edgellist; e; e = e->next) {
+            if (e->x != ZERO) {
+                thematching[k++] = e->ends[0]->name;
+                thematching[k++] = e->ends[1]->name;
+                thematching[k++] = (e->x == ONE ? 1 : 2);
+            }
+        }
+        thematching[k] = -1;
+    }
+    if (thedual != (int *) NULL) {
+        int i;
+        for (i = 0; i < nnodes; i++)
+            thedual[i] = nodenames[i]->y;
+    }
+    if (wantbasic && thebasis != (int *) NULL) {
+        int k = 0;
+        edge *e;
+        for (e = edgellist; e; e = e->next) {
+            if (e->basic) {
+                thebasis[k++] = e->ends[0]->name;
+                thebasis[k++] = e->ends[1]->name;
+            }
+        }
+    }
+
+CLEANUP:
+
+    free_graph ();
+    if (node_check_leaks (&ntotal, &nreserve)) {
+        printf ("Outstanding nodes %d (total %d)\n",
+                 ntotal - nreserve, ntotal);
+    }
+    if (edge_check_leaks (&ntotal, &nreserve)) {
+        printf ("Outstanding edges %d (total %d)\n",
+                 ntotal - nreserve, ntotal);
+    }
+    if (edgeptr_check_leaks (&ntotal, &nreserve)) {
+        printf ("Outstanding edgeptrs %d (total %d)\n",
+                 ntotal - nreserve, ntotal);
+    }
+    if (shortedge_check_leaks (&ntotal, &nreserve)) {
+        printf ("Outstanding shortedges %d (total %d)\n",
+                 ntotal - nreserve, ntotal);
+    }
+    free_linked_world ();
+
+    printf ("Total fractional matching time: %.2f (seconds)\n",
+             CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void initmat (void)
+#else
+static void initmat ()
+#endif
+{
+    node *n;
+    edge *e;
+
+    for (n = nodellist; n; n = n->next) {
+        n->y = 0;
+        n->matchcnt = 2 - MATCHDEGREE;
+        n->parentedge = (edge *) NULL;
+        n->label = 0;
+    }
+    for (e = edgellist; e; e = e->next) {
+        e->z = 0;
+        e->x = ZERO;
+        e->pnext = (edge *) NULL;
+    }
+    PLUS = 1;
+    MINUS = 2;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int chkmat (double *val)   /* val may be 1/2 integer and big */
+#else
+static int chkmat (val)
+double *val;
+#endif
+{
+    int k;
+    double v = 0.0, dualval = 0.0;
+    node *n;
+    edge *e;
+    edgeptr *ep;
+
+    for (n = nodellist; n; n = n->next) {
+        k = 0;
+        for (ep = n->adj; ep; ep = ep->next)
+            k += ep->this->x;
+        if (k != 2 * MATCHDEGREE) {
+            fprintf (stderr, "Not a matching, node %d has 2-degree %d\n",
+                                                               n->name, k);
+            return 1;
+        }
+        dualval += (double) n->y;
+    }
+    dualval *= (double) MATCHDEGREE;
+    for (e = edgellist; e; e = e->next) {
+        switch (e->x) {
+        case TWO:
+            if (e->z < 0 ||
+                    e->z != e->ends[0]->y + e->ends[1]->y - e->weight) {
+                fprintf (stderr, "Error in dual solution - 2\n");
+                return 1;
+            }
+            v += (double) e->weight;
+            v += (double) e->weight;
+            dualval -= (double) e->z;
+            break;
+        case ONE:
+            if (e->z != 0 ||
+                    e->ends[0]->y + e->ends[1]->y != e->weight) {
+                fprintf (stderr, "Error in dual solution - 1\n");
+                return 1;
+            }
+            v += (double) e->weight;
+            break;
+        case ZERO:
+            if (e->z != 0 || e->ends[0]->y + e->ends[1]->y > e->weight) {
+                fprintf (stderr, "Error in dual solution - 0\n");
+                return 1;
+            }
+            break;
+        default:
+            fprintf (stderr, "Error in matching values\n");
+            return 1;
+        }
+    }
+    v /= 4.0;
+    dualval /= 2.0;
+
+    if (v != dualval) {
+        fprintf (stderr, "The primal and dual objective values differ.\n");
+        return 1;
+    }
+    *val = v;
+    return 0;
+}
+
+
+/**********  Core fractional matching routines **********/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int twomatch (void)
+#else
+static int twomatch ()
+#endif
+{
+    node *n;
+
+    for (n = nodellist; n; n = n->next) {
+        while (n->matchcnt != TWO) {
+            if (augment (n)) {
+                fprintf (stderr, "augment failed - probably no fmatching\n");
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int augment (node *n)
+#else
+static int augment (n)
+node *n;
+#endif
+{
+    node *auglist;
+    int found_augmenting_path = 0;
+
+    PLUS += 2;
+    MINUS += 2;
+    n->label = PLUS;
+    n->parentedge = (edge *) NULL;
+    n->matchcnt++;
+    expand (n, &found_augmenting_path);
+    if (found_augmenting_path)
+        return 0;
+    while ((auglist = dualchange (n)) != (node *) NULL) {
+        while (auglist) {
+            expand (auglist, &found_augmenting_path);
+            if (found_augmenting_path)
+                return 0;
+            auglist = auglist->pnext;
+        }
+    }
+    fprintf (stderr, "Error - dual change did not create new edges\n");
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void expand (node *n, int *found_one)
+#else
+static void expand (n, found_one)
+node *n;
+int *found_one;
+#endif
+{
+    node *n1;
+    edgeptr *ep;
+    edge *e;
+
+    if (n->label == PLUS) {
+        for (ep = n->adj; ep; ep = ep->next) {
+            if (ep->this->x == ONE) {
+                augmentplushalf (n, ep->this);
+                *found_one = 1;
+                return;
+            }
+        }
+        for (ep = n->adj; ep; ep = ep->next) {
+            if (ep->this->x == ZERO &&
+                        ep->other->y + n->y == ep->this->weight) {
+                e = ep->this;
+                n1 = ep->other;
+                if (n1->label < PLUS) {         /* n1 has no label */
+                    n1->label = MINUS;
+                    n1->parentedge = e;
+                    if (n1->matchcnt != TWO) {
+                        augmentpath (n1);
+                        *found_one = 1;
+                        return;
+                    }
+                    expand (n1, found_one);
+                    if (*found_one)
+                        return;
+                } else if (n1->label == PLUS) {
+                    augmentpair (n, n1, e);
+                    *found_one = 1;
+                    return;
+                }
+            }
+        }
+    } else {                    /* MINUS */
+        for (ep = n->adj; ep; ep = ep->next) {
+            if (ep->this->x == ONE) {
+                augmentminushalf (n, ep->this);
+                *found_one = 1;
+                return;
+            }
+        }
+        for (ep = n->adj; ep; ep = ep->next) {
+            if (ep->this->x == TWO && ep->this->z == 0) {
+                e = ep->this;
+                n1 = ep->other;
+                if (n1->label < PLUS) {         /* n1 has no label */
+                    n1->label = PLUS;
+                    n1->parentedge = e;
+                    expand (n1, found_one);
+                    if (*found_one)
+                        return;
+                } else if (n1->label == MINUS) {
+                    augmentpair (n, n1, e);
+                    *found_one = 1;
+                    return;
+                }
+            }
+        }
+    }
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *dualchange (node *n)
+#else
+static node *dualchange (n)
+node *n;
+#endif
+{
+    node *new = (node *) NULL;
+    int alpha = MAXWEIGHT;
+
+    minalpha (n, &new, &alpha);
+    if (alpha == MAXWEIGHT) {
+        fprintf (stderr, "Dual change required, but no candidate edges\n");
+        return (node *) NULL;
+    }
+    if (alpha & 0x1) {
+        fprintf (stderr, "Whoops, 2 * alpha = %d, not even\n", alpha);
+        return (node *) NULL;
+    }
+    alpha /= 2;
+    subalpha (n, alpha);
+    return new;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void minalpha (node *n, node **new, int *alpha)
+#else
+static void minalpha (n, new, alpha)
+node *n;
+node **new;
+int *alpha;
+#endif
+{
+    int minv = MAXWEIGHT;
+    int thisv;
+    node *n1;
+    edgeptr *ep;
+    edge *e;
+
+    if (n->label == PLUS) {
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x == ZERO) {
+                n1 = ep->other;
+                if (n1->label < PLUS) {         /* n1 is unlabeled */
+                    thisv = e->weight - n->y - n1->y;
+                    thisv += thisv;
+                    if (thisv < minv)
+                        minv = thisv;
+                } else if (n1->label == PLUS) {
+                    thisv = e->weight - n->y - n1->y;
+                    if (thisv < minv)
+                        minv = thisv;
+                } else {        /* n1 has a minus label */
+                    if (n1->parentedge == e)
+                        minalpha (n1, new, alpha);
+                }
+            }
+        }
+    } else {                    /* MINUS case */
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x == TWO) {
+                n1 = ep->other;
+                if (n1->label < PLUS) {
+                    thisv = e->z + e->z;
+                    if (thisv < minv)
+                        minv = thisv;
+                } else if (n1->label == PLUS) {
+                    if (n1->parentedge == e)
+                        minalpha (n1, new, alpha);
+                } else {        /* n1 has a MINUS label */
+                    thisv = e->z;
+                    if (thisv < minv)
+                        minv = thisv;
+                }
+            }
+        }
+    }
+    if (minv < *alpha) {
+        *new = n;
+        n->pnext = (node *) NULL;
+        *alpha = minv;
+    } else if (minv == *alpha) {
+        n->pnext = *new;
+        *new = n;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void subalpha (node *n, int alpha)
+#else
+static void subalpha (n, alpha)
+node *n;
+int alpha;
+#endif
+{
+    edgeptr *ep;
+    edge *e;
+    node *n1;
+
+    if (n->label == PLUS) {
+        n->y += alpha;
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x == TWO)
+                e->z += alpha;
+            else if (e->x == ZERO) {
+                n1 = ep->other;
+                if (n1->parentedge == e && n1->label >= PLUS)
+                    subalpha (n1, alpha);
+            }
+        }
+    } else {                    /* MINUS */
+        n->y -= alpha;
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x == TWO) {
+                e->z -= alpha;
+                n1 = ep->other;
+                if (n1->parentedge == e && n1->label >= PLUS)
+                    subalpha (n1, alpha);
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void augmentpath (node *n)
+#else
+static void augmentpath (n)
+node *n;
+#endif
+{
+    n->matchcnt++;
+    augmentpath1 (n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void augmentpath1 (node *n)
+#else
+static void augmentpath1 (n)
+node *n;
+#endif
+{
+    while (n->parentedge != (edge *) NULL) {
+        n->parentedge->x = TWO - n->parentedge->x;
+        n = OTHEREND(n->parentedge, n);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void augmentplushalf (node *n, edge *e)
+#else
+static void augmentplushalf (n, e)
+node *n;
+edge *e;
+#endif
+{
+    flipcycle (n, e, TWO);
+    augmentpath1 (n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void augmentminushalf (node *n, edge *e)
+#else
+static void augmentminushalf (n, e)
+node *n;
+edge *e;
+#endif
+{
+    flipcycle (n, e, ZERO);
+    augmentpath1 (n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipcycle (node *n, edge *e, unsigned char v)
+#else
+static void flipcycle (n, e, v)
+node *n;
+edge *e;
+unsigned char v;
+#endif
+{
+    edge *e1;
+    edge *e2;
+
+    e1 = e->pnext;
+    if (e1->ends[0] == n || e1->ends[1] == n)
+        e = e1;
+    e1 = e;
+    do {
+        e1->x = v;
+        v = TWO - v;
+        e2 = e1->pnext;
+        e1->pnext = (edge *) NULL;
+        e1 = e2;
+    } while (e1 != e);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void augmentpair (node *n, node *n1, edge *e)
+#else
+static void augmentpair (n, n1, e)
+node *n;
+node *n1;
+edge *e;
+#endif
+{
+    node *n2, *n3;
+
+    setflag (n, FALSE);
+    setflag (n1, TRUE);
+    n2 = findflag (n);
+    if ((n3 = findhole (n, n2)) != (node *) NULL) {
+        n3->matchcnt++;
+        flipseg (n, n3);
+        e->x = TWO - e->x;
+        augmentpath1 (n1);
+        return;
+    }
+    if ((n3 = findhole (n1, n2)) != (node *) NULL) {
+        n3->matchcnt++;
+        flipseg (n1, n3);
+        e->x = TWO - e->x;
+        augmentpath1 (n);
+        return;
+    }
+    stringup (n, n1, n2, e);
+    augmentpath1 (n2);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void setflag (node *n, unsigned char v)
+#else
+static void setflag (n, v)
+node *n;
+unsigned char v;
+#endif
+{
+    n->flag = v;
+    while (n->parentedge != (edge *) NULL) {
+        n = OTHEREND(n->parentedge, n);
+        n->flag = v;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *findflag (node *n)
+#else
+static node *findflag (n)
+node *n;
+#endif
+{
+    while (!n->flag) {
+        n = OTHEREND(n->parentedge, n);
+    }
+    return n;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *findhole (node *n, node *n2)
+#else
+static node *findhole (n, n2)
+node *n;
+node *n2;
+#endif
+{
+    while (n != n2) {
+        if (n->matchcnt != TWO)
+            return n;
+        n = OTHEREND(n->parentedge, n);
+    }
+    return n2->matchcnt != TWO ? n2 : (node *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipseg (node *n, node *n2)
+#else
+static void flipseg (n, n2)
+node *n;
+node *n2;
+#endif
+{
+    while (n != n2) {
+        n->parentedge->x = TWO - n->parentedge->x;
+        n = OTHEREND(n->parentedge, n);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void stringup (node *n, node *n1, node *n2, edge *e)
+#else
+static void stringup (n, n1, n2, e)
+node *n;
+node *n1;
+node *n2;
+edge *e;
+#endif
+{
+    edge *preve, *savee;
+
+    preve = e;
+    while (n != n2) {
+        n->parentedge->x = ONE;
+        preve->pnext = n->parentedge;
+        preve = n->parentedge;
+        n = OTHEREND(n->parentedge, n);
+    }
+    savee = preve;
+    preve = e;
+    while (n1 != n2) {
+        n1->parentedge->x = ONE;
+        n1->parentedge->pnext = preve;
+        preve = n1->parentedge;
+        n1 = OTHEREND(n1->parentedge, n1);
+    }
+    savee->pnext = preve;
+    e->x = ONE;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static edge *findedge (node *n1, node *n2)
+#else
+static edge *findedge (n1, n2)
+node *n1;
+node *n2;
+#endif
+{
+    edgeptr *ep;
+
+    for (ep = n1->adj; ep; ep = ep->next) {
+        if (ep->other == n2)
+            return ep->this;
+    }
+    return  (edge *) NULL;
+}
+
+
+/********** Basis finding routines **********/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int basicrun (void)
+#else
+static int basicrun ()
+#endif
+{
+    node *n;
+    edge *e;
+
+    PLUS = 1;
+    MINUS = 2;
+
+    for (n = nodellist; n; n = n->next) {
+        n->label = 0;
+        n->flag = 0;
+    }
+    for (e = edgellist; e; e = e->next)
+        e->basic = 0;
+
+    for (n = nodellist; n; n = n->next) {
+        if (n->label == 0) {
+            if (basicscan (n))
+                return 1;
+        }
+    }
+    for (n = nodellist; n; n = n->next) {
+        if (n->flag == 0) {
+            if (basicgrow (n))
+                return 1;
+        }
+    }
+
+    for (n = nodellist; n; n = n->next)
+        n->label = 0;
+    for (n = nodellist; n; n = n->next) {
+        if (n->label == 0) {
+            if (basic_check_scan (n))
+                return 1;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int basicscan (node *n)
+#else
+static int basicscan (n)
+node *n;
+#endif
+{
+    edge *odd_circuit = (edge *) NULL;
+
+    PLUS += 2;
+    MINUS += 2;
+    n->parentedge = (edge *) NULL;
+    if (basic_grab_ones (n, 0, &odd_circuit))
+        return 1;
+    if (odd_circuit != (edge *) NULL) {
+        basic_mark_component_as_done (n);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int basic_check_scan (node *n)
+#else
+static int basic_check_scan (n)
+node *n;
+#endif
+{
+    edge *odd_circuit = (edge *) NULL;
+
+    PLUS += 2;
+    MINUS += 2;
+    n->parentedge = (edge *) NULL;
+    if (basic_checkout_basic (n, 0, &odd_circuit))
+        return 1;
+    if (odd_circuit == (edge *) NULL) {
+        printf ("No odd circuit\n");
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int basicgrow (node *n)
+#else
+static int basicgrow (n)
+node *n;
+#endif
+{
+    int hit_odd_circuit = 0;
+    node *expandlist;
+
+    PLUS += 2;
+    MINUS += 2;
+    basic_grab_basic (n, 0);
+
+    n->parentedge = (edge *) NULL;
+    basic_expand (n, &hit_odd_circuit);
+    if (hit_odd_circuit)
+        return 0;
+    else {
+        while ((expandlist = basic_dualchange (n)) != (node *) NULL) {
+            while (expandlist) {
+                basic_expand (expandlist, &hit_odd_circuit);
+                if (hit_odd_circuit)
+                    return 0;
+                expandlist = expandlist->pnext;
+            }
+        }
+        fprintf (stderr, "ERROR: No dual change in basis finding code\n");
+        return 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int basic_grab_ones (node *n, int parity, edge **odd_circuit)
+#else
+static int basic_grab_ones (n, parity, odd_circuit)
+node *n;
+int parity;
+edge **odd_circuit;
+#endif
+{
+    edge *e;
+    edgeptr *ep;
+    node *n1;
+
+    n->label = (parity == 0 ? PLUS : MINUS);
+    for (ep = n->adj; ep; ep = ep->next) {
+        e = ep->this;
+        if (e->x == ONE && e != n->parentedge) {
+            n1 = ep->other;
+            if (n1->label == 0) {
+                n1->parentedge = e;
+                e->basic = 1;
+                if (basic_grab_ones (n1, 1 - parity, odd_circuit))
+                    return 1;
+            } else if (n1->label == n->label) {
+                if (*odd_circuit == (edge *) NULL) {
+                    *odd_circuit = e;
+                    e->basic = 1;
+                } else if (*odd_circuit != e) {
+                    fprintf (stderr, "ERROR: Two odd circuits in 1-graph\n");
+                    printf ("Circuit forming edges: %d-%d  %d-%d\n",
+                         (*odd_circuit)->ends[0]->name,
+                         (*odd_circuit)->ends[1]->name,
+                         e->ends[0]->name,
+                         e->ends[1]->name);
+                    return 1;
+                }
+            } else {
+                fprintf (stderr, "ERROR: Even circuit in 1-graph\n");
+                printf ("Circuit forming edge: %d-%d\n",
+                              e->ends[0]->name,
+                              e->ends[1]->name);
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int basic_checkout_basic (node *n, int parity, edge **odd_circuit)
+#else
+static int basic_checkout_basic (n, parity, odd_circuit)
+node *n;
+int parity;
+edge **odd_circuit;
+#endif
+{
+    edge *e;
+    edgeptr *ep;
+    node *n1;
+
+    n->label = (parity == 0 ? PLUS : MINUS);
+    for (ep = n->adj; ep; ep = ep->next) {
+        e = ep->this;
+        if (e->basic && e != n->parentedge) {
+            n1 = ep->other;
+            if (n1->label == 0) {
+                n1->parentedge = e;
+                if (basic_checkout_basic (n1, 1 - parity, odd_circuit))
+                    return 1;
+            } else if (n1->label == n->label) {
+                if (*odd_circuit == (edge *) NULL) {
+                    *odd_circuit = e;
+                } else if (*odd_circuit != e) {
+                    fprintf (stderr, "ERROR: Two odd circuits in basish\n");
+                    printf ("Circuit forming edges: %d-%d  %d-%d\n",
+                         (*odd_circuit)->ends[0]->name,
+                         (*odd_circuit)->ends[1]->name,
+                         e->ends[0]->name,
+                         e->ends[1]->name);
+                    return 1;
+                }
+            } else {
+                fprintf (stderr, "ERROR: Even circuit in basis\n");
+                printf ("Circuit forming edge: %d-%d\n",
+                              e->ends[0]->name,
+                              e->ends[1]->name);
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void basic_grab_basic (node *n, int parity)
+#else
+static void basic_grab_basic (n, parity)
+node *n;
+int parity;
+#endif
+{
+    edgeptr *ep;
+
+    n->label = (parity == 0 ? PLUS : MINUS);
+    n->flag = 1;
+    for (ep = n->adj; ep; ep = ep->next) {
+        if (ep->this->basic) {
+            if (!ep->other->flag)
+                basic_grab_basic (ep->other, 1 - parity);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void basic_mark_component_as_done (node *n)
+#else
+static void basic_mark_component_as_done (n)
+node *n;
+#endif
+{
+    edgeptr *ep;
+
+    n->flag = 1;
+    for (ep = n->adj; ep; ep = ep->next) {
+        if (ep->this->basic) {
+            if (!ep->other->flag)
+                basic_mark_component_as_done (ep->other);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void basic_expand (node *n, int *hit_odd_circuit)
+#else
+static void basic_expand (n, hit_odd_circuit)
+node *n;
+int *hit_odd_circuit;
+#endif
+{
+    edge *e;
+    edgeptr *ep;
+    node *n1;
+
+    for (ep = n->adj; ep; ep = ep->next) {
+        e = ep->this;
+        if (e != n->parentedge) {
+            n1 = ep->other;
+            if (e->basic) {
+                n1->parentedge = e;
+                basic_expand (n1, hit_odd_circuit);
+                if (*hit_odd_circuit)
+                    return;
+            } else if (n->y + n1->y == e->weight) {
+                if (n1->label < PLUS) {
+                    e->basic = 1;
+                    if (n1->flag) {
+                        *hit_odd_circuit = 1;
+                        return;
+                    } else {
+                        n1->parentedge = e;
+                        if (n->label == PLUS)
+                            basic_grab_basic (n1, 1);
+                        else
+                            basic_grab_basic (n1, 0);
+                        basic_expand (n1, hit_odd_circuit);
+                        if (*hit_odd_circuit)
+                            return;
+                    }
+                } else if (n1->label == n->label) {
+                    e->basic = 1;
+                    *hit_odd_circuit = 1;
+                    return;
+                }
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static node *basic_dualchange (node *n)
+#else
+static node *basic_dualchange (n)
+node *n;
+#endif
+{
+    node *new = (node *) NULL;
+    int alpha = MAXWEIGHT;
+
+    basic_minalpha (n, &new, &alpha, 0);
+    if (alpha != MAXWEIGHT) {
+        alpha /= 2;
+        basic_subalpha (n, alpha, 0);
+    } else {
+        /* reverse sense of PLUS and MINUS */
+        basic_minalpha (n, &new, &alpha, 1);
+        if (alpha == MAXWEIGHT) {
+            printf ("Basic dual change required, but no candidate edges\n");
+            return (node *) NULL;
+        }
+        alpha /= 2;
+        basic_subalpha (n, alpha, 1);
+    }
+    return new;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void basic_minalpha (node *n, node **new, int *alpha,
+                           int flip_plus_and_minus)
+#else
+static void basic_minalpha (n, new, alpha, flip_plus_and_minus)
+node *n;
+node **new;
+int *alpha;
+int flip_plus_and_minus;
+#endif
+{
+    int minv = MAXWEIGHT;
+    int thisv;
+    node *n1;
+    edge *e;
+    edgeptr *ep;
+
+    if ((n->label == PLUS && !flip_plus_and_minus) ||
+        (n->label == MINUS && flip_plus_and_minus)) {
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            n1 = ep->other;
+            if (e->x != TWO) {
+                if (n1->label < PLUS) {         /* n1 is unlabeled */
+                    thisv = e->weight - n->y - n1->y;
+                    thisv += thisv;
+                    if (thisv < minv)
+                        minv = thisv;
+                } else if ((n1->label == PLUS && !flip_plus_and_minus) ||
+                           (n1->label == MINUS && flip_plus_and_minus)) {
+                    thisv = e->weight - n->y - n1->y;
+                    if (thisv < minv)
+                        minv = thisv;
+                } else {        /* n1 has a minus label */
+                    if (n1->parentedge == e)
+                        basic_minalpha (n1, new, alpha, flip_plus_and_minus);
+                }
+            } else if (e->basic && n1->parentedge == e) {
+                basic_minalpha (n1, new, alpha, flip_plus_and_minus);
+            }
+        }
+    } else {                    /* MINUS case */
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            n1 = ep->other;
+            if (e->x == TWO) {
+                if (n1->label < PLUS) {
+                    thisv = e->z + e->z;
+                    if (thisv < minv)
+                        minv = thisv;
+                } else if ((n1->label == PLUS && !flip_plus_and_minus) ||
+                           (n1->label == MINUS && flip_plus_and_minus)) {
+                    if (n1->parentedge == e)
+                        basic_minalpha (n1, new, alpha, flip_plus_and_minus);
+                } else {        /* n1 has a MINUS label */
+                    thisv = e->z;
+                    if (thisv < minv)
+                        minv = thisv;
+                }
+            } else if (e->basic && n1->parentedge == e) {
+                basic_minalpha (n1, new, alpha, flip_plus_and_minus);
+            }
+        }
+    }
+
+    if (minv < *alpha) {
+        *new = n;
+        n->pnext = (node *) NULL;
+        *alpha = minv;
+    } else if (minv == *alpha) {
+        n->pnext = *new;
+        *new = n;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void basic_subalpha (node *n, int alpha, int flip_plus_and_minus)
+#else
+static void basic_subalpha (n, alpha, flip_plus_and_minus)
+node *n;
+int alpha;
+int flip_plus_and_minus;
+#endif
+{
+    edge *e;
+    edgeptr *ep;
+
+    if ((n->label == PLUS && !flip_plus_and_minus) ||
+        (n->label == MINUS && flip_plus_and_minus)) {
+        n->y += alpha;
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x == TWO)
+                e->z += alpha;
+            if (e->basic) {
+                if (ep->other->parentedge == e)
+                    basic_subalpha (ep->other, alpha, flip_plus_and_minus);
+            }
+        }
+    } else {                    /* MINUS */
+        n->y -= alpha;
+        for (ep = n->adj; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x == TWO)
+                e->z -= alpha;
+            if (e->basic) {
+                if (ep->other->parentedge == e)
+                    basic_subalpha (ep->other, alpha, flip_plus_and_minus);
+            }
+        }
+    }
+}
+
+
+/********** Price - Repair routines **********/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkoutedge (node *n1, node *n2, int *hit)
+#else
+static int checkoutedge (n1, n2, hit)
+node *n1;
+node *n2;
+int *hit;
+#endif
+{
+    int w, wbar;
+    edge *e;
+
+    *hit = 0;
+    w = CCutil_dat_edgelen (n1->name, n2->name, gdat);
+    w += w;
+    wbar = w - n1->y - n2->y;
+    if (wbar < 0) {
+        if ((e = findedge (n1, n2)) != (edge *) NULL) {
+            if (e->z != -wbar) {
+                printf ("Hmmm.  edge (%d-%d) has z %d, wbar %d\n",
+                e->ends[0]->name, e->ends[1]->name, e->z, wbar);
+            }
+        } else {
+            if (addbadedge (n1, n2, w)) {
+                fprintf (stderr, "addbadedge failed\n");
+                return 1;
+            }
+            *hit = 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int precheckoutedge (node *n1, node *n2, shortedge **list)
+#else
+static int precheckoutedge (n1, n2, list)
+node *n1;
+node *n2;
+shortedge **list;
+#endif
+{
+    int w, wbar;
+    edge *e;
+    shortedge *s;
+
+    w = CCutil_dat_edgelen (n1->name, n2->name, gdat);
+    w += w;
+    wbar = w - n1->y - n2->y;
+    if (wbar < 0) {
+        if ((e = findedge (n1, n2)) != (edge *) NULL) {
+            if (e->z != -wbar) {
+                printf ("Hmmm.  edge (%d-%d) has z %d, wbar %d\n",
+                e->ends[0]->name, e->ends[1]->name, e->z, wbar);
+            }
+        } else {
+            s = shortedgealloc ();
+            s->ends[0] = n1;
+            s->ends[1] = n2;
+            s->next = *list;
+            *list = s;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int fixmatch (int *radded)
+#else
+static int fixmatch (radded)
+int *radded;
+#endif
+{
+    if ((gdat->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE)
+        return kd_fixmatch (radded);
+    else if ((gdat->norm & CC_NORM_BITS) == CC_X_NORM_TYPE)
+        return x_fixmatch (radded);
+    else
+        return junk_fixmatch (radded);
+}
+
+#define NEAR_TRY_NUM 1   /* The number of nearest (wbar) neighbors         */
+
+#define PULL_DIVISOR 100 /* Do not pull more than nnodes/PULL_DIVISOR.     */
+#define PULL_UNIT    100 /* Pull if PULL_UNIT nodes will cut the spread.   */
+#define PULL_CUT       2 /* A unit must cut at least spread/PULL_CUT.      */
+
+#ifdef CC_PROTOTYPE_ANSI
+static int kd_fixmatch (int *radded)
+#else
+static int kd_fixmatch (radded)
+int *radded;
+#endif
+{
+    int rval = 0;
+    int i, j, added, totaladded = 0;
+    int hit, passcount = 0;
+    int maxy = -MAXWEIGHT;
+    int miny =  MAXWEIGHT;
+    double *xcoord = (double *) NULL;
+    double *ycoord = (double *) NULL;
+    double *wcoord = (double *) NULL;
+    CCdatagroup ldat;
+    node *n;
+/*
+    NEEDED WHEN RADIX SORT IS WORKING
+    node *ysorted;
+*/
+    node **heavy, **light, **order = (node **) NULL;
+    int top, bottom, nlight, nheavy = 0;  /* nheavy should be set to 0 */
+    int *invnames = (int *) NULL;
+    double *lbnds = (double *) NULL, *gbnds = (double *) NULL;
+
+    *radded = 0;
+
+    ldat.x = (double *) NULL;
+    ldat.y = (double *) NULL;
+    ldat.z = (double *) NULL;
+    ldat.adj = (int **) NULL;
+    ldat.norm = gdat->norm;
+
+
+    for (n = nodellist; n; n = n->next) {
+        if (n->y < miny)
+            miny = n->y;
+        if (n->y > maxy)
+            maxy = n->y;
+    }
+    printf ("Node weight spread: (%d, %d)\n", miny, maxy);
+    fflush (stdout);
+
+/*
+    THIS CODE CANNOT BE USED UNDER OS2 WITH CURRENT RADIX
+    for (n = nodellist; n; n = n->next)
+        n->pnext = n->next;
+    ysorted = (node *) CCutil_linked_radixsort ((char *) nodellist,
+        (char *) &(nodellist->pnext),
+        (char *) &(nodellist->y), sizeof (int));
+
+    order = CC_SAFE_MALLOC (nnodes, node *);
+    if (!order) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    THIS IS THE CODE WHEN RADIXSORT WORKS WITH NEGATIVES
+    for (i = 0, n = ysorted; n; i++, n = n->pnext) {
+        order[i] = n;
+    }
+
+    INSTEAD, THIS CODE WORKS WITH CURRENT RADIX ON THE RS6000
+    for (n = ysorted; n; n = n->pnext)
+        if (n->y < 0)
+            break;
+    for (i = 0; n; n = n->pnext, i++)
+        order[i] = n;
+    for (n = ysorted; n && n->y >= 0; n = n->pnext, i++)
+        order[i] = n;
+*/
+
+    {
+        /* ONLY HERE UNTIL RADIX WORKS */
+        int *y;
+
+        order = CC_SAFE_MALLOC (nnodes, node *);
+        if (!order) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        y = CC_SAFE_MALLOC (nnodes, int);
+        if (!y) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        for (i = 0; i < nnodes; i++) {
+            order[i] = nodenames[i];
+            y[i] = nodenames[i]->y;
+        }
+        y_quicksort (order, y, 0, nnodes - 1);
+
+        CC_FREE (y, int);
+    }
+
+
+    {
+        int new, newspread, newtop, newbottom, spread;
+
+        newtop = top = -1;
+        newbottom = bottom = nnodes;
+        nheavy = 0;
+        spread = maxy - miny;
+
+        do {
+            new = 0;
+            while (new < PULL_UNIT && nheavy + new < nnodes/ PULL_DIVISOR) {
+                if (order[newbottom - 1]->y > -2 * order[newtop + 1]->y)
+                    newbottom--;
+                else
+                    newtop++;
+                new++;
+            }
+            newspread = order[newbottom - 1]->y - order[newtop + 1]->y;
+            if (spread - newspread > spread / PULL_CUT) {
+                spread = newspread;
+                bottom = newbottom;
+                top = newtop;
+                nheavy += new;
+            }
+        } while (spread == newspread && nheavy < nnodes / PULL_DIVISOR);
+    }
+
+
+    printf ("Truncated %d nodes to get spread: (%d, %d)\n",
+        nheavy, order[top + 1]->y, order[bottom - 1]->y);
+    fflush (stdout);
+
+
+    if (nheavy) {
+        heavy = order;
+        light = order + nheavy;
+        nlight = nnodes - nheavy;
+/*
+        THIS IS THE CODE WHEN RADIXSORT WORKS WITH NEGATIVES
+        for (i = 0, n = ysorted; i <= top; i++, n = n->pnext) {
+            heavy[i] = n;
+        }
+        for (i = 0; i < nlight; i++, n = n->pnext) {
+            light[i] = n;
+        }
+        for (i = top + 1; i < nheavy; i++, n = n->pnext) {
+            heavy[i] = n;
+        }
+*/
+        {
+            node **temporder = (node **) NULL;
+            int k;
+
+            temporder = CC_SAFE_MALLOC (nnodes, node *);
+            if (!temporder) {
+                rval = 1;
+                goto CLEANUP;
+            }
+            for (i = 0; i < nnodes; i++)
+                temporder[i] = order[i];
+
+            for (i = 0, k = 0; i <= top; i++)
+                heavy[i] = temporder[k++];
+            for (i = 0; i < nlight; i++)
+                light[i] = temporder[k++];
+            for (i = top + 1; i < nheavy; i++)
+                heavy[i] = temporder[k++];
+                CC_FREE (temporder, node *);
+        }
+
+        lbnds = CC_SAFE_MALLOC (nheavy, double);
+        if (!lbnds) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        gbnds = CC_SAFE_MALLOC (nheavy, double);
+        if (!gbnds) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        xcoord = CC_SAFE_MALLOC (nlight, double);
+        if (!xcoord) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        ldat.x = xcoord;
+        ycoord = CC_SAFE_MALLOC (nlight, double);
+        if (!ycoord) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        ldat.y = ycoord;
+        for (i = 0; i < nlight; i++) {
+            xcoord[i] = gdat->x[light[i]->name];
+            ycoord[i] = gdat->y[light[i]->name];
+        }
+    } else {
+        nlight = nnodes;
+        light = nodenames;
+        heavy = (node **) NULL;
+        xcoord = gdat->x;
+        ycoord = gdat->y;
+        ldat.x = xcoord;
+        ldat.y = ycoord;
+        CC_FREE (order, node *);
+    }
+
+    wcoord = CC_SAFE_MALLOC (nlight, double);
+    if (!wcoord) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    invnames = CC_SAFE_MALLOC (nnodes, int);
+    if (!invnames) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < nlight; i++)
+        invnames[light[i]->name] = i;
+    for (i = 0; i < nheavy; i++)
+        invnames[heavy[i]->name] = -i;
+
+
+    do {
+        int nodeschecked = 0;
+        int saver = 0;
+        int list[NEAR_TRY_NUM];
+        shortedge *s, *snext, *slist = (shortedge *) NULL;
+        CCkdtree localkt;
+        added = 0;
+        maxy = -MAXWEIGHT;
+        for (i = 0; i < nlight; i++) {
+            if (light[i]->y > maxy)
+                maxy = light[i]->y;
+        }
+        for (i = 0; i < nlight; i++)
+            wcoord[i] = ((double) (maxy - light[i]->y)) * 0.5;
+        if (CCkdtree_build (&localkt, nlight, &ldat, wcoord)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        for (i = 0; i < nheavy; i++) {                    /* 1.0 for floats */
+            lbnds[i] = gdat->x[heavy[i]->name] -
+                          (((double) (heavy[i]->y)) * 0.5) - 1.0;
+            gbnds[i] = gdat->x[heavy[i]->name] +
+                          (((double) (heavy[i]->y)) * 0.5) + 1.0;
+        }
+
+        for (i = 0; i < nlight; i++) {
+            if (light[i]->label != -1) {
+                edgeptr *ep;
+                hit = 0;
+                for (ep = light[i]->adj; ep; ep = ep->next) {
+                    if (ep->this->x != ZERO && invnames[ep->other->name] >= 0)
+                        CCkdtree_delete (&localkt, invnames[ep->other->name]);
+                }
+                nodeschecked++;
+                if (CCkdtree_node_k_nearest (&localkt, nlight, i, NEAR_TRY_NUM,
+                                           &ldat, wcoord, list)) {
+                    fprintf (stderr, "node nearest failed\n");
+                    CCkdtree_free (&localkt);
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                for (j = NEAR_TRY_NUM - 1; j >= 0; j--) {
+                    if (list[j] != -1)
+                        hit += precheckoutedge (light[i],
+                                                light[list[j]], &slist);
+                }
+                for (j = 0; j < nheavy; j++) {
+                    if (heavy[j]->label == -1) {
+                        if (xcoord[i] +
+                               (((double) light[i]->y) * 0.5) > lbnds[j] &&
+                            xcoord[i] -
+                               (((double) light[i]->y) * 0.5) < gbnds[j]) {
+                            hit += precheckoutedge (light[i], heavy[j], &slist);
+                        } else {
+                            saver++;
+                        }
+                    }
+                }
+                added += hit;
+                if (hit == 0)
+                    light[i]->label = -1;
+                for (ep = light[i]->adj; ep; ep = ep->next) {
+                    if (ep->this->x != ZERO && invnames[ep->other->name] >= 0)
+                        CCkdtree_undelete (&localkt, invnames[ep->other->name]);
+                }
+            }
+        }
+        for (j = 0; j < nheavy; j++) {
+            if (heavy[j]->label != -1) {
+                hit = 0;
+                nodeschecked++;
+                for (i = 0; i < nlight; i++) {
+                    if (xcoord[i] + (((double) light[i]->y) * 0.5) > lbnds[j] &&
+                        xcoord[i] - (((double) light[i]->y) * 0.5) < gbnds[j]) {
+                        hit += precheckoutedge (light[i], heavy[j], &slist);
+                    } else {
+                        saver++;
+                    }
+                }
+                for (i = 0; i < j; i++) {
+                    if (gdat->x[heavy[i]->name] +
+                          (((double) heavy[i]->y) * 0.5) > lbnds[j] &&
+                        gdat->x[heavy[i]->name] -
+                          (((double) heavy[i]->y) * 0.5) < gbnds[j]) {
+                        hit += precheckoutedge (heavy[i], heavy[j], &slist);
+                    }
+                }
+                for (i = j + 1; i < nheavy; i++) {
+                    if (heavy[i]->label == -1) {
+                        if (gdat->x[heavy[i]->name] +
+                              (((double) heavy[i]->y) * 0.5) > lbnds[j] &&
+                            gdat->x[heavy[i]->name] -
+                              (((double) heavy[i]->y) * 0.5) < gbnds[j]) {
+                            hit += precheckoutedge (heavy[i], heavy[j], &slist);
+                        }
+                    }
+                }
+                added += hit;
+                if (hit == 0)
+                    heavy[j]->label = -1;
+            }
+        }
+
+        printf ("Need to check %d edges (saved %d checks)\n", added, saver);
+        fflush (stdout);
+        CCkdtree_free (&localkt);
+
+        added = 0;
+        for (s = slist; s; s = snext) {
+            snext = s->next;
+            if (checkoutedge (s->ends[0], s->ends[1], &hit)) {
+                fprintf (stderr, "checkoutedge failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            added += hit;
+            shortedgefree (s);
+        }
+        totaladded += added;
+        printf ("Pass %d: %d edges added (%d total), %d nodes checked\n",
+                              passcount++, added, totaladded, nodeschecked);
+        fflush (stdout);
+    } while (added);
+    *radded = totaladded;
+
+CLEANUP:
+
+    CC_IFFREE (invnames, int);
+    CC_IFFREE (wcoord, double);
+    CC_IFFREE (order, node *);
+    if (nheavy) {
+        CC_IFFREE (xcoord, double);
+        CC_IFFREE (ycoord, double);
+        CC_IFFREE (lbnds, double);
+        CC_IFFREE (gbnds, double);
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void initlist (node *head, node *tail, node *head2, node *tail2)
+#else
+static void initlist (head, tail, head2, tail2)
+node *head;
+node *tail;
+node *head2;
+node *tail2;
+#endif
+{
+    node *n, *p;
+    int bound;
+    double *xcoord = gdat->x;
+    double scale;
+
+    if (gdat->norm == CC_GEOGRAPHIC)
+        scale = CC_GEOGRAPHIC_SCALE;
+    else if (gdat->norm == CC_ATT)
+        scale = CC_ATT_SCALE;
+    else
+        scale = 1.0;
+
+    head->sort.order = -MAXWEIGHT;
+    tail->sort.order = MAXWEIGHT;
+    head->sort.next = tail;
+    head->sort.prev = (node **) NULL;
+    tail->sort.next = (node *) NULL;
+    tail->sort.prev = &(head->sort.next);
+    head2->sort.order = MAXWEIGHT;
+    tail2->sort.order = -MAXWEIGHT;
+    head2->sort.next = tail2;
+    head2->sort.prev = (node **) NULL;
+    tail2->sort.next = (node *) NULL;
+    tail2->sort.prev = &(head2->sort.next);
+
+    for (n = nodellist; n; n = n->next) {
+        bound = (2 * ((int) (scale * xcoord[n->name]))) - n->y;
+        for (p = head->sort.next; p->sort.order < bound; p = p->sort.next);
+        n->sort.order = bound;
+        n->sort.next = p;
+        n->sort.prev = p->sort.prev;
+        *(n->sort.prev) = n;
+        p->sort.prev = &(n->sort.next);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int x_fixmatch (int *radded)
+#else
+static int x_fixmatch (radded)
+int *radded;
+#endif
+{
+    node *n1, *n2;
+    int i;
+    int added, hit;
+    int nodeschecked;
+    int edgeschecked;
+    int totaladded = 0;
+    node high_fakehead, high_faketail, low_fakehead, low_faketail;
+    int bound;
+    double *xcoord = gdat->x;
+    double scale;
+
+    if ((gdat->norm & CC_NORM_BITS) != CC_X_NORM_TYPE &&
+        (gdat->norm & CC_NORM_BITS) != CC_KD_NORM_TYPE) {
+        fprintf (stderr, "Cannot run x_fixmatch with norm %d\n", gdat->norm);
+        return 1;
+    }
+
+    if (gdat->norm == CC_GEOGRAPHIC)
+        scale = CC_GEOGRAPHIC_SCALE;
+    else if (gdat->norm == CC_ATT)
+        scale = CC_ATT_SCALE;
+    else
+        scale = 1.0;
+
+    initlist (&high_fakehead, &high_faketail, &low_fakehead, &low_faketail);
+
+    do {
+        added = 0;
+        nodeschecked = 0;
+        edgeschecked = 0;
+        for (i = 0; i < nnodes; i++) {
+            n1 = nodenames[i];
+            *(n1->sort.prev) = n1->sort.next;
+            n1->sort.next->sort.prev = n1->sort.prev;
+            if (n1->label != -1) {
+                nodeschecked++;
+                n1->label = -1;
+                bound = (2 * ((int) (scale * xcoord[n1->name]))) + n1->y + 3;
+                 /* Need the +3 to handle floating point data */
+                for (n2 = high_fakehead.sort.next; n2->sort.order < bound;
+                     n2 = n2->sort.next) {
+                    edgeschecked++;
+                    if (checkoutedge (n1, n2, &hit)) {
+                        fprintf (stderr, "checkoutedge failed\n");
+                        return 1;
+                    }
+                    added += hit;
+                }
+                bound = (2 * ((int) (scale * xcoord[n1->name]))) - n1->y - 3;
+                for (n2 = low_fakehead.sort.next; n2->sort.order > bound;
+                     n2 = n2->sort.next) {
+                    edgeschecked++;
+                    if (checkoutedge (n1, n2, &hit)) {
+                        fprintf (stderr, "checkoutedge failed\n");
+                        return 1;
+                    }
+                    added += hit;
+                }
+            }
+            bound = (2 * ((int) (scale * xcoord[n1->name]))) + n1->y;
+            for (n2 = low_fakehead.sort.next; n2->sort.order > bound;
+                 n2 = n2->sort.next);
+            n1->sort.order = bound;
+            n1->sort.next = n2;
+            n1->sort.prev = n2->sort.prev;
+            *(n1->sort.prev) = n1;
+            n2->sort.prev = &n1->sort.next;
+        }
+        totaladded += added;
+        printf ("Forward pass completed, %d nodes checked, %d edges checked\n",
+                nodeschecked, edgeschecked);
+        printf ("    %d edges added, total %d edges added\n",
+                added, totaladded);
+        if (added == 0)
+            break;
+        added = 0;
+        nodeschecked = 0;
+        edgeschecked = 0;
+        for (i = nnodes - 1; i >= 0; i--) {
+            n1 = nodenames[i];
+            *(n1->sort.prev) = n1->sort.next;
+            n1->sort.next->sort.prev = n1->sort.prev;
+            if (n1->label != -1) {
+                nodeschecked++;
+                n1->label = -1;
+                bound = (2 * ((int) (scale * xcoord[n1->name]))) + n1->y + 3;
+                for (n2 = high_fakehead.sort.next; n2->sort.order < bound;
+                     n2 = n2->sort.next) {
+                    edgeschecked++;
+                    if (checkoutedge (n1, n2, &hit)) {
+                        fprintf (stderr, "checkoutedge failed\n");
+                        return 1;
+                    }
+                    added += hit;
+                }
+                bound = (2 * ((int) (scale * xcoord[n1->name]))) - n1->y - 3;
+                for (n2 = low_fakehead.sort.next; n2->sort.order > bound;
+                     n2 = n2->sort.next) {
+                    edgeschecked++;
+                    if (checkoutedge (n1, n2, &hit)) {
+                        fprintf (stderr, "checkoutedge failed\n");
+                        return 1;
+                    }
+                    added += hit;
+                }
+            }
+            bound = (2 * ((int) (scale * xcoord[n1->name]))) - n1->y;
+            for (n2 = high_fakehead.sort.next; n2->sort.order < bound;
+                 n2 = n2->sort.next);
+            n1->sort.order = bound;
+            n1->sort.next = n2;
+            n1->sort.prev = n2->sort.prev;
+            *(n1->sort.prev) = n1;
+            n2->sort.prev = &n1->sort.next;
+        }
+        totaladded += added;
+        printf ("Backward pass completed, %d nodes checked, %d edges checked\n",
+                nodeschecked, edgeschecked);
+        printf ("    %d edges added, total %d edges added\n",
+                added, totaladded);
+    } while (added);
+    *radded = totaladded;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int junk_fixmatch (int *radded)
+#else
+static int junk_fixmatch (radded)
+int *radded;
+#endif
+{
+    int added, hit, totaladded = 0;
+    node *n1, *n2;
+
+    *radded = 0;
+
+    do {
+        added = 0;
+        for (n1 = nodellist; n1; n1 = n1->next) {
+            for (n2 = n1->next; n2; n2 = n2->next) {
+                if (checkoutedge (n1, n2, &hit)) {
+                    fprintf (stderr, "checkoutedge failed\n");
+                    return 1;
+                }
+                added += hit;
+            }
+        }
+        totaladded += added;
+        printf ("Pass completed: %d edges added, total %d edges added\n",
+                 added, totaladded);
+        fflush (stdout);
+    } while (added);
+
+    *radded = totaladded;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int addbadedge (node *n1, node *n2, int w)
+#else
+static int addbadedge (n1, n2, w)
+node *n1;
+node *n2;
+int w;
+#endif
+{
+    int wbar = -(w - n1->y - n2->y);
+    edgeptr *ep;
+    edge *newe;
+    node *other1 = 0, *other2 = 0;
+
+    for (ep = n1->adj; ep; ep = ep->next) {
+        switch (ep->this->x) {
+        case ONE:
+            flipcycle (n1, ep->this, ZERO);
+            n1->matchcnt--;
+            break;
+        case TWO:
+            if ((ep->this->z -= wbar) < 0) {
+                ep->this->z = 0;
+                ep->this->x = ZERO;
+                n1->matchcnt--;
+                ep->other->matchcnt--;
+                other2 = other1;
+                other1 = ep->other;
+            }
+            break;
+        }
+    }
+    n1->y -= wbar;
+    newe = newedge (n1, n2);
+    if (!newe)
+        return 1;
+    newe->weight = w;
+    newe->z = 0;
+    newe->x = ZERO;
+    newe->pnext = (edge *) NULL;
+    while (n1->matchcnt != TWO)
+        augment (n1);
+    if (other1) {
+        while (other1->matchcnt != TWO)
+            augment (other1);
+    }
+    if (other2) {
+        while (other2->matchcnt != TWO)
+            augment (other2);
+    }
+    return 0;
+}
+
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+
+#ifdef CC_PROTOTYPE_ANSI
+static void y_quicksort (node **list, int *y, int l, int u)
+#else
+static void y_quicksort (list, y, l, u)
+node **list;
+int *y;
+int l, u;
+#endif
+{
+    int i, j, t;
+    int itemp;
+    node *ntemp;
+
+    if (l >= u)
+        return;
+
+    SWAP (y[l], y[(l+u)/2], itemp);
+    SWAP (list[l], list[(l+u)/2], ntemp);
+
+    i = l;
+    j = u + 1;
+    t = y[l];
+
+    while (1) {
+        do i++; while (i <= u && y[i] < t);
+        do j--; while (y[j] > t);
+        if (j < i) break;
+        SWAP (y[i], y[j], itemp);
+        SWAP (list[i], list[j], ntemp);
+    }
+    SWAP (y[l], y[j], itemp);
+    SWAP (list[l], list[j], ntemp);
+    y_quicksort (list, y, l, j - 1);
+    y_quicksort (list, y, i, u);
+}
diff --git a/contrib/blossom/concorde97/INCLUDE/Makefile.common b/contrib/blossom/concorde97/INCLUDE/Makefile.common
new file mode 100644
index 0000000000000000000000000000000000000000..62562580a63e98c39200dda34589833122bc16aa
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/Makefile.common
@@ -0,0 +1,77 @@
+# 
+# rules common to most of the makefiles
+#
+
+OBJS=$(LIBSRCS:.c=.$o)
+
+ifneq ($(OBJS),)
+$(LIB): $(LIB)($(OBJS))
+	$(RANLIB) $(LIB)
+endif
+
+ifneq ($(OBJS),)
+$(ROOT)/concorde.a: $(ROOT)/concorde.a($(OBJS))
+	$(RANLIB) $(ROOT)/concorde.a
+#else
+$(ROOT)/concorde.a:
+endif
+
+depend:
+	mv Makefile Makefile.orig
+	sed -e '/^# DO NOT DELETE THIS LINE -- make depend depends on it.$$/,$$d' < Makefile.orig > Makefile
+	echo "# DO NOT DELETE THIS LINE -- make depend depends on it." >> Makefile
+	echo >> Makefile
+	echo "I=$$(INCLUDE)" >> Makefile
+	echo >> Makefile
+	gcc -DSYSGNUSOLARIS -I$(ROOT)/INCLUDE $(CPLEX_INCFLAG) -MM \
+            `echo $(ALLSRCS) | tr ' ' '\012' | sort -u` | \
+            sed -e 's,../INCLUDE,$$(I),g' -e 's,\.o,.$$o,g' | \
+            awk '{for(i=1;i<=NF;i++){if($$i=="\\"){next;}if(ecnt==0){ \
+            printf("%-12s ",$$i);}else if(ecnt==1){printf("%-10s ",$$i);} \
+            else{if(ecnt>=5&&ecnt%4==1)printf("\\\n        "); \
+            if(substr($$i,1,5)=="$$(I)/")printf("%-15s ",$$i);else \
+            printf ("     %-10s ",$$i);}ecnt++;}printf("\n");ecnt=0;}' >> Makefile
+
+.PHONY: concorde.a
+concorde.a: $(ROOT)/concorde.a
+
+.PHONY: $(ROOT)/BIGGUY/bigguy.a
+$(ROOT)/BIGGUY/bigguy.a:
+	$(MAKE) -C $(ROOT)/BIGGUY bigguy.a
+
+.PHONY: $(ROOT)/CUT/cut.a
+$(ROOT)/CUT/cut.a:
+	$(MAKE) -C $(ROOT)/CUT cut.a
+
+.PHONY: $(ROOT)/EDGEGEN/edgegen.a
+$(ROOT)/EDGEGEN/edgegen.a:
+	$(MAKE) -C $(ROOT)/EDGEGEN edgegen.a
+
+.PHONY: $(ROOT)/FMATCH/fmatch.a
+$(ROOT)/FMATCH/fmatch.a:
+	$(MAKE) -C $(ROOT)/FMATCH fmatch.a
+
+.PHONY: $(ROOT)/KDTREE/kdtree.a
+$(ROOT)/KDTREE/kdtree.a:
+	$(MAKE) -C $(ROOT)/KDTREE kdtree.a
+
+.PHONY: $(ROOT)/LINKERN/linkern.a
+$(ROOT)/LINKERN/linkern.a:
+	$(MAKE) -C $(ROOT)/LINKERN linkern.a
+
+.PHONY: $(ROOT)/LP/lp.a
+$(ROOT)/LP/lp.a:
+	$(MAKE) -C $(ROOT)/LP lp.a
+
+.PHONY: $(ROOT)/TSP/tsp.a
+$(ROOT)/TSP/tsp.a:
+	$(MAKE) -C $(ROOT)/TSP tsp.a
+
+.PHONY: $(ROOT)/UTIL/util.a
+$(ROOT)/UTIL/util.a:
+	$(MAKE) -C $(ROOT)/UTIL util.a
+
+.PHONY: $(ROOT)/XSTUFF/Xstuff.a
+$(ROOT)/XSTUFF/Xstuff.a:
+	$(MAKE) -C $(ROOT)/XSTUFF Xstuff.a
+
diff --git a/contrib/blossom/concorde97/INCLUDE/Xstuff.h b/contrib/blossom/concorde97/INCLUDE/Xstuff.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8c615030e30ae2db0d65296fd596b98b6aad085
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/Xstuff.h
@@ -0,0 +1,35 @@
+#ifndef __XSTUFF_H
+#define __XSTUFF_H
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    Xfastcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xslowcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xfastsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xexactsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xcliquetrees (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xconsecutiveones (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+                      int *elist, double *x, CCtsp_lpcuts *pool),
+    Xnecklacecuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+                      int *elist, double *x, CCtsp_lpcuts *pool);
+
+#else
+
+int
+    Xfastcuts (),
+    Xslowcuts (),
+    Xfastsubtours (),
+    Xexactsubtours (),
+    Xcliquetrees (),
+    Xconsecutiveones (),
+    Xnecklacecuts ();
+
+#endif
+
+#endif  /* __XSTUFF_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/bigguy.h b/contrib/blossom/concorde97/INCLUDE/bigguy.h
new file mode 100644
index 0000000000000000000000000000000000000000..701acb98a3cd3c8c25778f084a898b5033c790a5
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/bigguy.h
@@ -0,0 +1,93 @@
+#ifndef  __BIGGUY_H
+#define  __BIGGUY_H
+
+#include "util.h"
+
+#ifdef  CC_BIGGUY_LONGLONG
+
+typedef long long CCbigguy;
+
+#define CCbigguy_FRACBITS 32
+#define CCbigguy_DUALSCALE (((CCbigguy) 1) << CCbigguy_FRACBITS)
+#define CCbigguy_FRACPART(x) ((x) & (CCbigguy_DUALSCALE-1))
+#define CCbigguy_MAXBIGGUY (((((CCbigguy) 1) << 62) - 1) + \
+                            (((CCbigguy) 1) << 62))
+#define CCbigguy_MINBIGGUY (-CCbigguy_MAXBIGGUY)
+#define CCbigguy_bigguytod(x) (((double) (x)) / ((double) CCbigguy_DUALSCALE))
+#define CCbigguy_itobigguy(d) ((CCbigguy) ((d) * (double) CCbigguy_DUALSCALE))
+#define CCbigguy_ceil(x) (CCbigguy_FRACPART(x) ? \
+        ((x) + (CCbigguy_DUALSCALE - CCbigguy_FRACPART(x))) : (x))
+#define CCbigguy_cmp(x,y) (((x) < (y)) ? -1 : ((x) > (y)) ? 1 : 0)
+#define CCbigguy_ZERO ((CCbigguy) 0)
+#define CCbigguy_ONE ((CCbigguy) CCbigguy_DUALSCALE)
+#define CCbigguy_addmult(x,y,m) ((*x) += (y)*(m))
+#define CCbigguy_dtobigguy(d) ((CCbigguy) ((d) * (double) CCbigguy_DUALSCALE))
+
+#else /* CC_BIGGUY_LONGLONG */
+
+typedef struct CCbigguy {
+    unsigned short ihi;
+    unsigned short ilo;
+    unsigned short fhi;
+    unsigned short flo;
+} CCbigguy;
+
+extern const CCbigguy CCbigguy_MINBIGGUY;
+extern const CCbigguy CCbigguy_MAXBIGGUY;
+extern const CCbigguy CCbigguy_ZERO;
+extern const CCbigguy CCbigguy_ONE;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+    void
+        CCbigguy_addmult (CCbigguy *x, CCbigguy y, short m);
+
+    int
+        CCbigguy_cmp (CCbigguy x, CCbigguy y);
+
+    double
+        CCbigguy_bigguytod (CCbigguy x);
+
+    CCbigguy
+        CCbigguy_itobigguy (int d),
+        CCbigguy_dtobigguy (double d),
+        CCbigguy_ceil (CCbigguy x);
+
+#else
+
+    void
+        CCbigguy_addmult ();
+
+    int
+        CCbigguy_cmp ();
+
+    double
+        CCbigguy_bigguytod ();
+
+    CCbigguy
+        CCbigguy_itobigguy (),
+        CCbigguy_dtobigguy (),
+        CCbigguy_ceil ();
+
+#endif
+
+#endif /* CC_BIGGUY_LONGLONG */
+
+#define CCbigguy_add(x,y) (CCbigguy_addmult(x,y,1))
+#define CCbigguy_sub(x,y) (CCbigguy_addmult(x,y,-1))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCbigguy_swrite (CC_SFILE *f, CCbigguy x),
+    CCbigguy_sread (CC_SFILE *f, CCbigguy *x);
+
+#else
+
+int
+    CCbigguy_swrite (),
+    CCbigguy_sread ();
+
+#endif
+
+#endif /* __BIGGUY_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/cut.h b/contrib/blossom/concorde97/INCLUDE/cut.h
new file mode 100644
index 0000000000000000000000000000000000000000..1486577b948b1e1c85c26f4779ce83df1bae86bd
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/cut.h
@@ -0,0 +1,157 @@
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN CUT                        */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+
+#ifndef  __CUT_H
+#define  __CUT_H
+
+
+#define CC_MINCUT_BIGDOUBLE   (100000000000.0)
+#define CC_MINCUT_ONE_EPSILON (0.000001)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCcut_mincut (int ncount, int ecount, int *elist, double *dlen,
+            double *valval, int **cut, int *cutcount),
+    CCcut_violated_cuts (int ncount, int ecount, int *elist, double *dlen,
+            double cutoff, int (*doit_fn) (double, int, int *, void *),
+            void *pass_param),
+    CCcut_mincut_st (int ncount, int ecount, int *elist, double *ecap,
+            int s, int t, double *value, int **cut, int *cutcount),
+    CCcut_linsub (int ncount, int ecount, int *elist, double *x, double cutoff,
+        int (*doit_fn) (double, int, int, void *), void *pass_param),
+    CCcut_connect_components (int ncount, int ecount, int *elist, double *x,
+        int *ncomp, int **compscount, int **comps);
+
+#else
+
+int
+    CCcut_mincut (),
+    CCcut_violated_cuts (),
+    CCcut_mincut_st (),
+    CCcut_linsub (),
+    CCcut_connect_components ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             shrink.c                                    */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CC_SRKnode {
+    struct CC_SRKedge *adj;
+    struct CC_SRKnode *next;
+    struct CC_SRKnode *prev;
+    struct CC_SRKnode *members;
+    struct CC_SRKnode *parent;
+    struct CC_SRKnode *qnext;
+    double             prweight;
+    double             weight;
+    int                num;
+    int                newnum;
+    int                onecnt;
+    int                onqueue;
+} CC_SRKnode;
+
+typedef struct CC_SRKedge {
+    struct CC_SRKnode *end;
+    struct CC_SRKedge *other;
+    struct CC_SRKedge *next;
+    struct CC_SRKedge *prev;
+    double             weight;
+} CC_SRKedge;
+
+typedef struct CC_SRKgraph {
+    struct CC_SRKnode  *nodespace;
+    struct CC_SRKedge  *edgespace;
+    struct CC_SRKnode  *head;
+    struct CC_SRKedge **hit;
+    int                 original_ncount;
+    int                 original_ecount;
+} CC_SRKgraph;
+
+typedef struct CC_SRKexpinfo {
+    int *members;
+    int *memindex;
+} CC_SRKexpinfo;
+
+typedef struct CC_SRKcallback {
+    double  cutoff;
+    void   *pass_param;
+#ifdef CC_PROTOTYPE_ANSI
+    int   (*doit_fn) (double, int, int *, void *);
+#else
+    int   (*doit_fn) ();
+#endif
+} CC_SRKcallback;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCcut_SRK_identify_paths (CC_SRKgraph *G, int *newcount, int onecnt_okay),
+    CCcut_SRK_identify_paths_to_edges (CC_SRKgraph *G, int *newcount,
+        int onecnt_okay),
+    CCcut_SRK_identify_ones (CC_SRKgraph *G, int *count, double epsilon),
+    CCcut_SRK_identify_one_triangles (CC_SRKgraph *G, int *count,
+        CC_SRKnode *qstart, double epsilon),
+    CCcut_SRK_identify_nodes (CC_SRKgraph *G, CC_SRKnode *n, CC_SRKnode *m),
+    CCcut_SRK_init_graph (CC_SRKgraph *G),
+    CCcut_SRK_free_graph (CC_SRKgraph *G),
+    CCcut_SRK_init_expinfo (CC_SRKexpinfo *expand),
+    CCcut_SRK_free_expinfo (CC_SRKexpinfo *expand),
+    CCcut_SRK_init_callback (CC_SRKcallback *cb);
+
+int
+    CCcut_SRK_buildgraph (CC_SRKgraph *G, int ncount, int ecount, int *elist,
+        double *dlen),
+    CCcut_SRK_subtour_shrink (CC_SRKgraph *G, double *minval, double epsilon,
+        CC_SRKcallback *cb, int **cut, int *cutcount),
+    CCcut_SRK_identify_pr_edges (CC_SRKgraph *G, double *minval, int *count,
+        CC_SRKnode *qstart, double epsilon, CC_SRKcallback *cb, int **cut,
+        int *cutcount),
+    CCcut_SRK_defluff (CC_SRKgraph *G),
+    CCcut_SRK_grab_edges (CC_SRKgraph *G, int *oncount, int *oecount,
+        int **olist, double **olen, CC_SRKexpinfo *expand),
+    CCcut_SRK_grab_nodes (CC_SRKgraph *G, CC_SRKexpinfo *expand),
+    CCcut_SRK_trivial (int ncount, CC_SRKexpinfo *expand),
+    CCcut_SRK_expand (CC_SRKexpinfo *expand, int *arr, int size, int **pnewarr,
+        int *pnewsize);
+
+#else
+
+void
+    CCcut_SRK_identify_paths (),
+    CCcut_SRK_identify_paths_to_edges (),
+    CCcut_SRK_identify_ones (),
+    CCcut_SRK_identify_one_triangles (),
+    CCcut_SRK_identify_nodes (),
+    CCcut_SRK_init_graph (),
+    CCcut_SRK_free_graph (),
+    CCcut_SRK_init_expinfo (),
+    CCcut_SRK_free_expinfo (),
+    CCcut_SRK_init_callback ();
+
+int
+    CCcut_SRK_buildgraph (),
+    CCcut_SRK_subtour_shrink (),
+    CCcut_SRK_identify_pr_edges (),
+    CCcut_SRK_defluff (),
+    CCcut_SRK_grab_edges (),
+    CCcut_SRK_grab_nodes (),
+    CCcut_SRK_trivial (),
+    CCcut_SRK_expand ();
+
+#endif
+
+#endif  /* __CUT_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/edgegen.h b/contrib/blossom/concorde97/INCLUDE/edgegen.h
new file mode 100644
index 0000000000000000000000000000000000000000..110d25f3f3467356f0b966db55742500b99740f9
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/edgegen.h
@@ -0,0 +1,144 @@
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN EDGEGEN                    */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+#ifndef __EDGEGEN_H
+#define __EDGEGEN_H
+
+#include "util.h"
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edgegen.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCedgegengroup {
+    struct {
+        int count;
+        int quadnearest;
+        int nearest;
+        int nearest_start;
+        int greedy_start;
+        int random_start;
+        int nkicks;
+    } linkern;
+
+    struct {
+        int twoopt_count;
+        int twoopt5_count;
+        int threeopt_count;
+        int greedy;
+        int nearest_count;
+        int random_count;
+    } tour;
+
+    struct {
+        int wantit;
+        int basic;
+        int priced;
+    } f2match;
+
+    struct {
+        int number;
+        int basic;
+        int priced;
+    } f2match_nearest;
+
+    int    nearest;
+    int    quadnearest;
+    int    want_tree;
+    int    nearest_twomatch_count;
+    int    delaunay;
+    int    mlinkern;
+} CCedgegengroup;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCedgegen_read (char *egname, CCedgegengroup *plan),
+    CCedgegen_edges (CCedgegengroup *plan, int ncount, CCdatagroup *dat,
+        double *wcoord, int *ecount, int **elist);
+void
+    CCedgegen_init_edgegengroup (CCedgegengroup *plan);
+
+#else
+
+int
+    CCedgegen_read (),
+    CCedgegen_edges ();
+void
+    CCedgegen_init_edgegengroup ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             xnear.c                                     */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCxnear {
+    struct CCdatagroup  dat;
+    double             *w;
+    int                *nodenames;
+    int                *invnames;
+} CCxnear;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCedgegen_x_k_nearest (int ncount, int num, CCdatagroup *dat,
+        double *wcoord, int wantlist, int *ecount, int **elist),
+    CCedgegen_x_quadrant_k_nearest (int ncount, int num, CCdatagroup *dat,
+        double *wcoord, int wantlist, int *ecount, int **elist),
+    CCedgegen_x_node_k_nearest (CCxnear *xn, int n, int nearnum, int ncount,
+        int *list),
+    CCedgegen_x_node_quadrant_k_nearest (CCxnear *xn, int n, int nearnum,
+        int ncount, int *list),
+    CCedgegen_x_node_nearest (CCxnear *xn, int ncount, int ni, char *marks),
+    CCedgegen_x_nearest_neighbor_tour (int ncount, int start, CCdatagroup *dat,
+        int *outcycle, double *val),
+    CCedgegen_junk_k_nearest (int ncount, int num, CCdatagroup *dat,
+        double *wcoord, int wantlist, int *ecount, int **elist),
+    CCedgegen_junk_node_k_nearest (CCdatagroup *dat, double *wcoord, int n,
+        int nearnum, int ncount, int *list),
+    CCedgegen_junk_node_nearest (CCdatagroup *dat, double *wcoord, int ncount,
+        int n, char *marks),
+    CCedgegen_junk_nearest_neighbor_tour (int ncount, int start,
+        CCdatagroup *dat, int *outcycle, double *val),
+    CCedgegen_xnear_build (int ncount, CCdatagroup *dat, double *wcoord,
+        CCxnear *xn);
+
+void
+    CCedgegen_xnear_free (int ncount, CCxnear *xn);
+
+#else
+
+int
+    CCedgegen_x_k_nearest (),
+    CCedgegen_x_quadrant_k_nearest (),
+    CCedgegen_x_node_k_nearest (),
+    CCedgegen_x_node_quadrant_k_nearest (),
+    CCedgegen_x_node_nearest (),
+    CCedgegen_x_nearest_neighbor_tour (),
+    CCedgegen_junk_k_nearest (),
+    CCedgegen_junk_node_k_nearest (),
+    CCedgegen_junk_node_nearest (),
+    CCedgegen_junk_nearest_neighbor_tour (),
+    CCedgegen_xnear_build ();
+void
+    CCedgegen_xnear_free ();
+
+#endif
+
+#endif  /* __EDGEGEN_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/fmatch.h b/contrib/blossom/concorde97/INCLUDE/fmatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc708e7d9f79fc6a61e416d4fd446dce4e1e2209
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/fmatch.h
@@ -0,0 +1,20 @@
+#ifndef __FMATCH_H
+#define __FMATCH_H
+
+#include "util.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCfmatch_fractional_2match (int ncount, int ecount, int *elist, int *elen,
+        CCdatagroup *dat, double *val, int *thematching, int *thedual,
+        int *thebasis, int wantbasic);
+
+#else
+
+int
+    CCfmatch_fractional_2match ();
+
+#endif
+
+#endif  /* __FMATCH_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/kdtree.h b/contrib/blossom/concorde97/INCLUDE/kdtree.h
new file mode 100644
index 0000000000000000000000000000000000000000..a940ea5a20fa49c48abe50453c3dae525f99dd09
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/kdtree.h
@@ -0,0 +1,104 @@
+#ifndef __KDTREE_H
+#define __KDTREE_H
+
+#include "util.h"
+
+typedef struct CCkdnode {
+    double           cutval;
+    struct CCkdnode *loson;
+    struct CCkdnode *hison;
+    struct CCkdnode *father;
+    struct CCkdnode *next;
+    struct CCkdbnds *bnds;
+    int              lopt;
+    int              hipt;
+    char             bucket;
+    char             empty;
+    char             cutdim;
+} CCkdnode;
+
+typedef struct CCkdtree {
+    CCkdnode  *root;
+    CCkdnode **bucketptr;
+    int       *perm;
+} CCkdtree;
+
+typedef struct CCkdbnds {
+    double           x[2];
+    double           y[2];
+    struct CCkdbnds *next;
+} CCkdbnds;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCkdtree_free (CCkdtree *kt),
+    CCkdtree_delete (CCkdtree *kt, int k),
+    CCkdtree_delete_all (CCkdtree *kt, int ncount),
+    CCkdtree_undelete (CCkdtree *kt, int k),
+    CCkdtree_undelete_all (CCkdtree *kt, int ncount);
+int
+    CCkdtree_build (CCkdtree *kt, int ncount, CCdatagroup *dat, double *wcoord),
+    CCkdtree_k_nearest (CCkdtree *kt, int ncount, int k, CCdatagroup *dat,
+            double *wcoord, int wantlist, int *ocount, int **olist),
+    CCkdtree_quadrant_k_nearest (CCkdtree *kt, int ncount, int k,
+            CCdatagroup *dat, double *wcoord, int wantlist, int *ocount,
+            int **olist),
+    CCkdtree_node_k_nearest (CCkdtree *kt, int ncount, int n, int k,
+            CCdatagroup *dat, double *wcoord, int *list),
+    CCkdtree_node_quadrant_k_nearest (CCkdtree *kt, int ncount, int n, int k,
+            CCdatagroup *dat, double *wcoord, int *list),
+    CCkdtree_node_nearest (CCkdtree *kt, int n, CCdatagroup *dat,
+            double *wcoord),
+    CCkdtree_fixed_radius_nearest (CCkdtree *kt, CCdatagroup *dat,
+            double *wcoord, int n, double rad,
+            int (*doit_fn) (int, int, void *), void *pass_param),
+    CCkdtree_nearest_neighbor_tour (CCkdtree *kt, int ncount, int start,
+            CCdatagroup *dat, int *outcycle, double *val),
+    CCkdtree_nearest_neighbor_2match (CCkdtree *kt, int ncount, int start,
+            CCdatagroup *dat, int *outmatch, double *val),
+    CCkdtree_prim_spanningtree (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            double *wcoord, int *outtree, double *val),
+    CCkdtree_greedy_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *outcycle, double *val),
+    CCkdtree_far_add_tour (CCkdtree *kt, int ncount, int start,
+            CCdatagroup *dat, int *outcycle, double *val),
+    CCkdtree_qboruvka_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *outcycle, double *val),
+    CCkdtree_boruvka_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *outcycle, double *val),
+    CCkdtree_twoopt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *incycle, int *outcycle, double *val,
+            int in_run_two_and_a_half_opt, int run_silently),
+    CCkdtree_3opt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *incycle, int *outcycle, double *val, int run_silently);
+
+#else
+
+void
+    CCkdtree_free (),
+    CCkdtree_delete (),
+    CCkdtree_delete_all (),
+    CCkdtree_undelete (),
+    CCkdtree_undelete_all ();
+int
+    CCkdtree_build (),
+    CCkdtree_k_nearest (),
+    CCkdtree_quadrant_k_nearest (),
+    CCkdtree_node_k_nearest (),
+    CCkdtree_node_quadrant_k_nearest (),
+    CCkdtree_node_nearest (),
+    CCkdtree_fixed_radius_nearest (),
+    CCkdtree_nearest_neighbor_tour (),
+    CCkdtree_nearest_neighbor_2match (),
+    CCkdtree_prim_spanningtree (),
+    CCkdtree_greedy_tour (),
+    CCkdtree_far_add_tour (),
+    CCkdtree_qboruvka_tour (),
+    CCkdtree_boruvka_tour (),
+    CCkdtree_twoopt_tour (),
+    CCkdtree_3opt_tour ();
+#endif
+
+#endif  /* __KDTREE_H */
+
diff --git a/contrib/blossom/concorde97/INCLUDE/linkern.h b/contrib/blossom/concorde97/INCLUDE/linkern.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc3b6c2d33f5d13e10a20fe7f7918b36ed1d1864
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/linkern.h
@@ -0,0 +1,124 @@
+#ifndef  __LINKERN_H
+#define  __LINKERN_H
+
+#include "util.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CClinkern_tour (int ncount, CCdatagroup *dat, int ecount,
+            int *elist, int stallcount, int repeatcount, int *incycle,
+            int *outcycle, double *val, int run_silently, double time_bound,
+            double length_bound, char *saveit_name);
+
+#else
+
+int
+    CClinkern_tour ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/* Must define exactly one of:                                             */
+/*                                                                         */
+/*          CC_LINKED_LIST_FLIPPER       (flip_llX)                        */
+/*          CC_ARRAY_FLIPPER             (flip_ary)                        */
+/*          CC_TWO_LEVEL_FLIPPER         (flip_two)                        */
+/*          CC_SEGMENTS_FLIPPER          (flip_sg1)                        */
+/*          CC_NO_UNDO_SEGMENTS_FLIPPER  (flip_sg2)                        */
+/*          CC_FULL_SEGMENTS_FLIPPER     (flip_sg3)                        */
+/*          CC_SPLAY_FLIPPER             (flip_sp2)                        */
+/*          CC_BTREE_FLIPPER             (flip_btr)                        */
+/*                                                                         */
+/* NOTE: If MARK_NEIGHBORS is not defined in linkern.c, then               */
+/*       NO_UNDO_SEGMENTS may follow a different improving sequence then   */
+/*       the other flippers, since the next and prevs in turn () will be   */
+/*       with respect to an out-of-date-tour.                              */
+/*                                                                         */
+/***************************************************************************/
+
+
+#define CC_TWO_LEVEL_FLIPPER
+/* #define BTREE_FLIPPER */
+
+#ifdef CC_LINKED_LIST_FLIPPER
+#define CC_EXTRA_INFO_FLIP
+#endif
+
+#ifdef CC_ARRAY_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#endif
+
+#ifdef CC_TWO_LEVEL_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#endif
+
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#define CC_USE_QUICK_FLIPS
+#endif
+
+#ifdef CC_FULL_SEGMENTS_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#endif
+
+#ifdef CC_SPLAY_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#define CC_EXTRA_INFO_FLIP
+#endif
+
+#ifdef CC_BTREE_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#define CC_EXTRA_INFO_FLIP
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CClinkern_flipper_init (int ncount, int *cyc),
+    CClinkern_flipper_reset_perm (int ncount),
+    CClinkern_flipper_reset_temp (int ncount),
+    CClinkern_flipper_next (int x),
+    CClinkern_flipper_prev (int x),
+    CClinkern_flipper_cycle (int *x),
+    CClinkern_flipper_sequence_burst (int x, int y, int z),
+    CClinkern_flipper_sequence (int x, int y, int z);
+
+void
+#ifdef CC_EXTRA_INFO_FLIP
+    CClinkern_flipper_flip (int xprev, int x, int y, int ynext),
+#else
+    CClinkern_flipper_flip (int x, int y),
+#endif
+    CClinkern_flipper_flip_quick (int x, int y),
+    CClinkern_flipper_flip_perm (int x, int y),
+    CClinkern_flipper_sequence_burst_init (int x, int z),
+    CClinkern_flipper_finish (void),
+    CClinkern_flipper_free_world (void);
+
+#else
+
+int
+    CClinkern_flipper_init (),
+    CClinkern_flipper_reset_perm (),
+    CClinkern_flipper_reset_temp (),
+    CClinkern_flipper_next (),
+    CClinkern_flipper_prev (),
+    CClinkern_flipper_cycle (),
+    CClinkern_flipper_sequence_burst (),
+    CClinkern_flipper_sequence ();
+
+void
+    CClinkern_flipper_flip (),
+    CClinkern_flipper_flip_quick (),
+    CClinkern_flipper_flip_perm (),
+    CClinkern_flipper_sequence_burst_init (),
+    CClinkern_flipper_finish (),
+    CClinkern_flipper_free_world ();
+
+#endif
+
+#endif  /* __LINKERN_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/lp.h b/contrib/blossom/concorde97/INCLUDE/lp.h
new file mode 100644
index 0000000000000000000000000000000000000000..988d9f059263dba5df5f996382b2c133c010428c
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/lp.h
@@ -0,0 +1,121 @@
+#ifndef __LP_H
+#define __LP_H
+
+#define  CClp_METHOD_DUAL    1
+#define  CClp_METHOD_BARRIER 2
+
+#define  CClp_SUCCESS        0
+#define  CClp_FAILURE        1
+#define  CClp_UNBOUNDED      2
+#define  CClp_INFEASIBLE     3
+#define  CClp_UNKNOWN        4
+
+typedef struct CClp {
+    struct cpxenv *cplex_env;
+    struct cpxlp  *cplex_lp;
+    int            lp_allocated;
+} CClp;
+
+typedef struct CClpbasis {
+    int       *rstat;
+    int       *cstat;
+    double    *dnorm;
+} CClpbasis;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CClp_init (CClp *lp),
+    CClp_loadlp (CClp *lp, char *name, int ncols, int nrows, int objsense,
+            double *obj, double *rhs, char *sense, int *matbeg, int *matcnt,
+            int *matind, double *matval, double *lb, double *ub),
+    CClp_opt (CClp *lp, int method),
+    CClp_dualopt (CClp *lp),
+    CClp_limited_dualopt (CClp *lp, int lim, int *status, double *upperbound),
+    CClp_primalopt (CClp *lp),
+    CClp_addrows (CClp *lp, int newrows, int newnz, double *rhs, char *sense,
+            int *rmatbeg, int *rmatind, double *rmatval),
+    CClp_addcols (CClp *lp, int newcols, int newnz, double *obj,
+            int *cmatbeg, int *cmatind, double *cmatval, double *lb,
+            double *ub),
+    CClp_delete_row (CClp *lp, int i),
+    CClp_delete_set_of_rows (CClp *lp, int *delstat),
+    CClp_delete_column (CClp *lp, int i),
+    CClp_delete_set_of_columns (CClp *lp, int *delstat),
+    CClp_setbnd (CClp *lp, int col, char lower_or_upper, double bnd),
+    CClp_get_basis_and_norms (CClp *lp, CClpbasis *b),
+    CClp_load_basis_and_norms (CClp *lp, CClpbasis *b),
+    CClp_basis (CClp *lp, int *cstat, int *rstat),
+    CClp_loadbasis (CClp *lp, int *cstat, int *rstat),
+    CClp_getbasis_and_norms (CClp *lp, int *cstat, int *rstat,
+            double *dnorm),
+    CClp_loadbasis_and_norms (CClp *lp, int *cstat, int *rstat,
+                              double *dnorm),
+    CClp_x (CClp *lp, double *x),
+    CClp_rc (CClp *lp, double *rc),
+    CClp_pi_range (CClp *lp, double *pi, int from, int to),
+    CClp_objval (CClp *lp, double *obj),
+    CClp_nonzeros (CClp *lp),
+    CClp_status (CClp *lp, int *status),
+    CClp_getweight (CClp *lp, int nrows, int *rmatbeg, int *rmatind,
+            double *rmatval, double *weight),
+    CClp_dump_lp (CClp *lp, char *fname),
+    CClp_getgoodlist (CClp *lp, int *goodlist, int *goodlen_p,
+            double *downpen, double *uppen),
+    CClp_strongbranch (CClp *lp, int *candidatelist, int ncand,
+            double *downpen, double *uppen, int iterations,
+            double *upperbound),
+    CClp_getfarkasmultipliers (CClp *lp, double *y);
+
+void
+    CClp_init_struct (CClp *lp),
+    CClp_free (CClp *lp),
+    CClp_init_basis (CClpbasis *b),
+    CClp_free_basis (CClpbasis *b),
+    CClp_pivotin (CClp *lp, int i);
+
+#else
+
+int
+    CClp_init (),
+    CClp_loadlp (),
+    CClp_opt (),
+    CClp_dualopt (),
+    CClp_limited_dualopt (),
+    CClp_primalopt (),
+    CClp_addrows (),
+    CClp_addcols (),
+    CClp_delete_row (),
+    CClp_delete_set_of_rows (),
+    CClp_delete_column (),
+    CClp_delete_set_of_columns (),
+    CClp_setbnd (),
+    CClp_get_basis_and_norms (),
+    CClp_load_basis_and_norms (),
+    CClp_basis (),
+    CClp_loadbasis (),
+    CClp_getbasis_and_norms (),
+    CClp_loadbasis_and_norms (),
+    CClp_x (),
+    CClp_rc (),
+    CClp_pi_range (),
+    CClp_objval (),
+    CClp_nonzeros (),
+    CClp_status (),
+    CClp_getweight (),
+    CClp_dump_lp (),
+    CClp_getgoodlist (),
+    CClp_strongbranch (),
+    CClp_getfarkasmultipliers ();
+
+void
+    CClp_init_struct (),
+    CClp_free (),
+    CClp_init_basis (),
+    CClp_free_basis (),
+    CClp_pivotin ();
+
+#endif
+
+
+#endif  /* __LP_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/machdefs.h b/contrib/blossom/concorde97/INCLUDE/machdefs.h
new file mode 100644
index 0000000000000000000000000000000000000000..7612cb3ce47aac1c1ca0a30c4a1e121d4fb7b84e
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/machdefs.h
@@ -0,0 +1,94 @@
+#ifndef __MACHDEFS_H
+#define __MACHDEFS_H
+
+#define NDEBUG
+#define CCSYS_STANDARD
+
+#ifdef  CCSYS_STANDARD
+#define CC_PROTOTYPE_ANSI
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <time.h>
+#define CC_ZEIT_TIMES
+#endif
+
+#ifdef  CCSYS_STANDARD_KNR
+#undef CC_PROTOTYPE_ANSI
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <time.h>
+#define CC_ZEIT_TIMES
+#define const
+#define void int
+#endif
+
+#ifdef  CCSYS_ALTERNATE
+#define CC_PROTOTYPE_ANSI
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <time.h>
+#define CC_ZEIT_RUSAGE
+#endif
+
+#ifdef  CCSYS_SUNOS_GCC
+#define CC_PROTOTYPE_ANSI
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <time.h>
+
+extern int
+    printf (const char *, ...),
+    fprintf (FILE *, const char *, ...),
+    fflush (FILE *),
+    scanf (const char *, ...),
+    sscanf (const char *, const char *, ...),
+    fscanf (FILE *, const char *, ...),
+    fclose (FILE *),
+    _filbuf (FILE *),
+    rename (const char *, const char *),
+    time (int *);
+
+extern void
+    perror (const char *);
+
+#define CC_ZEIT_TIMES
+#endif
+
+
+#ifndef NULL
+#define NULL (0)
+#endif
+
+#endif  /* __MACHDEFS_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/macrorus.h b/contrib/blossom/concorde97/INCLUDE/macrorus.h
new file mode 100644
index 0000000000000000000000000000000000000000..35db43624b2d72296bfae9ce5646b01176fa6781
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/macrorus.h
@@ -0,0 +1,8 @@
+#ifndef  __MACRORUS_H
+#define  __MACRORUS_H
+
+#define CC_SWAP(a,b,t) (((t)=(a)),((a)=(b)),((b)=(t)))
+
+#define CC_OURABS(a) (((a) >= 0) ? (a) : -(a))
+
+#endif  /* __MACRORUS_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/prefix.h b/contrib/blossom/concorde97/INCLUDE/prefix.h
new file mode 100644
index 0000000000000000000000000000000000000000..eebaf8d76c83cb76461f4077e3666cd304049e7c
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/prefix.h
@@ -0,0 +1,9 @@
+#ifndef  __PREFIX_H
+#define  __PREFIX_H
+
+#define CC_PROTOTYPE_ANSI
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#endif  /* __PREFIX_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/tsp.h b/contrib/blossom/concorde97/INCLUDE/tsp.h
new file mode 100644
index 0000000000000000000000000000000000000000..2915941442030e7cb365431f18747e826d9cea39
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/tsp.h
@@ -0,0 +1,996 @@
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN CUT                        */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+
+#ifndef __TSP_H
+#define __TSP_H
+
+#include "util.h"
+#include "edgegen.h"
+#include "bigguy.h"
+#include "lp.h"
+#include "cut.h"
+#include "kdtree.h"
+
+/*************** Tolerances for the LP and Cutting routines ***************/
+
+#define CCtsp_MIN_VIOL (0.00001)   /* min violation for cut to be added to lp */
+#define CCtsp_CUTS_NEXT_TOL (0.0001)       /* to try next level  */
+#define CCtsp_CUTS_NEXT_ROUND (0.00000001) /* if improve is less, stop round */
+#define CCtsp_PRICE_RCTHRESH  (-0.00001)   /* to add a bad edge */
+#define CCtsp_PRICE_MAXPENALTY (0.49)      /* penalty permitted in addbad */
+#define CCtsp_PHASE1_RCTHRESH (-0.000000001)
+#define CCtsp_PHASE1_MAXPENALTY (0.00000001)
+#define CCtsp_EDGE_LIFE (1000000) /* 200 */  /* Large for subtour runs */
+#define CCtsp_CUT_LIFE  (50)
+#define CCtsp_CUT_BATCH (250)     /* number of new cuts before lp optimize */
+#define CCtsp_STORE_BATCH (50)    /* number of new cuts before lp addrows  */
+#define CCtsp_INTTOL (0.0001)     /* used to check if lp soln is integral  */
+
+/************************** Branching Strategies  ************************/
+
+#define CCtsp_BRANCH_MIDDLE 1
+#define CCtsp_BRANCH_STRONG 2
+
+/*************************************************************************/
+
+#define CCtsp_LP_MAXDOUBLE  1e30
+
+#define CCtsp_CUTRHS(c) (3*(c)->cliquecount - (c)->handlecount - 1)
+
+typedef struct CCtsp_lpnode {
+    int                 deg;
+    int                 mark;
+    struct CCtsp_lpadj *adj;
+} CCtsp_lpnode;
+
+typedef struct CCtsp_lpedge {
+    int ends[2];   /* ends[0] should always be < ends[1] */
+    int fixed;
+    int branch;    /* < 0 means set to 0 and > 0 means set to 1 */
+    int len;
+    int age;
+    int coef;      /* should be maintained at zero */
+    int coefnext;  /* should be maintained at -2 */
+} CCtsp_lpedge;
+
+typedef struct CCtsp_lpadj {
+    int to;
+    int edge;
+} CCtsp_lpadj;
+
+typedef struct CCtsp_lpgraph {
+    int           ncount;
+    int           espace;
+    int           ecount;
+    int           nodemarker;
+    CCtsp_lpnode *nodes;
+    CCtsp_lpedge *edges;
+    CCtsp_lpadj  *adjspace;
+    int           adjstart;
+    int           adjend;
+} CCtsp_lpgraph;
+
+typedef struct CCtsp_predge {
+    int    ends[2];
+    int    len;
+    double rc;
+} CCtsp_predge;
+
+typedef struct CCtsp_pricegroup {
+    int                    ncount;
+    int                    espace;
+    int                    ecount;
+    CCtsp_lpnode          *nodes;
+    CCtsp_predge          *edges;
+    int                    cliquecount;
+    struct CCtsp_lpclique *cliques; /* just a copy of the pointer */
+    CCtsp_lpgraph         *graph;   /* pointer to the copy in a CCtsp_lp */
+    CCtsp_lpadj           *adjspace;
+    double                *node_pi;
+    double                *clique_pi;
+    double                 penalty;
+} CCtsp_pricegroup;
+
+typedef struct CCtsp_extraedge {
+    int ends[2];
+} CCtsp_extraedge;
+
+typedef struct CCtsp_sparser {
+    unsigned int node : 24;
+    unsigned int mult : 8;
+} CCtsp_sparser;
+
+typedef struct CCtsp_segment {
+    int lo;
+    int hi;
+} CCtsp_segment;
+
+typedef struct CCtsp_lpclique {
+    int                   segcount;
+    struct CCtsp_segment *nodes;
+    int                   hashnext;
+    int                   refcount;
+} CCtsp_lpclique;
+
+#define CC_FOREACH_NODE_IN_CLIQUE(i,c,tmp) \
+    for(tmp=0;tmp<(c).segcount;tmp++) \
+        for(i=(c).nodes[tmp].lo;i<=(c).nodes[tmp].hi;i++)
+
+#define CCtsp_NEWCUT_AGE (-1)
+
+typedef struct CCtsp_lpcut {
+    int                   handlecount;
+    int                   cliquecount;
+    int                   modcount;
+    int                   age;
+    int                   rhs;
+    char                  sense;
+    char                  branch;
+    int                  *cliques;
+    struct CCtsp_sparser *mods;
+} CCtsp_lpcut;
+
+typedef struct CCtsp_lpcut_in {
+    int                    handlecount;
+    int                    cliquecount;
+    int                    rhs;
+    char                   sense;
+    char                   branch;
+    CCtsp_lpclique        *cliques;
+    struct CCtsp_lpcut_in *next;
+    struct CCtsp_lpcut_in *prev;
+} CCtsp_lpcut_in;
+
+typedef struct CCtsp_lp_result {
+    double         ub;
+    double         lb;
+    int            ecount;
+    int           *elist;
+    double        *x;
+    double        *rc;
+} CCtsp_lp_result;
+
+typedef struct CCtsp_lpcuts {
+    int            cutcount;
+    int            cliqueend;
+    int            cutspace;
+    int            cliquespace;
+    int            cliquehashsize;
+    int            cliquefree;
+    int            *cliquehash;
+    CCtsp_lpcut    *cuts;
+    CCtsp_lpclique *cliques;
+    CCgenhash      *cuthash;
+    char           *tempcuthash;
+    int            tempcuthashsize;
+} CCtsp_lpcuts;
+
+typedef struct CCtsp_bigdual {
+    int            cutcount;
+    CCbigguy      *node_pi;
+    CCbigguy      *cut_pi;
+} CCtsp_bigdual;
+
+typedef struct CCtsp_tighten_info {
+    int    ncall;
+    int    nfail;
+    int    nadd;
+    int    nadd_tied;
+    int    ndel;
+    int    ndel_tied;
+    double add_delta;
+    double del_delta;
+    double time;
+} CCtsp_tighten_info;
+
+typedef struct CCtsp_branchobj {
+    int             depth;
+    int             rhs;
+    int             ends[2];
+    char            sense;
+    CCtsp_lpclique *clique;
+} CCtsp_branchobj;
+
+typedef struct CCtsp_cutselect {
+    int    cutpool;
+    int    connect;
+    int    segments;
+    int    exactsubtour;
+    int    tighten_lp;
+    int    decker_lp;
+    int    teething_lp;
+    int    tighten_pool;
+    int    decker_pool;
+    int    teething_pool;
+    int    maxchunksize;
+    int    Xfastcuts;
+    int    Xexactsubtours;
+    int    Xslowcuts;
+    int    consecutiveones;
+    int    necklace;
+    int    usetighten;     /* set to 1 to tighten before cuts are added */
+    int    extra_connect;  /* set to 1 to force a connected solution */
+    double nexttol;
+    double roundtol;
+} CCtsp_cutselect;
+
+/* nodes are reordered to match compression tour */
+
+typedef struct CCtsp_genadj {
+    int                     deg;
+    struct CCtsp_genadjobj *list;
+} CCtsp_genadj;
+
+typedef struct CCtsp_genadjobj {
+    int end;
+    int len;
+} CCtsp_genadjobj;
+
+typedef struct CCtsp_edgegenerator {
+    double                    *node_piest;
+    struct CCdatagroup        *dg;
+    int                       *supply;
+    CCkdtree                  *kdtree;
+    CCxnear                   *xnear;
+    struct CCtsp_xnorm_pricer *xprice;
+    CCtsp_genadjobj           *adjobjspace;
+    CCtsp_genadj              *adj;
+    int                        ncount;
+    int                        nneighbors;
+    int                        start;
+    int                        current;
+    int                        supplyhead;
+    int                        supplycount;
+} CCtsp_edgegenerator;
+
+typedef struct CCtsp_xnorm_pricer_val {
+    double                         val;
+    struct CCtsp_xnorm_pricer_val *next;
+    struct CCtsp_xnorm_pricer_val *prev;
+    int                            index;
+} CCtsp_xnorm_pricer_val;
+
+typedef struct CCtsp_xnorm_pricer {
+    CCdatagroup            *dat;
+    double                 *pi;
+    int                    *order;
+    CCtsp_xnorm_pricer_val *xminuspi_space;
+    CCtsp_xnorm_pricer_val *xminuspi;
+    int                    *invxminuspi;
+    int                     ncount;
+} CCtsp_xnorm_pricer;
+
+typedef struct CCtsp_lp {
+    CCtsp_lpgraph              graph;
+    CCtsp_lpcuts               cuts;
+    CCtsp_lpcuts              *pool;
+    CClp                       lp;
+    int                       *perm;
+    CCdatagroup               *dat;
+    int                        fullcount;
+    struct CCtsp_genadj       *fulladj;
+    struct CCtsp_genadjobj    *fulladjspace;
+    int                        nfixededges;
+    int                       *fixededges;
+    struct CCtsp_qsparsegroup *sparsifier;
+    int                        edge_life;
+    int                        cut_life;
+    char                      *name;
+    int                        id;
+    int                        parent_id;
+    int                        root;
+    double                     upperbound;
+    double                     lowerbound;
+    CCbigguy                   exact_lowerbound;
+    CCtsp_bigdual             *exact_dual;
+    int                        infeasible;
+    int                        full_edges_valid;
+    CClpbasis                 *basis;
+    CCtsp_lpcut_in             cutqueue;    /* dummy entry for doubly-linked
+                                               list */
+    CCtsp_lp_result            result;
+    CCtsp_tighten_info         tighten_stats;
+    int                        branchdepth;
+    CCtsp_branchobj           *branchhistory;
+} CCtsp_lp;
+
+typedef struct CCtsp_lprow {
+    int           rowcnt;
+    int           nzcnt;
+    char         *sense;
+    double       *rhs;
+    int          *begin;      /* offset into the array for start of row */
+    int           indexspace;
+    int          *indices;    /* the column indices of the row entries  */
+    int           entryspace;
+    double       *entries;    /* the matrix entries                     */
+} CCtsp_lprow;
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             tsp_lp.c                                    */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_cutting_loop (CCtsp_lp *lp, CCtsp_cutselect *sel, int savelp),
+    CCtsp_subtour_loop (CCtsp_lp *lp),
+    CCtsp_pricing_loop (CCtsp_lp *lp, double *bnd),
+    CCtsp_init_cutselect (CCtsp_lp *lp, CCtsp_cutselect *s),
+    CCtsp_call_x_heuristic (CCtsp_lp *lp, double *val, int *outcyc),
+    CCtsp_bb_cutting (char *probname, int probnum, int ncount,
+            CCdatagroup *dat, int *ptour, double *upbound, CCtsp_lpcuts *pool,
+            CCtsp_cutselect *sel, double *val, int *prune, int *foundtour,
+            int *besttour),
+    CCtsp_init_lp (CCtsp_lp **lp, char *probname, int probnum,
+            char *probfilename, int ncount, CCdatagroup *dat, int ecount,
+            int *elist, int *elen, int excount, int *exlist, int *exlen,
+            int exvalid, int *ptour, double initial_ub, CCtsp_lpcuts *pool),
+    CCtsp_bb_init_lp (CCtsp_lp **lp, char *probname, int probnum,
+            int ncount, CCdatagroup *dat, int *ptour, double initial_ub,
+            CCtsp_lpcuts *pool),
+    CCtsp_get_lp_result (CCtsp_lp *lp, double *lb, double *ub, int *ecount,
+            int **elist, double **x, double **rc, double **node_pi,
+            double **cut_pi),
+    CCtsp_process_cuts (CCtsp_lp *lp, int *pnadded, int tighten),
+    CCtsp_add_cut_to_cutlist (CCtsp_lpcuts *cuts, CCtsp_lpcut *c),
+    CCtsp_add_cut (CCtsp_lp *lp, CCtsp_lpcut_in *d, CCtsp_lprow *cr),
+    CCtsp_lpcut_in_nzlist (CCtsp_lpgraph *g, CCtsp_lpcut_in *c),
+    CCtsp_add_nzlist_to_lp (CCtsp_lp *lp, int nzlist, int rhs, char sense,
+            CCtsp_lprow *cr),
+    CCtsp_add_vars_to_lp (CCtsp_lp *lp, CCtsp_predge *prlist, int n),
+    CCtsp_update_result (CCtsp_lp *lp),
+    CCtsp_infeas_recover (CCtsp_lp *lp),
+    CCtsp_test_cut_branch (CCtsp_lp *lp, CCtsp_lpclique *c, double *down,
+            double *up),
+    CCtsp_register_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut_in *c,
+            CCtsp_lpcut *new),
+    CCtsp_addbad_variables (CCtsp_lp *lp, struct CCtsp_edgegenerator *eg,
+            double *ppenalty, int *pnadded, double rcthresh,
+            double maxpenalty, int phase1, int *feasible),
+    CCtsp_eliminate_variables (CCtsp_lp *lp),
+    CCtsp_build_lpgraph (CCtsp_lpgraph *g, int ncount, int ecount,
+            int *elist, int *elen),
+    CCtsp_build_lpadj (CCtsp_lpgraph *g, int estart, int eend),
+    CCtsp_add_multiple_rows (CCtsp_lp *lp, CCtsp_lprow *cr),
+    CCtsp_delete_cut (CCtsp_lp *lp, int i),
+    CCtsp_find_edge (CCtsp_lpgraph *g, int from, int to),
+    CCtsp_find_branch (CCtsp_lp *lp, int nwant, int *ngot,
+            CCtsp_branchobj **bobj, double *val, int **cyc, int usecliques),
+    CCtsp_bb_find_branch (char *probname, int probnum, int ncount,
+            CCdatagroup *dat, int *ptour, double *upperbound,
+            CCtsp_lpcuts *pool, CCtsp_branchobj **b, int usecliques,
+            int *foundtour, int *besttour),
+    CCtsp_check_integral (CCtsp_lp *lp, double *val, int **cyc, int *yesno),
+    CCtsp_find_branch_edge (CCtsp_lp *lp, int *n0, int *n1, double *val,
+            int **cyc, int branchtype),
+    CCtsp_find_branch_cliques (CCtsp_lp *lp, int nwant, int *ngot,
+            CCtsp_lpclique **bcliques, double **bval),
+    CCtsp_execute_branch (CCtsp_lp *lp, CCtsp_branchobj *b),
+    CCtsp_execute_unbranch (CCtsp_lp *lp, CClpbasis *basis),
+    CCtsp_splitprob (CCtsp_lp *lp, CCtsp_branchobj *b, int child0, int child1),
+    CCtsp_bb_splitprob (char *probname, int probnum, int ncount,
+            CCdatagroup *dat, int *ptour, double initial_ub, CCtsp_lpcuts *pool,
+            CCtsp_branchobj *b, int child0, int child1, double *val0,
+            double *val1, int *prune0, int *prune1),
+    CCtsp_dumptour (int ncount, CCdatagroup *dat, int *perm, char *probname,
+            int *tour),
+    CCtsp_add_branchhistory_to_lp (CCtsp_lp *lp),
+    CCtsp_easy_dfs_brancher (CCtsp_lp *lp, CCtsp_cutselect *sel, int depth,
+            double *upbound, int *bbcount, int usecliques, int *besttour),
+    CCtsp_bfs_brancher (char *probname, int id, double lowerbound,
+            CCtsp_cutselect *sel, double *upbound, int *bbcount, int usecliques,
+            CCdatagroup *mydat, int *ptour, CCtsp_lpcuts *pool, int ncount,
+            int *besttour),
+    CCtsp_do_interactive_branch (CCtsp_lp *lp),
+    CCtsp_inspect_full_edges (CCtsp_lp *lp),
+    CCtsp_read_probfile (CCtsp_lp *lp, char *fname, int ncount),
+    CCtsp_read_probfile_id (CCtsp_lp *lp, char *fname, int id, int ncount),
+    CCtsp_write_probfile_sav (CCtsp_lp *lp),
+    CCtsp_write_probfile_id (CCtsp_lp *lp),
+    CCtsp_dump_x (CCtsp_lp *lp, char *fname),
+    CCtsp_exact_price (CCtsp_lp *lp, CCbigguy *bound, int phase1),
+    CCtsp_edge_elimination (CCtsp_lp *lp),
+    CCtsp_exact_dual (CCtsp_lp *lp),
+    CCtsp_verify_infeasible_lp (CCtsp_lp *lp, int *yesno),
+    CCtsp_verify_lp_prune (CCtsp_lp *lp, int *yesno),
+    CCtsp_tighten_lpcut_in (CCtsp_lpgraph *g, CCtsp_lpcut_in *c,
+            double *x, CCtsp_lpcut_in *d, CCtsp_tighten_info *stats,
+            double *pimprove),
+    CCtsp_tighten_lpcut (CCtsp_lpgraph *g, CCtsp_lpclique *cliques,
+            CCtsp_lpcut *c, double *x, CCtsp_lpcut_in *d,
+            CCtsp_tighten_info *stats, double *pimprove),
+    CCtsp_test_pure_comb (int ncount, CCtsp_lpcut_in *c, int *yes_no,
+            int *handle),
+    CCtsp_test_pseudocomb (int ncount, CCtsp_lpcut_in *c, int handle,
+            int *yes_no),
+    CCtsp_test_teeth_disjoint (int ncount, CCtsp_lpcut_in *c, int handle,
+            int *yes_no),
+    CCtsp_find_pure_handle (int ncount, CCtsp_lpcut_in *c, int *handle),
+    CCtsp_comb_to_double_decker (CCtsp_lpgraph *g, double *x,
+            CCtsp_lpcut_in *c, CCtsp_lpcut_in **d),
+    CCtsp_teething (CCtsp_lpgraph *g, double *x, CCtsp_lpcut_in *cut,
+            CCtsp_lpcut_in **newcut),
+    CCtsp_init_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts **pool),
+    CCtsp_write_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts  *pool),
+    CCtsp_search_cutpool (CCtsp_lpcuts *pool, CCtsp_lpcut_in **cuts,
+            int *cutcount, int ncount, int ecount, int *elist, double *x),
+    CCtsp_search_cutpool_cliques (CCtsp_lpcuts *pool, CCtsp_lpclique **cliques,
+            int *cliquecount, int ncount, int ecount, int *elist, double *x,
+            double maxdelta, int maxcliques, double **cliquevals),
+    CCtsp_branch_cutpool_cliques (CCtsp_lpcuts *pool, CCtsp_lpclique **cliques,
+            int *cliquecount, int ncount, int ecount, int *elist, double *x,
+            int nwant, double **cliquevals),
+    CCtsp_add_to_cutpool (CCtsp_lpcuts *pool, CCtsp_lpcuts *cuts,
+            CCtsp_lpcut *c),
+    CCtsp_add_to_cutpool_lpcut_in (CCtsp_lpcuts *pool, CCtsp_lpcut_in *cut),
+    CCtsp_display_cutpool (CCtsp_lpcuts *pool),
+    CCtsp_price_cuts (CCtsp_lpcuts *pool, int ncount, int ecount, int *elist,
+            double *x, double *cutval),
+    CCtsp_clique_to_array (CCtsp_lpclique *c, int **ar, int *count),
+    CCtsp_clique_delta (CCtsp_lpgraph *g, double *x, CCtsp_lpclique *c,
+            double *delta),
+    CCtsp_x_greedy_tour (CCdatagroup *dat, int ncount, int ecount, int *elist,
+            double *x, int *cyc, double *val),
+    CCtsp_x_greedy_tour_lk (CCdatagroup *dat, int ncount, int ecount,
+            int *elist, double *x, int *cyc, double *val);
+
+void
+    CCtsp_init_tsp_lp_struct (CCtsp_lp *lp),
+    CCtsp_free_tsp_lp_struct (CCtsp_lp **lp),
+    CCtsp_add_cuts_to_queue (CCtsp_lp *lp, CCtsp_lpcut_in **c),
+    CCtsp_delete_cut_from_cutlist (CCtsp_lpcuts *cuts, int ind),
+    CCtsp_init_lprow (CCtsp_lprow *cr),
+    CCtsp_free_lprow (CCtsp_lprow *cr),
+    CCtsp_unregister_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut *c),
+    CCtsp_free_cutpool (CCtsp_lpcuts **pool),
+    CCtsp_init_lpgraph_struct (CCtsp_lpgraph *g),
+    CCtsp_free_lpgraph (CCtsp_lpgraph *g),
+    CCtsp_free_lpcut_in (CCtsp_lpcut_in *c),
+    CCtsp_free_lpclique (CCtsp_lpclique *c),
+    CCtsp_free_bigdual (CCtsp_bigdual **d),
+    CCtsp_init_branchobj (CCtsp_branchobj *b),
+    CCtsp_free_branchobj (CCtsp_branchobj *b),
+    CCtsp_print_branchhistory (CCtsp_lp *lp),
+    CCtsp_init_tighten_info (CCtsp_tighten_info *stats),
+    CCtsp_print_tighten_info (CCtsp_tighten_info *stats),
+    CCtsp_mark_clique (CCtsp_lpclique *c, int *marks, int marker),
+    CCtsp_mark_clique_and_neighbors (CCtsp_lpgraph *g, CCtsp_lpclique *c,
+           int *marks, int marker),
+    CCtsp_mark_cut (CCtsp_lpcut_in *c, int *marks, int marker),
+    CCtsp_mark_cut_and_neighbors (CCtsp_lpgraph *g, CCtsp_lpcut_in *c,
+           int *marks, int marker),
+    CCtsp_mark_clique_and_neighbors_double (CCtsp_lpgraph *g, CCtsp_lpclique *c,
+           double *marks, double marker),
+    CCtsp_is_clique_marked (CCtsp_lpclique *c, int *marks, int marker,
+           int *yes_no),
+    CCtsp_clique_count (CCtsp_lpclique *c, int *count);
+
+
+double
+    CCtsp_cutprice (CCtsp_lpgraph *g, CCtsp_lpcut_in *c, double *x);
+
+#else
+
+int
+    CCtsp_cutting_loop (),
+    CCtsp_subtour_loop (),
+    CCtsp_pricing_loop (),
+    CCtsp_init_cutselect (),
+    CCtsp_call_x_heuristic (),
+    CCtsp_bb_cutting (),
+    CCtsp_init_lp (),
+    CCtsp_bb_init_lp (),
+    CCtsp_get_lp_result (),
+    CCtsp_process_cuts (),
+    CCtsp_add_cut_to_cutlist (),
+    CCtsp_add_cut (),
+    CCtsp_lpcut_in_nzlist (),
+    CCtsp_add_nzlist_to_lp (),
+    CCtsp_add_vars_to_lp (),
+    CCtsp_update_result (),
+    CCtsp_infeas_recover (),
+    CCtsp_test_cut_branch (),
+    CCtsp_register_cliques (),
+    CCtsp_addbad_variables (),
+    CCtsp_eliminate_variables (),
+    CCtsp_build_lpgraph (),
+    CCtsp_build_lpadj (),
+    CCtsp_add_multiple_rows (),
+    CCtsp_delete_cut (),
+    CCtsp_find_edge (),
+    CCtsp_find_branch (),
+    CCtsp_bb_find_branch (),
+    CCtsp_check_integral (),
+    CCtsp_find_branch_edge (),
+    CCtsp_find_branch_cliques (),
+    CCtsp_execute_branch (),
+    CCtsp_execute_unbranch (),
+    CCtsp_splitprob (),
+    CCtsp_bb_splitprob (),
+    CCtsp_dumptour (),
+    CCtsp_add_branchhistory_to_lp (),
+    CCtsp_easy_dfs_brancher (),
+    CCtsp_bfs_brancher (),
+    CCtsp_do_interactive_branch (),
+    CCtsp_inspect_full_edges (),
+    CCtsp_read_probfile (),
+    CCtsp_read_probfile_id (),
+    CCtsp_write_probfile_sav (),
+    CCtsp_write_probfile_id (),
+    CCtsp_dump_x (),
+    CCtsp_exact_price (),
+    CCtsp_edge_elimination (),
+    CCtsp_exact_dual (),
+    CCtsp_verify_infeasible_lp (),
+    CCtsp_verify_lp_prune (),
+    CCtsp_tighten_lpcut_in (),
+    CCtsp_tighten_lpcut (),
+    CCtsp_test_pure_comb (),
+    CCtsp_test_pseudocomb (),
+    CCtsp_test_teeth_disjoint (),
+    CCtsp_find_pure_handle (),
+    CCtsp_comb_to_double_decker (),
+    CCtsp_teething (),
+    CCtsp_init_cutpool (),
+    CCtsp_write_cutpool (),
+    CCtsp_search_cutpool (),
+    CCtsp_search_cutpool_cliques (),
+    CCtsp_branch_cutpool_cliques (),
+    CCtsp_add_to_cutpool (),
+    CCtsp_add_to_cutpool_lpcut_in (),
+    CCtsp_display_cutpool (),
+    CCtsp_price_cuts (),
+    CCtsp_clique_to_array (),
+    CCtsp_clique_delta (),
+    CCtsp_x_greedy_tour (),
+    CCtsp_x_greedy_tour_lk ();
+
+void
+    CCtsp_init_tsp_lp_struct (),
+    CCtsp_free_tsp_lp_struct (),
+    CCtsp_add_cuts_to_queue (),
+    CCtsp_delete_cut_from_cutlist (),
+    CCtsp_init_lprow (),
+    CCtsp_free_lprow (),
+    CCtsp_unregister_cliques (),
+    CCtsp_free_cutpool (),
+    CCtsp_init_lpgraph_struct (),
+    CCtsp_free_lpgraph (),
+    CCtsp_free_lpcut_in (),
+    CCtsp_free_lpclique (),
+    CCtsp_free_bigdual (),
+    CCtsp_init_branchobj (),
+    CCtsp_free_branchobj (),
+    CCtsp_print_branchhistory (),
+    CCtsp_init_tighten_info (),
+    CCtsp_print_tighten_info (),
+    CCtsp_mark_clique (),
+    CCtsp_mark_clique_and_neighbors (),
+    CCtsp_mark_cut (),
+    CCtsp_mark_cut_and_neighbors (),
+    CCtsp_mark_clique_and_neighbors_double (),
+    CCtsp_is_clique_marked (),
+    CCtsp_clique_count ();
+
+
+double
+    CCtsp_cutprice ();
+
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                             cliqhash.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_init_cliquehash (CCtsp_lpcuts *cuts, int size),
+    CCtsp_register_clique (CCtsp_lpcuts *cuts, CCtsp_lpclique *c);
+
+void
+    CCtsp_free_cliquehash (CCtsp_lpcuts *cuts),
+    CCtsp_unregister_clique (CCtsp_lpcuts *cuts, int c);
+
+#else
+
+int
+    CCtsp_init_cliquehash (),
+    CCtsp_register_clique ();
+
+void
+    CCtsp_free_cliquehash (),
+    CCtsp_unregister_clique ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             cutcall.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct cutinfo {
+    CC_SRKexpinfo expand;
+    CCtsp_lpcut_in **clist;
+    CCtsp_lpcut_in *current;
+    int *cutcount;
+} cutinfo;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_connect_cuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+            int ecount, int *elist, double *x),
+    CCtsp_segment_cuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+            int ecount, int *elist, double *x),
+    CCtsp_exact_subtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+            int ecount, int *elist, double *x),
+    CCtsp_tighten_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+            CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+            int *elist, double *x, double testtol, int maxcuts),
+    CCtsp_double_decker_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+            CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+            int *elist, double *x, double testtol, int maxcuts),
+    CCtsp_teething_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+            CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+            int *elist, double *x, double testtol, int maxcuts),
+    CCtsp_copy_lpcut_in (CCtsp_lpcut_in *c, CCtsp_lpcut_in *new),
+    CCtsp_segment_to_subtour (CCtsp_lpcut_in **cut, int a, int b),
+    CCtsp_array_to_subtour (CCtsp_lpcut_in **cut, int *ar, int acount),
+    CCtsp_array_to_lpclique (int *ar, int acount, CCtsp_lpclique *cliq),
+    CCtsp_seglist_to_lpclique (int nseg, int *list, CCtsp_lpclique *cliq),
+    CCtsp_add_node_to_lpclique (CCtsp_lpclique *cin, CCtsp_lpclique *cout,
+            int n),
+    CCtsp_delete_node_from_lpclique (CCtsp_lpclique *cin,
+            CCtsp_lpclique *cout, int n),
+    CCtsp_lpcut_to_lpcut_in (CCtsp_lpcuts *cuts, CCtsp_lpcut *c,
+            CCtsp_lpcut_in *new),
+    CCtsp_copy_lpclique (CCtsp_lpclique *c, CCtsp_lpclique *new),
+    CCtsp_file_cuts (char *cutfile, CCtsp_lpcut_in **cuts, int *cutcount,
+            int ncount, int *tour),
+    CCtsp_file_cuts_write (char *cutfile, CCtsp_lpcuts *cuts, int *tour),
+    CCtsp_buildcut_begin (cutinfo *cuts, int init_cliquecount),
+    CCtsp_buildcut_addclique (cutinfo *cuts, int *arr, int size, int handle);
+
+void
+    CCtsp_init_lpcut_in (CCtsp_lpcut_in *c),
+    CCtsp_init_lpclique (CCtsp_lpclique *c),
+    CCtsp_print_lpcut_in (CCtsp_lpcut_in *c),
+    CCtsp_print_lpclique (CCtsp_lpclique *c),
+    CCtsp_lpclique_compare (CCtsp_lpclique *a, CCtsp_lpclique *b, int *diff),
+    CCtsp_buildcut_abort (cutinfo *cuts),
+    CCtsp_buildcut_finish (cutinfo *cuts, int rhs);
+
+#else
+
+int
+    CCtsp_connect_cuts (),
+    CCtsp_segment_cuts (),
+    CCtsp_exact_subtours (),
+    CCtsp_tighten_lp (),
+    CCtsp_double_decker_lp (),
+    CCtsp_teething_lp (),
+    CCtsp_copy_lpcut_in (),
+    CCtsp_segment_to_subtour (),
+    CCtsp_array_to_subtour (),
+    CCtsp_array_to_lpclique (),
+    CCtsp_seglist_to_lpclique (),
+    CCtsp_add_node_to_lpclique (),
+    CCtsp_delete_node_from_lpclique (),
+    CCtsp_lpcut_to_lpcut_in (),
+    CCtsp_copy_lpclique (),
+    CCtsp_file_cuts (),
+    CCtsp_file_cuts_write (),
+    CCtsp_buildcut_begin (),
+    CCtsp_buildcut_addclique ();
+
+void
+    CCtsp_init_lpcut_in (),
+    CCtsp_init_lpclique (),
+    CCtsp_print_lpcut_in (),
+    CCtsp_print_lpclique (),
+    CCtsp_lpclique_compare (),
+    CCtsp_buildcut_abort (),
+    CCtsp_buildcut_finish ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edgemap.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCtsp_edgeinf {
+    int ends[2];
+    int val;
+    struct CCtsp_edgeinf *next;
+} CCtsp_edgeinf;
+
+typedef struct CCtsp_edgehash {
+    struct CCtsp_edgeinf **table;
+    unsigned int size;
+    unsigned int mult;
+} CCtsp_edgehash;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_edgehash_init (CCtsp_edgehash *h, int size),
+    CCtsp_edgehash_add (CCtsp_edgehash *h, int end1, int end2, int val),
+    CCtsp_edgehash_del (CCtsp_edgehash *h, int end1, int end2),
+    CCtsp_edgehash_find (CCtsp_edgehash *h, int end1, int end2);
+
+void
+    CCtsp_edgehash_delall (CCtsp_edgehash *h),
+    CCtsp_edgehash_free (CCtsp_edgehash *h);
+
+#else
+
+int
+    CCtsp_edgehash_init (),
+    CCtsp_edgehash_add (),
+    CCtsp_edgehash_del (),
+    CCtsp_edgehash_find ();
+
+void
+    CCtsp_edgehash_delall (),
+    CCtsp_edgehash_free ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             generate.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define CCtsp_PRICE_COMPLETE_GRAPH -1
+#define CCtsp_GEN_PRICE_EPSILON 0.0001 /* 0.0000001 */
+#define CCtsp_GEN_USE_ADJ 50           /* Cutoff for using explicit adj list */
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCtsp_free_edgegenerator (CCtsp_edgegenerator *eg);
+
+int
+    CCtsp_init_edgegenerator (CCtsp_edgegenerator *eg, int ncount,
+            CCdatagroup *dg, CCtsp_genadj *adj, int nneighbors),
+    CCtsp_reset_edgegenerator (CCtsp_edgegenerator *eg, double *node_piest),
+    CCtsp_generate_edges (CCtsp_edgegenerator *eg, int nwant, int *pngot,
+            int *elist, int *elen, int *finished),
+    CCtsp_edgelist_to_genadj (int ncount, int ecount, int *elist, int *elen,
+            CCtsp_genadj **adj, CCtsp_genadjobj **adjobjspace);
+
+#else
+
+void
+    CCtsp_free_edgegenerator ();
+
+int
+    CCtsp_init_edgegenerator (),
+    CCtsp_reset_edgegenerator (),
+    CCtsp_generate_edges (),
+    CCtsp_edgelist_to_genadj ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             prob_io.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#define CCtsp_PROB_IO_VERSION  1
+#define CCtsp_PROB_FILE_NAME_LEN 128
+
+#define CCtsp_PROB_IO_CUTS_VERSION_BASE  -1000
+#define CCtsp_PROB_IO_CUTS_VERSION       -1001   /* Should be <= BASE (-1000) */
+
+typedef struct CCtsp_PROB_FILE {
+    CC_SFILE *f;
+    char name[CCtsp_PROB_FILE_NAME_LEN];
+    int id;
+    int parent;
+    double ub;
+    double lb;
+    CCbigguy exactlb;
+    int nnodes;
+    int child0;
+    int child1;
+    int real;       /* Set to 1 when we know this is a real child */
+    int processed;
+    int infeasible;
+    struct {
+        int dat;
+        int edge;
+        int fulladj;
+        int cut;
+        int tour;
+        int basis;
+        int norms;
+        int fix;
+        int exactdual;
+        int history;
+    } offsets;
+} CCtsp_PROB_FILE;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+CCtsp_PROB_FILE
+    *CCtsp_prob_read (char *f, int n),
+    *CCtsp_prob_read_name (char *f),
+    *CCtsp_prob_write (char *f, int n),
+    *CCtsp_prob_write_name (char *fname, char *pname);
+
+int
+    CCtsp_prob_file_delete (char *f, int n),
+    CCtsp_prob_getname (CCtsp_PROB_FILE *p, char *name),
+    CCtsp_prob_getid (CCtsp_PROB_FILE *p, int *id),
+    CCtsp_prob_getparent (CCtsp_PROB_FILE *p, int *parent),
+    CCtsp_prob_getub (CCtsp_PROB_FILE *p, double *ub),
+    CCtsp_prob_getlb (CCtsp_PROB_FILE *p, double *lb),
+    CCtsp_prob_getexactlb (CCtsp_PROB_FILE *p, CCbigguy *lb),
+    CCtsp_prob_getnnodes (CCtsp_PROB_FILE *p, int *nnodes),
+    CCtsp_prob_getchildren (CCtsp_PROB_FILE *p, int *child0, int *child1),
+    CCtsp_prob_getreal (CCtsp_PROB_FILE *p, int *real),
+    CCtsp_prob_getprocessed (CCtsp_PROB_FILE *p, int *processed),
+    CCtsp_prob_getinfeasible (CCtsp_PROB_FILE *p, int *infeasible),
+    CCtsp_prob_gettour (CCtsp_PROB_FILE *p, int **tour),
+    CCtsp_prob_getedges (CCtsp_PROB_FILE *p, int *nedges, int **elist,
+        int **elen),
+    CCtsp_prob_getcuts (CCtsp_PROB_FILE *p, CC_SFILE *s, CCtsp_lpcuts *cuts),
+    CCtsp_prob_getbasis (CCtsp_PROB_FILE *p, int *ccount, int *rcount,
+        int **cstat, int **rstat),
+    CCtsp_prob_getnorms (CCtsp_PROB_FILE *p, int *rcount, double **dnorm),
+    CCtsp_prob_getfulladj (CCtsp_PROB_FILE *p, int ncount, int *fullcount,
+        CCtsp_genadj **adj, CCtsp_genadjobj **adjspace),
+    CCtsp_prob_getfixed (CCtsp_PROB_FILE *p, int *ecount, int **elist),
+    CCtsp_prob_getexactdual (CCtsp_PROB_FILE *p, int ncount,
+        CCtsp_bigdual **d),
+    CCtsp_prob_gethistory (CCtsp_PROB_FILE *p, int *depth,
+        CCtsp_branchobj **history),
+    CCtsp_prob_rclose (CCtsp_PROB_FILE *p),
+
+    CCtsp_prob_putname (CCtsp_PROB_FILE *p, char *name),
+    CCtsp_prob_putid (CCtsp_PROB_FILE *p, int id),
+    CCtsp_prob_putparent (CCtsp_PROB_FILE *p, int parent),
+    CCtsp_prob_putub (CCtsp_PROB_FILE *p, double ub),
+    CCtsp_prob_putlb (CCtsp_PROB_FILE *p, double lb),
+    CCtsp_prob_putexactlb (CCtsp_PROB_FILE *p, CCbigguy lb),
+    CCtsp_prob_putnnodes (CCtsp_PROB_FILE *p, int nnodes),
+    CCtsp_prob_putchildren (CCtsp_PROB_FILE *p, int child0, int child1),
+    CCtsp_prob_putreal (CCtsp_PROB_FILE *p, int real),
+    CCtsp_prob_putprocessed (CCtsp_PROB_FILE *p, int processed),
+    CCtsp_prob_putinfeasible (CCtsp_PROB_FILE *p, int infeasible),
+    CCtsp_prob_puttour (CCtsp_PROB_FILE *p, int *tour),
+    CCtsp_prob_putedges (CCtsp_PROB_FILE *p, int nedges, int *elist, int *elen),
+    CCtsp_prob_putcuts (CCtsp_PROB_FILE *p, CC_SFILE *s, CCtsp_lpcuts *cuts),
+    CCtsp_prob_putbasis (CCtsp_PROB_FILE *p, int ccount, int rcount, int *cstat,
+        int *rstat),
+    CCtsp_prob_putnorms (CCtsp_PROB_FILE *p, int rcount, double *dnorm),
+    CCtsp_prob_putfulladj (CCtsp_PROB_FILE *p, int ncount, int fullcount,
+        CCtsp_genadj *adj),
+    CCtsp_prob_putfixed (CCtsp_PROB_FILE *p, int ecount, int *elist),
+    CCtsp_prob_putexactdual (CCtsp_PROB_FILE *p, CCtsp_bigdual *d, int ncount),
+    CCtsp_prob_puthistory (CCtsp_PROB_FILE *p, int depth,
+        CCtsp_branchobj *history),
+    CCtsp_prob_wclose (CCtsp_PROB_FILE *p);
+
+#else
+
+CCtsp_PROB_FILE
+    *CCtsp_prob_read (),
+    *CCtsp_prob_read_name (),
+    *CCtsp_prob_write (),
+    *CCtsp_prob_write_name ();
+
+int
+    CCtsp_prob_file_delete (),
+    CCtsp_prob_getname (),
+    CCtsp_prob_getid (),
+    CCtsp_prob_getparent (),
+    CCtsp_prob_getub (),
+    CCtsp_prob_getlb (),
+    CCtsp_prob_getexactlb (),
+    CCtsp_prob_getnnodes (),
+    CCtsp_prob_getchildren (),
+    CCtsp_prob_getreal (),
+    CCtsp_prob_getprocessed (),
+    CCtsp_prob_getinfeasible (),
+    CCtsp_prob_gettour (),
+    CCtsp_prob_getedges (),
+    CCtsp_prob_getcuts (),
+    CCtsp_prob_getbasis (),
+    CCtsp_prob_getnorms (),
+    CCtsp_prob_getfulladj (),
+    CCtsp_prob_getfixed (),
+    CCtsp_prob_getexactdual (),
+    CCtsp_prob_gethistory (),
+    CCtsp_prob_rclose (),
+
+    CCtsp_prob_putname (),
+    CCtsp_prob_putid (),
+    CCtsp_prob_putparent (),
+    CCtsp_prob_putub (),
+    CCtsp_prob_putlb (),
+    CCtsp_prob_putexactlb (),
+    CCtsp_prob_putnnodes (),
+    CCtsp_prob_putchildren (),
+    CCtsp_prob_putreal (),
+    CCtsp_prob_putprocessed (),
+    CCtsp_prob_putinfeasible (),
+    CCtsp_prob_puttour (),
+    CCtsp_prob_putedges (),
+    CCtsp_prob_putcuts (),
+    CCtsp_prob_putbasis (),
+    CCtsp_prob_putnorms (),
+    CCtsp_prob_putfulladj (),
+    CCtsp_prob_putfixed (),
+    CCtsp_prob_putexactdual (),
+    CCtsp_prob_puthistory (),
+    CCtsp_prob_wclose ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             qsparse.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCtsp_qsparsegroup {
+    CCdheap *add_queue;   /* An empty heap will be maintained */
+    CCdheap *sub_queue;   /* An empty heap will be maintained */
+    int *count_m1;        /* The array will be maintained at 0 */
+    int *count_non0;      /* The array will be maintained at 0 */
+    int *count_1;         /* The array will be maintained at 0 */
+    int *on_add_queue;    /* The array will be maintained at 0 */
+    int *on_sub_queue;    /* The array will be maintained at 0 */
+    int *mults;           /* The array will be maintained at 0 */
+} CCtsp_qsparsegroup;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCtsp_free_qsparsify (CCtsp_qsparsegroup **pqs);
+int
+    CCtsp_qsparsify (CCtsp_qsparsegroup **pqs, struct CCtsp_lpgraph *g,
+            int *pnzlist, int *scount, struct CCtsp_sparser **slist,
+            int *savedcount);
+#else
+
+void
+    CCtsp_free_qsparsify ();
+int
+    CCtsp_qsparsify ();
+
+#endif
+
+#endif  /* __TSP_H */
diff --git a/contrib/blossom/concorde97/INCLUDE/util.h b/contrib/blossom/concorde97/INCLUDE/util.h
new file mode 100644
index 0000000000000000000000000000000000000000..1421f5e776da9da62a6fb54d9f17f5a2a0c44bc9
--- /dev/null
+++ b/contrib/blossom/concorde97/INCLUDE/util.h
@@ -0,0 +1,935 @@
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN UTIL                       */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+
+#ifndef __UTIL_H
+#define __UTIL_H
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             allocrus.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+/***************************************************************************/
+/*                                                                         */
+/*                   MEMORY ALLOCATION MACROS                              */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 24, 1995 (cofeb24)                                      */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED MACROS:                                                       */
+/*    CC_SAFE_MALLOC (nnum,type)                                           */
+/*         int nnum (the number of objects to be malloced)                 */
+/*         data type (the sort of objects to be malloced)                  */
+/*         RETURNS a pointer to the allocated space. If out of memory,     */
+/*                 it prints an error message and returns NULL.            */
+/*                                                                         */
+/*    CC_FREE (object,type)                                                */
+/*         type *object (pointer to previously allocated space)            */
+/*         data type (the sort of object)                                  */
+/*         ACTION: frees the memory and sets the object to NULL.           */
+/*                                                                         */
+/*    CC_IFFREE (object,type)                                              */
+/*         type *object (pointer to previously allocated space)            */
+/*         data type (the sort of object)                                  */
+/*         ACTION: if *object is not NULL, frees the memory and sets       */
+/*                 the object to NULL.                                     */
+/*                                                                         */
+/*    CC_PTR_ALLOC_ROUTINE (type, functionname, chunklist, freelist)       */
+/*         data type (the sort of objects)                                 */
+/*         string functionname (the generated function)                    */
+/*         CCbigchunkptr *chunklist (used to accumulate bigchunks)         */
+/*         type *freelist (used for the linked list of objects)            */
+/*         ACTION: Generates a function ("functionname") that returns      */
+/*                 (type *) objects, keeping the free ones on freelist     */
+/*                 and getting its space from calls to bigchunkalloc.      */
+/*                                                                         */
+/*    CC_PTR_FREE_ROUTINE (type, functionname, freelist)                   */
+/*         Parameters as above.                                            */
+/*         ACTION: Generates a function that adds an object to the         */
+/*                 freelist.                                               */
+/*                                                                         */
+/*    CC_PTR_FREE_LIST_ROUTINE (type, functionname, freefunction)          */
+/*         Parameters defined as above, with freefunction the function     */
+/*         generated by PTR_FREE_ROUTINE.                                  */
+/*         ACTION: Generates a function to free a linked list of           */
+/*                 objects using calls to freefunction.                    */
+/*                                                                         */
+/*    CC_PTR_FREE_WORLD_ROUTINE( type, functionname, chunklist, freelist)  */
+/*         Parameters defined as above.                                    */
+/*         ACTION: Generates a function that returns all of the            */
+/*                 memory used in the PTR_ALLOC_ROUTINE allocations        */
+/*                 back to the global supply of CCbigchunkptrs.            */
+/*                                                                         */
+/*    CC_PTR_LEAKS_ROUTINE (type, name, chunklist, freelist, field,        */
+/*            fieldtype)                                                   */
+/*          As above, with "field" the name of a "fieldtype" field in the  */
+/*          object type that can be set to 0 or to 1.                      */
+/*          ACTION: Generates a function that checks to see that we have   */
+/*                  not leaked any of the objects.                         */
+/*                                                                         */
+/*    CC_PTR_STATUS_ROUTINE (type, name, chunklist, freelist)              */
+/*          ACTION: Like LEAKS, but does not check for duplicates (and so  */
+/*                  does not corrupt the objects).                         */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*     These routines use the functions in allocrus.c.  The PTR macros     */
+/*  The PTR macros generate the functions for allocating objects for       */
+/*  linked lists. They get their raw memory from the bigchunk supply, so   */
+/*  so foo_free_world (geneated by PTR_FREE_WORLD_ROUTINE) should be       */
+/*  called for each type of linked object "foo" when closing down the      */
+/*  local memory.                                                          */
+/*     To use these functions, put the macros near the top of the file     */
+/*  before any calls to the functions (since the macros also write the     */
+/*  function prototypes). If you use PTR_FREE_LIST_ROUTINE for foo, you    */
+/*  must also use PTR_FREE_ROUTINE, and PTR_FREE_LIST_ROUTINE must be      */
+/*  listed after CC_PTR_FREE_ROUTINE (to get the prototype).               */
+/*                                                                         */
+/***************************************************************************/
+
+
+#define CC_SAFE_MALLOC(nnum,type)                                          \
+    (type *) CCutil_allocrus (((unsigned int) (nnum)) * sizeof (type))
+
+#define CC_FREE(object,type) {                                             \
+    CCutil_freerus ((void *) (object));                                    \
+    object = (type *) NULL;                                                \
+}
+
+#define CC_IFFREE(object,type) {                                           \
+    if ((object)) CC_FREE ((object),type);                                 \
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_ALLOC_ROUTINE(type, functionname)                    \
+static type * functionname (void);                                         \
+static type * functionname (void)
+#else
+#define CC_HEADER_PTR_ALLOC_ROUTINE(type, functionname)                    \
+static type * functionname ();                                             \
+static type * functionname ()
+#endif
+
+#define CC_PTR_ALLOC_ROUTINE(type, functionname, chunklist, freelist)      \
+static  type * freelist = ( type * ) NULL;                                 \
+static  CCbigchunkptr * chunklist = ( CCbigchunkptr * ) NULL;              \
+ CC_HEADER_PTR_ALLOC_ROUTINE (type, functionname)                          \
+{                                                                          \
+    type *p;                                                               \
+                                                                           \
+    if (! freelist ) {                                                     \
+        int count = CC_BIGCHUNK / sizeof ( type );                         \
+        CCbigchunkptr *bp;                                                 \
+                                                                           \
+        bp = CCutil_bigchunkalloc ();                                      \
+        if (!bp) {                                                         \
+            fprintf (stderr, "ptr alloc failed\n");                        \
+            return ( type * ) NULL;                                        \
+        }                                                                  \
+        freelist = ( type * ) bp->this;                                    \
+        bp->next = chunklist ;                                             \
+        chunklist = bp;                                                    \
+                                                                           \
+        for (p = freelist + count - 2; p >= freelist ; p--)                \
+            p->next = p + 1;                                               \
+        freelist [count - 1].next = ( type * ) NULL;                       \
+    }                                                                      \
+    p = freelist ;                                                         \
+    freelist = p->next;                                                    \
+                                                                           \
+    return p;                                                              \
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_FREE_ROUTINE(type, functionname)                     \
+static void functionname ( type *p );                                      \
+static void functionname ( type *p )
+#else
+#define CC_HEADER_PTR_FREE_ROUTINE(type, functionname)                     \
+static void functionname ();                                               \
+static void functionname ( p )                                             \
+type *p;
+#endif
+
+#define CC_PTR_FREE_ROUTINE(type, functionname, freelist)                  \
+ CC_HEADER_PTR_FREE_ROUTINE(type, functionname)                            \
+{                                                                          \
+    p->next = freelist ;                                                   \
+    freelist = p;                                                          \
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_FREE_LIST_ROUTINE(type, functionname)                \
+static void functionname ( type *p );                                      \
+static void functionname ( type *p )
+#else
+#define CC_HEADER_PTR_FREE_LIST_ROUTINE(type, functionname)                \
+static void functionname ();                                               \
+static void functionname ( p )                                             \
+type *p;
+#endif
+
+#define CC_PTR_FREE_LIST_ROUTINE(type, functionname, freefunction)         \
+ CC_HEADER_PTR_FREE_LIST_ROUTINE (type, functionname)                      \
+{                                                                          \
+    type *next;                                                            \
+                                                                           \
+    while (p) {                                                            \
+        next = p->next;                                                    \
+        freefunction (p);                                                  \
+        p = next;                                                          \
+    }                                                                      \
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_FREE_WORLD_ROUTINE(functionname)                     \
+static void functionname (void);                                           \
+static void functionname (void)
+#else
+#define CC_HEADER_PTR_FREE_WORLD_ROUTINE(functionname)                     \
+static void functionname ();                                               \
+static void functionname ()
+#endif
+
+#define CC_PTR_FREE_WORLD_ROUTINE(type, functionname, chunklist, freelist) \
+ CC_HEADER_PTR_FREE_WORLD_ROUTINE(functionname)                            \
+{                                                                          \
+    CCbigchunkptr *bp, *bpnext;                                            \
+                                                                           \
+    for (bp = chunklist ; bp; bp = bpnext) {                               \
+        bpnext = bp->next;                                                 \
+        CCutil_bigchunkfree (bp);                                          \
+    }                                                                      \
+    chunklist = (CCbigchunkptr *) NULL;                                    \
+    freelist = (type *) NULL;                                              \
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_LEAKS_ROUTINE(functionname)                          \
+static int functionname (int *total, int *onlist);                         \
+static int functionname (int *total, int *onlist)
+#else
+#define CC_HEADER_PTR_LEAKS_ROUTINE(functionname)                          \
+static int functionname ();                                                \
+static int functionname (total, onlist)                                    \
+int *total, *onlist;
+#endif
+
+#define CC_PTR_LEAKS_ROUTINE(type,name,chunklist,freelist,field,fieldtype) \
+ CC_HEADER_PTR_LEAKS_ROUTINE(name)                                         \
+{                                                                          \
+    int count = CC_BIGCHUNK / sizeof ( type );                             \
+    int duplicates = 0;                                                    \
+    type * p;                                                              \
+    CCbigchunkptr *bp;                                                     \
+                                                                           \
+    *total = 0;                                                            \
+    *onlist = 0;                                                           \
+                                                                           \
+    for (bp = chunklist ; bp; bp = bp->next)                               \
+        (*total) += count;                                                 \
+                                                                           \
+    for (p = freelist ; p; p = p->next) {                                  \
+        (*onlist)++;                                                       \
+        p-> field = ( fieldtype ) 0;                                       \
+    }                                                                      \
+    for (p = freelist ; p; p = p->next) {                                  \
+        if (p-> field == ( fieldtype ) 1)                                  \
+            duplicates++;                                                  \
+        else                                                               \
+            p-> field = ( fieldtype ) 1;                                   \
+    }                                                                      \
+    if (duplicates) {                                                      \
+        fprintf (stderr, "WARNING: %d duplicates on ptr free list \n",     \
+                 duplicates);                                              \
+    }                                                                      \
+    return *total - *onlist;                                               \
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_STATUS_ROUTINE(functionname)                         \
+static int functionname (int *total, int *onlist);                         \
+static int functionname (int *total, int *onlist)
+#else
+#define CC_HEADER_PTR_STATUS_ROUTINE(functionname)                         \
+static int functionname ();                                                \
+static int functionname (total, onlist)                                    \
+int *total, *onlist;
+#endif
+
+#define CC_PTR_STATUS_ROUTINE(type, name, chunklist, freelist)             \
+ CC_HEADER_PTR_STATUS_ROUTINE(name)                                        \
+{                                                                          \
+    int count = CC_BIGCHUNK / sizeof ( type );                             \
+    type * p;                                                              \
+    CCbigchunkptr *bp;                                                     \
+                                                                           \
+    *total = 0;                                                            \
+    *onlist = 0;                                                           \
+                                                                           \
+    for (bp = chunklist ; bp; bp = bp->next)                               \
+        (*total) += count;                                                 \
+                                                                           \
+    for (p = freelist ; p; p = p->next)                                    \
+        (*onlist)++;                                                       \
+    return *total - *onlist;                                               \
+}
+
+
+#define CC_BIGCHUNK ((int) ((1<<16)-16))
+
+typedef struct CCbigchunkptr {
+    void                 *this;
+    struct CCbigchunkptr *next;
+} CCbigchunkptr;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+   *CCutil_allocrus (unsigned int size),
+   *CCutil_reallocrus (void *ptr, unsigned int size),
+    CCutil_freerus (void *p),
+    CCutil_bigchunkquery (int *total, int *reserve),
+    CCutil_bigchunkfree (CCbigchunkptr *bp);
+
+int
+    CCutil_reallocrus_scale (void **pptr, int *pnnum, int count, double scale,
+                      unsigned int size),
+    CCutil_reallocrus_count (void **pptr, int count, unsigned int size),
+    CCutil_bigchunk_free_world (void);
+
+CCbigchunkptr
+   *CCutil_bigchunkalloc (void);
+
+#else
+
+void
+   *CCutil_allocrus (),
+   *CCutil_reallocrus (),
+    CCutil_freerus (),
+    CCutil_bigchunkquery (),
+    CCutil_bigchunkfree ();
+
+int
+    CCutil_reallocrus_scale (),
+    CCutil_reallocrus_count (),
+    CCutil_bigchunk_free_world ();
+
+CCbigchunkptr
+    *CCutil_bigchunkalloc ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             bgetopt.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_bix_getopt (int, char **, char *);
+
+#else
+
+int
+    CCutil_bix_getopt ();
+
+#endif
+
+#define CC_BIX_GETOPT_UNKNOWN -3038
+
+extern int CCutil_bix_optind;
+extern char *CCutil_bix_optarg;
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             dheaps_i.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCdheap {
+    double  *key;
+    int     *entry;
+    int     *loc;
+    int     total_space;
+    int     size;
+} CCdheap;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_dheap_free (CCdheap *h),
+    CCutil_dheap_insert (CCdheap *h, int i),
+    CCutil_dheap_delete (CCdheap *h, int i),
+    CCutil_dheap_changekey (CCdheap *h, int i, double newkey);
+int
+    CCutil_dheap_init (CCdheap *h, int k),
+    CCutil_dheap_resize (CCdheap *h, int newsize),
+    CCutil_dheap_findmin (CCdheap *h),
+    CCutil_dheap_deletemin (CCdheap *h);
+
+#else
+
+void
+    CCutil_dheap_free (),
+    CCutil_dheap_insert (),
+    CCutil_dheap_delete (),
+    CCutil_dheap_changekey ();
+int
+    CCutil_dheap_init (),
+    CCutil_dheap_resize (),
+    CCutil_dheap_findmin (),
+    CCutil_dheap_deletemin ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edg2cyc.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_edge_to_cycle (int ncount, int *elist, int *cyc);
+
+#else
+
+int
+    CCutil_edge_to_cycle ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edgelen.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCdatagroup {
+    double  *x;
+    double  *y;
+    double  *z;
+    int    **adj;
+    int      norm;
+} CCdatagroup;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+extern int
+  (*CCutil_dat_edgelen) (int i, int j, CCdatagroup *dat);
+int
+    CCutil_init_dat_edgelen (CCdatagroup *dat),
+    CCutil_max_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_euclid_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_ibm_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_euclid_ceiling_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_euclid3d_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_geographic_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_att_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_dsjrand_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_crystal_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_matrix_edgelen (int i, int j, CCdatagroup *dat);
+void
+    CCutil_dsjrand_init (int maxdist, int seed),
+    CCutil_freedatagroup (int ncount, CCdatagroup *dat);
+
+#else
+
+extern int
+  (*CCutil_dat_edgelen) ();
+int
+    CCutil_init_dat_edgelen (),
+    CCutil_max_edgelen (),
+    CCutil_euclid_edgelen (),
+    CCutil_ibm_edgelen (),
+    CCutil_euclid_ceiling_edgelen (),
+    CCutil_euclid3d_edgelen (),
+    CCutil_geographic_edgelen (),
+    CCutil_att_edgelen (),
+    CCutil_dsjrand_edgelen (),
+    CCutil_crystal_edgelen (),
+    CCutil_matrix_edgelen ();
+void
+    CCutil_dsjrand_init (),
+    CCutil_freedatagroup ();
+
+#endif
+
+
+#define CC_KD_NORM_TYPE    128            /* Kdtrees work      */
+#define CC_X_NORM_TYPE     256            /* Old nearest works */
+#define CC_JUNK_NORM_TYPE  512            /* Nothing works     */
+
+#define CC_D2_NORM_SIZE      1024         /* x,y coordinates   */
+#define CC_D3_NORM_SIZE      2048         /* x,y,z coordinates */
+#define CC_MATRIX_NORM_SIZE  4096         /* adj matrix        */
+
+#define CC_NORM_BITS      (CC_KD_NORM_TYPE | CC_X_NORM_TYPE | CC_JUNK_NORM_TYPE)
+#define CC_NORM_SIZE_BITS (CC_D2_NORM_SIZE | CC_D3_NORM_SIZE | CC_MATRIX_NORM_SIZE)
+
+#define CC_MAXNORM        (0 |   CC_KD_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_EUCLIDEAN_CEIL (1 |   CC_KD_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_EUCLIDEAN      (2 |   CC_KD_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_EUCLIDEAN_3D   (3 |    CC_X_NORM_TYPE |     CC_D3_NORM_SIZE)
+#define CC_IBM            (4 | CC_JUNK_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_ATT            (5 |    CC_X_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_GEOGRAPHIC     (6 |    CC_X_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_MATRIXNORM     (7 | CC_JUNK_NORM_TYPE | CC_MATRIX_NORM_SIZE)
+#define CC_DSJRANDNORM    (8 | CC_JUNK_NORM_TYPE)
+#define CC_CRYSTAL        (9 |    CC_X_NORM_TYPE |     CC_D3_NORM_SIZE)
+
+#define CC_GEOGRAPHIC_SCALE (6378.388 * 3.14 / 180.0) /*    see edgelen.c   */
+#define CC_ATT_SCALE (.31622)                         /*    sqrt(1/10)      */
+
+/* For X-NORMS, scales are such that |x[i] - x[j]| * scale <= edgelen(i,j). */
+/* Ggeographic is slightly off, since the fractional part of x[i] is really */
+/* really minutes, not fractional degrees.                                  */
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             fastread.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_readint (FILE *);
+
+#else
+
+int
+    CCutil_readint ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             genhash.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCgenhash {
+    int                     nelem;
+    int                     maxelem;
+    int                     size;
+#ifdef CC_PROTOTYPE_ANSI
+    int                   (*hcmp) (void *key1, void *key2, void *u_data);
+    unsigned int          (*hfunc) (void *key, void *u_data);
+#else
+    int                   (*hcmp) ();
+    unsigned int          (*hfunc) ();
+#endif
+    void                   *u_data;
+    double                  maxdensity;
+    double                  lowdensity;
+    struct CCgenhash_elem **table;
+} CCgenhash;
+
+typedef struct CCgenhash_iter {
+    int                    i;
+    struct CCgenhash_elem *next;
+} CCgenhash_iter;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_genhash_init (CCgenhash *h, int size,
+            int (*hcmp) (void *key1, void *key2, void *u_data),
+            unsigned int (*hfunc) (void *key, void *u_data),
+            void *u_data, double maxdensity, double lowdensity),
+    CCutil_genhash_insert (CCgenhash *h, void *key, void *data),
+    CCutil_genhash_insert_h (CCgenhash *h, unsigned int hashval, void *key,
+            void *data),
+    CCutil_genhash_replace (CCgenhash *h, void *key, void *data),
+    CCutil_genhash_replace_h (CCgenhash *h, unsigned int hashval, void *key,
+                       void *data),
+    CCutil_genhash_delete (CCgenhash *h, void *key),
+    CCutil_genhash_delete_h (CCgenhash *h, unsigned int hashval, void *key);
+
+unsigned int
+    CCutil_genhash_hash (CCgenhash *h, void *key);
+
+void
+   *CCutil_genhash_lookup (CCgenhash *h, void *key),
+   *CCutil_genhash_lookup_h (CCgenhash *h, unsigned int hashval, void *key),
+   *CCutil_genhash_next (CCgenhash *h, CCgenhash_iter *iter, void **key,
+            int *keysize);
+
+void
+    CCutil_genhash_u_data (CCgenhash *h, void *u_data),
+    CCutil_genhash_free (CCgenhash *h, void (*freefunc)(void *key, void *data,
+            void *u_data)),
+    CCutil_genhash_start (CCgenhash *h, CCgenhash_iter *iter);
+
+#else
+
+int
+    CCutil_genhash_init (),
+    CCutil_genhash_insert (),
+    CCutil_genhash_insert_h (),
+    CCutil_genhash_replace (),
+    CCutil_genhash_replace_h (),
+    CCutil_genhash_delete (),
+    CCutil_genhash_delete_h ();
+
+unsigned int
+    CCutil_genhash_hash ();
+
+void
+   *CCutil_genhash_lookup (),
+   *CCutil_genhash_lookup_h (),
+   *CCutil_genhash_next ();
+
+void
+    CCutil_genhash_u_data (),
+    CCutil_genhash_free (),
+    CCutil_genhash_start ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             getdata.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#define CC_MASTER_NO_DAT  100
+#define CC_MASTER_DAT     101
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_getdata (char *datname, int binary_in, int innorm, int *ncount,
+            CCdatagroup *dat),
+    CCutil_writemaster (char *mastername, int ncount, CCdatagroup *dat,
+            int *perm),
+    CCutil_getmaster (char *mastername, int *ncount, CCdatagroup *dat,
+            int **perm),
+    CCutil_getnodeweights (char *weightname, int ncount, int weight_limit,
+            double **wcoord),
+    CCutil_gettsplib (char *datname, int *ncount, CCdatagroup *dat),
+    CCutil_datagroup_perm (int ncount, CCdatagroup *dat, int *perm),
+    CCutil_getedgelist (int ncount, char *fname, int *ecount, int **elist,
+            int **elen),
+    CCutil_getedgelist_n (int *ncount, char *fname, int *ecount, int **elist,
+            int **elen),
+    CCutil_getcycle_edgelist (int ncount, char *cyclename, int *outcycle),
+    CCutil_getcycle (int ncount, char *cyclename, int *outcycle),
+    CCutil_getedges_double (int *ncount, char *fname, int *ecount, int **elist,
+            double **elen, int binary_in),
+    CCutil_writeedges (int ncount, char *outedgename, int ecount, int *elist,
+            CCdatagroup *dat),
+    CCutil_writecycle_edgelist (int ncount, char *outedgename, int *cycle,
+            CCdatagroup *dat),
+    CCutil_writecycle (int ncount, char *outcyclename, int *cycle),
+    CCutil_writeedges_double (int ncount, char *outedgename, int ecount,
+            int *elist, double *elen, int binary_out);
+
+#else
+
+int
+    CCutil_getdata (),
+    CCutil_writemaster (),
+    CCutil_getmaster (),
+    CCutil_getnodeweights (),
+    CCutil_gettsplib (),
+    CCutil_datagroup_perm (),
+    CCutil_getedgelist (),
+    CCutil_getedgelist_n (),
+    CCutil_getcycle_edgelist (),
+    CCutil_getcycle (),
+    CCutil_getedges_double (),
+    CCutil_writeedges (),
+    CCutil_writecycle_edgelist (),
+    CCutil_writecycle (),
+    CCutil_writeedges_double ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             priority.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCpriority {
+    CCdheap   heap;
+    union pri_data {
+        void *data;
+        int  next;
+    }        *pri_info;
+    int       space;
+    int       freelist;
+} CCpriority;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_priority_free (CCpriority *pri),
+    CCutil_priority_delete (CCpriority *pri, int handle),
+    CCutil_priority_changekey (CCpriority *pri, int handle, double newkey),
+   *CCutil_priority_findmin (CCpriority *pri, double *keyval),
+   *CCutil_priority_deletemin (CCpriority *pri, double *keyval);
+
+int
+    CCutil_priority_init (CCpriority *pri, int k),
+    CCutil_priority_insert (CCpriority *pri, void *data, double keyval);
+
+#else
+
+void
+    CCutil_priority_free (),
+    CCutil_priority_delete (),
+    CCutil_priority_changekey (),
+   *CCutil_priority_findmin (),
+   *CCutil_priority_deletemin ();
+
+int
+    CCutil_priority_init (),
+    CCutil_priority_insert ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             safe_io.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#define CC_SBUFFER_SIZE (4000)
+#define CC_SFNAME_SIZE (32)
+
+typedef struct CC_SFILE {
+    int           status;
+    int           desc;
+    int           chars_in_buffer;
+    int           current_buffer_char;     /* only used for reading */
+    int           bits_in_last_char;       /* writing: number of empty bits in
+                                            * buffer[chars_in_buffer];
+                                            * reading: number of full bits in
+                                            * buffer[?] */
+    int           pos;
+    char          fname[CC_SFNAME_SIZE];
+    unsigned char buffer[CC_SBUFFER_SIZE];
+} CC_SFILE;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+CC_SFILE
+   *CCutil_sopen (char *f, char *s),
+   *CCutil_sdopen (int d, char *s);
+
+int
+    CCutil_swrite (CC_SFILE *f, unsigned char *buf, int size),
+    CCutil_swrite_bits (CC_SFILE *f, unsigned int x, int xbits),
+    CCutil_swrite_char (CC_SFILE *f, unsigned char x),
+    CCutil_swrite_string (CC_SFILE *f, unsigned char *x),
+    CCutil_swrite_short (CC_SFILE *f, unsigned short x),
+    CCutil_swrite_int (CC_SFILE *f, unsigned int x),
+    CCutil_swrite_double (CC_SFILE *f, double x),
+    CCutil_sread (CC_SFILE *f, unsigned char *buf, int size),
+    CCutil_sread_bits (CC_SFILE *f, unsigned int *x, int xbits),
+    CCutil_sread_char (CC_SFILE *f, unsigned char *x),
+    CCutil_sread_string (CC_SFILE *f, unsigned char *x, int maxlen),
+    CCutil_sread_short (CC_SFILE *f, unsigned short *x),
+    CCutil_sread_short_r (CC_SFILE *f, unsigned short *x),
+    CCutil_sread_int (CC_SFILE *f, unsigned int *x),
+    CCutil_sread_int_r (CC_SFILE *f, unsigned int *x),
+    CCutil_sread_double (CC_SFILE *f, double *x),
+    CCutil_sread_double_r (CC_SFILE *f, double *x),
+    CCutil_sflush (CC_SFILE *f),
+    CCutil_stell (CC_SFILE *f),
+    CCutil_sseek (CC_SFILE *f, int offset),
+    CCutil_srewind (CC_SFILE *f),
+    CCutil_sclose (CC_SFILE *f),
+    CCutil_sbits (unsigned int x),
+    CCutil_sdelete_file (char *fname),
+    CCutil_sdelete_file_backup (char *fname);
+
+#else
+
+CC_SFILE
+   *CCutil_sopen (),
+   *CCutil_sdopen ();
+
+int
+    CCutil_swrite (),
+    CCutil_swrite_bits (),
+    CCutil_swrite_char (),
+    CCutil_swrite_string (),
+    CCutil_swrite_short (),
+    CCutil_swrite_int (),
+    CCutil_swrite_double (),
+    CCutil_sread (),
+    CCutil_sread_bits (),
+    CCutil_sread_char (),
+    CCutil_sread_string (),
+    CCutil_sread_short (),
+    CCutil_sread_short_r (),
+    CCutil_sread_int (),
+    CCutil_sread_int_r (),
+    CCutil_sread_double (),
+    CCutil_sread_double_r (),
+    CCutil_sflush (),
+    CCutil_stell (),
+    CCutil_sseek (),
+    CCutil_srewind (),
+    CCutil_sclose (),
+    CCutil_sbits (),
+    CCutil_sdelete_file (),
+    CCutil_sdelete_file_backup ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             sortrus.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_int_array_quicksort (int *len, int n),
+    CCutil_int_perm_quicksort (int *perm, int *len, int n),
+    CCutil_double_perm_quicksort (int *perm, double *len, int n),
+    CCutil_rselect (int *arr, int l, int r, int m, double *coord);
+
+char
+   *CCutil_linked_radixsort (char *data, char *datanext, char *dataval,
+            int valsize);
+
+#else
+
+void
+    CCutil_int_array_quicksort (),
+    CCutil_int_perm_quicksort (),
+    CCutil_double_perm_quicksort (),
+    CCutil_rselect ();
+
+char
+   *CCutil_linked_radixsort ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             urandom.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_sprand (int);
+int
+    CCutil_lprand (void);
+
+#else
+
+void
+    CCutil_sprand ();
+int
+    CCutil_lprand ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             util.c                                      */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+char
+   *CCutil_strrchr (char *s, int c);
+
+unsigned int
+    CCutil_nextprime (unsigned int x);
+
+int
+    CCutil_our_gcd (int a, int b);
+
+#else
+
+char
+   *CCutil_strrchr ();
+
+unsigned int
+    CCutil_nextprime ();
+
+int
+    CCutil_our_gcd ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             zeit.c                                      */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+double
+    CCutil_zeit (void),
+    CCutil_real_zeit (void);
+
+#else
+
+double
+    CCutil_zeit (),
+    CCutil_real_zeit ();
+
+#endif
+
+
+#endif /* __UTIL_H */
diff --git a/contrib/blossom/concorde97/KDTREE/Makefile b/contrib/blossom/concorde97/KDTREE/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0a5d597ba21e8f3bef8548f5f78c3bb32d7968d6
--- /dev/null
+++ b/contrib/blossom/concorde97/KDTREE/Makefile
@@ -0,0 +1,33 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=kdtree.a
+LIBSRCS=kdbuild.c kdnear.c kdspan.c kdtwoopt.c
+LIBS=$(ROOT)/UTIL/util.a
+ALLSRCS=kd_main.c $(LIBSRCS)
+
+all: kdtree $(LIB)
+
+kdtree: kd_main.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ -lm
+
+clean:
+	-rm -f *.$o $(LIB) kdtree
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+kd_main.$o:  kd_main.c  $(I)/machdefs.h $(I)/util.h     $(I)/kdtree.h   
+kdbuild.$o:  kdbuild.c  $(I)/machdefs.h $(I)/util.h     $(I)/kdtree.h   
+kdnear.$o:   kdnear.c   $(I)/machdefs.h $(I)/util.h     $(I)/kdtree.h   
+kdspan.$o:   kdspan.c   $(I)/machdefs.h $(I)/util.h     $(I)/kdtree.h   
+kdtwoopt.$o: kdtwoopt.c $(I)/machdefs.h $(I)/util.h     $(I)/kdtree.h   
diff --git a/contrib/blossom/concorde97/KDTREE/kd_main.c b/contrib/blossom/concorde97/KDTREE/kd_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..013f940b288b025939cf08d6a01f12212bf32dad
--- /dev/null
+++ b/contrib/blossom/concorde97/KDTREE/kd_main.c
@@ -0,0 +1,544 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  CODE FOR TESTING KD-TREE ROUTINES                      */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 24, 1995  (cofeb24)                                     */
+/*                                                                         */
+/*  For a short describtion see usage ()                                   */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "machdefs.h"
+#include "util.h"
+#include "kdtree.h"
+
+static int norm = CC_EUCLIDEAN;
+static int usenodeweights = 0;
+static int random_weight_limit = 0;
+static int seed = 0;
+static int nnodes_want = 0;
+static int nearnum = 0;
+static int quadnearnum = 0;
+static int find_nearest_tour = 0;
+static int find_nearest_2match = 0;
+static int find_greedy_tour = 0;
+static int find_fa_tour = 0;
+static int find_qboruvka_tour = 0;
+static int find_boruvka_tour = 0;
+static int find_twoopt_tour = 0;
+static int find_3opt_tour = 0;
+static int find_spanning_tree = 0;
+static int run_two_and_a_half_opt = 0;
+static int binary_in = 0;
+static int tsplib_in = 0;
+
+static char *nodefile = (char *) NULL;
+static char *weightfile = (char *) NULL;
+static char *cycle_for_twoopt = (char *) NULL;
+static char *outfile = (char *) NULL;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+static void
+    usage (char *f);
+static int
+    parseargs (int ac, char **av);
+
+#else
+
+int
+    main ();
+static void
+    usage ();
+static int
+    parseargs ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    double val, szeit;
+    CCkdtree kt;
+    CCdatagroup dat;
+    double *wcoord = (double *) NULL;
+    int ncount;
+    int *ttour = (int *) NULL, *tour2 = (int *) NULL;
+    int rval = 0;
+    int ecount;
+    int *elist = (int *) NULL;
+
+    seed = (int) CCutil_real_zeit ();
+    if (parseargs (ac, av))
+        return 1;
+    CCutil_sprand (seed);
+
+    if ((!nnodes_want && !nodefile) || (tsplib_in && !nodefile)) {
+        usage (av[0]);
+        return 1;
+    }
+
+    if (tsplib_in) {
+        if (CCutil_gettsplib (nodefile, &ncount, &dat)) {
+            fprintf (stderr, "could not read the TSPLIB file\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        norm = dat.norm;
+    } else {
+        ncount = nnodes_want;
+        if (CCutil_getdata (nodefile, binary_in, norm, &ncount, &dat)) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if ((norm & CC_NORM_BITS) != CC_KD_NORM_TYPE) {
+        fprintf (stderr, "Cannot run CCkdtree with norm %d\n", norm);
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (CCutil_init_dat_edgelen (&dat)) {
+        fprintf (stderr, "init_dat_edgelen failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (usenodeweights) {
+        if (CCutil_getnodeweights (weightfile, ncount, random_weight_limit,
+                                   &wcoord)) {
+            fprintf (stderr, "could not read the nodeweight file\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (find_nearest_tour || find_greedy_tour || find_twoopt_tour ||
+        find_fa_tour || find_qboruvka_tour || find_boruvka_tour ||
+        find_3opt_tour) {
+        ttour = CC_SAFE_MALLOC (ncount, int);
+        if (!ttour) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (find_twoopt_tour || find_3opt_tour) {
+        tour2 = CC_SAFE_MALLOC (ncount, int);
+        if (!tour2) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (cycle_for_twoopt) {
+        if (CCutil_getcycle (ncount, cycle_for_twoopt, ttour)) {
+            fprintf (stderr, "Getcycle failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    } else if (find_nearest_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_nearest_neighbor_tour ((CCkdtree *) NULL, ncount,
+                  CCutil_lprand () % ncount, &dat, ttour, &val)) {
+            fprintf (stderr, "Nearest neighbor failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("NN tour: %.2f (%.2f seconds)\n", val, CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (find_fa_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_far_add_tour ((CCkdtree *) NULL, ncount,
+                  CCutil_lprand () % ncount, &dat, ttour, &val)) {
+            fprintf (stderr, "Farthest Addition Tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("FA tour: %.2f (%.2f seconds)\n", val, CCutil_zeit () - szeit);
+        fflush (stdout);
+        {
+            char *marks;
+            int i;
+
+            marks = CC_SAFE_MALLOC (ncount, char);
+            if (!marks) {
+                rval = 1;
+                goto CLEANUP;
+            }
+            for (i = 0; i < ncount; i++)
+                marks[i] = 0;
+            for (i = 0; i < ncount; i++) {
+                if (ttour[i] < 0 || ttour[i] >= ncount) {
+                    fprintf (stderr, "MADE NODE IN FA TOUR: %d\n", ttour[i]);
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                if (marks[ttour[i]]) {
+                    fprintf (stderr, "REPEAT NODE IN FA-TOUR: %d\n", ttour[i]);
+                    fprintf (stderr, "BAD INDEX: %d\n", i);
+                    rval = 1;
+                    goto CLEANUP;
+                } else {
+                    marks[ttour[i]] = 1;
+                }
+            }
+            CC_FREE (marks, char);
+        }
+    } else if (find_boruvka_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_boruvka_tour ((CCkdtree *) NULL, ncount, &dat, ttour,
+                                    &val)) {
+            fprintf (stderr, "Boruvka tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Boruvka tour: %.2f (%.2f seconds)\n",
+                         val, CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (find_qboruvka_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_qboruvka_tour ((CCkdtree *) NULL, ncount, &dat, ttour,
+                                     &val)) {
+            fprintf (stderr, "Quick-Boruvka tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Quick-Boruvka tour: %.2f (%.2f seconds)\n",
+                         val, CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (find_greedy_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_greedy_tour ((CCkdtree *) NULL, ncount, &dat, ttour,
+                                   &val)) {
+            fprintf (stderr, "Greedy tour failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Greedy tour: %.2f (%.2f seconds)\n",
+                         val, CCutil_zeit () - szeit);
+        fflush (stdout);
+    }
+
+    if (find_twoopt_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_twoopt_tour ((CCkdtree *) NULL, ncount, &dat, ttour,
+                                tour2, &val, run_two_and_a_half_opt, 0)) {
+            fprintf (stderr, "Two-opt failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("2-opt tour: %.2f (%.2f seconds))\n",
+                         val, CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (find_3opt_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_3opt_tour ((CCkdtree *) NULL, ncount, &dat, ttour, tour2,
+                                 &val, 0)) {
+            fprintf (stderr, "3-opt failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("3-opt tour: %.2f (%.2f seconds))\n",
+                         val, CCutil_zeit () - szeit);
+        fflush (stdout);
+        {
+            char *marks;
+            int i;
+
+            marks = CC_SAFE_MALLOC (ncount, char);
+            if (!marks) {
+                rval = 1;
+                goto CLEANUP;
+            }
+            for (i = 0; i < ncount; i++)
+                marks[i] = 0;
+            for (i = 0; i < ncount; i++) {
+                if (tour2[i] < 0 || tour2[i] >= ncount) {
+                    fprintf (stderr, "MADE NODE IN TOUR2: %d\n", tour2[i]);
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                if (marks[tour2[i]]) {
+                    fprintf (stderr, "REPEATED NODE IN TOUR2: %d\n",
+                             tour2[i]);
+                    rval = 1;
+                    goto CLEANUP;
+                } else {
+                    marks[tour2[i]] = 1;
+                }
+            }
+            CC_FREE (marks, char);
+        }
+    }
+
+    if (find_spanning_tree) {
+        if (outfile) {
+            ecount = ncount - 1;
+            elist = CC_SAFE_MALLOC (2 * ecount, int);
+            if (!elist) {
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        szeit = CCutil_zeit ();
+        if (CCkdtree_prim_spanningtree ((CCkdtree *) NULL, ncount, &dat, wcoord,
+                                         elist, &val)) {
+            fprintf (stderr, "Prim_spanningtree failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Min spanning tree: %.2f (%.2f seconds)\n", val,
+                 CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (nearnum) {
+        int wantlist = (outfile ? 1 : 0);
+        szeit = CCutil_zeit ();
+        if (CCkdtree_k_nearest ((CCkdtree *) NULL, ncount, nearnum, &dat,
+                                 wcoord, wantlist, &ecount, &elist)) {
+            fprintf (stderr, "k-nearest failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Nearest %d: %.2f (seconds)\n",
+                         nearnum, CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (quadnearnum) {
+        int wantlist = (outfile ? 1 : 0);
+        szeit = CCutil_zeit ();
+        if (CCkdtree_quadrant_k_nearest ((CCkdtree *) NULL, ncount, quadnearnum,
+              &dat, wcoord, wantlist, &ecount, &elist)) {
+            fprintf (stderr, "k-nearest failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Quadrant-Nearest %d: %.2f (seconds)\n", quadnearnum,
+                 CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (find_nearest_2match) {
+        if (outfile) {
+            ecount = ncount;
+            elist = CC_SAFE_MALLOC (2 * ecount, int);
+            if (!elist) {
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        szeit = CCutil_zeit ();
+        if (CCkdtree_nearest_neighbor_2match ((CCkdtree *) NULL, ncount,
+               CCutil_lprand () % ncount, &dat, elist, &val)) {
+            fprintf (stderr, "Nearest neighbor 2-matching failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Nearest 2-matching: %.2f (%.2f seconds)\n", val,
+                 CCutil_zeit () - szeit);
+        fflush (stdout);
+    } else if (!find_nearest_tour && !find_greedy_tour && !find_twoopt_tour &&
+               !find_qboruvka_tour && !find_boruvka_tour && !find_fa_tour &&
+               !find_3opt_tour) {
+        szeit = CCutil_zeit ();
+        if (CCkdtree_build (&kt, ncount, &dat, wcoord)) {
+            fprintf (stderr, "CCkdtree_build failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        printf ("Built CCkdtree: %.2f (seconds)\n", CCutil_zeit () - szeit);
+        fflush (stdout);
+        CCkdtree_free (&kt);
+    }
+
+    if (outfile) {
+        if (find_twoopt_tour || find_3opt_tour) {
+            if (CCutil_writecycle (ncount, outfile, tour2)) {
+                fprintf (stderr, "Could not write tour\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        } else if (find_nearest_tour || find_greedy_tour || find_fa_tour ||
+                   find_qboruvka_tour || find_boruvka_tour) {
+            if (CCutil_writecycle (ncount, outfile, ttour)) {
+                fprintf (stderr, "Could not write tour\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        } else if (find_spanning_tree ||  find_nearest_2match || nearnum ||
+                                                             quadnearnum) {
+            if (CCutil_writeedges (ncount, outfile, ecount, elist, &dat)) {
+                fprintf (stderr, "Could not write the edge set\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+    }
+
+
+CLEANUP:
+
+    CCutil_freedatagroup (ncount, &dat);
+    if (wcoord)
+        CC_FREE (wcoord, double);
+    if (ttour)
+        CC_FREE (ttour, int);
+    if (tour2)
+        CC_FREE (tour2, int);
+    if (elist)
+        CC_FREE (elist, int);
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: CCutil_bigcunk free world failed\n");
+        return 1;
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "bfghjk:mn:o:pq:s:tTvw:W:x:Xz:Z012?")) != EOF)
+        switch (c) {
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'f':
+            find_fa_tour = 1;
+            break;
+        case 'j':
+            find_qboruvka_tour = 1;
+            break;
+        case 'w':
+            usenodeweights = 1;
+            weightfile = CCutil_bix_optarg;
+            break;
+        case 'W':
+            usenodeweights = 1;
+            random_weight_limit = atoi (CCutil_bix_optarg);
+            break;
+        case 'k':
+            nnodes_want = atoi (CCutil_bix_optarg);
+            break;
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 'n':
+            nearnum = atoi (CCutil_bix_optarg);
+            break;
+        case 'm':
+            find_nearest_2match++;
+            break;
+        case 'q':
+            quadnearnum = atoi (CCutil_bix_optarg);
+            break;
+        case 't':
+            find_nearest_tour++;
+            break;
+        case 'g':
+            find_greedy_tour++;
+            break;
+        case 'v':
+            find_boruvka_tour++;
+            break;
+        case 'Z':
+            find_twoopt_tour++;
+            find_greedy_tour++;
+            break;
+        case 'z':
+            cycle_for_twoopt = CCutil_bix_optarg;
+            find_twoopt_tour++;
+            break;
+        case 'X':
+            find_3opt_tour++;
+            find_greedy_tour++;
+            break;
+        case 'x':
+            cycle_for_twoopt = CCutil_bix_optarg;
+            find_3opt_tour++;
+            break;
+        case 'h':
+            run_two_and_a_half_opt++;
+            break;
+        case 'o':
+            outfile = CCutil_bix_optarg;
+            break;
+        case 'p':
+            find_spanning_tree++;
+            break;
+        case 'T':
+            tsplib_in = 1;
+            break;
+        case '0':
+            norm = CC_MAXNORM;
+            break;
+        case '1':
+            norm = CC_EUCLIDEAN_CEIL;
+            break;
+        case '2':
+            norm = CC_EUCLIDEAN;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+        default:
+            usage (av[0]);
+            return 1;
+        }
+    if (CCutil_bix_optind < ac)
+        nodefile = av[CCutil_bix_optind++];
+
+    if (CCutil_bix_optind > ac) {
+        usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "Usage: %s [- see below -] [node_file]\n", f);
+    fprintf (stderr, "          -b:   dat file in binary-ints\n");
+    fprintf (stderr, "          -w f  use node weights from file\n");
+    fprintf (stderr, "          -W #  use random node weights (0, #)\n");
+    fprintf (stderr, "          -k #  number of nodes for random problem\n");
+    fprintf (stderr, "          -s #  random seed\n");
+    fprintf (stderr, "          -n #  find # nearest graph\n");
+    fprintf (stderr, "          -q #  find quadrant # nearest graph\n");
+    fprintf (stderr, "          -t    nearest neighbor tour\n");
+    fprintf (stderr, "          -g    greedy tour\n");
+    fprintf (stderr, "          -j    quick-boruvka tour\n");
+    fprintf (stderr, "          -v    boruvka tour\n");
+    fprintf (stderr, "          -f    farthest addition tour\n");
+    fprintf (stderr, "          -z f  two_opt the given cycle\n");
+    fprintf (stderr, "          -Z    run two_opt (default: on greedy)\n");
+    fprintf (stderr, "          -x f  3_opt the given cycle\n");
+    fprintf (stderr, "          -X    run 3_opt (default: on greedy)\n");
+    fprintf (stderr, "          -h    use limited 3-swaps in two_opt\n");
+    fprintf (stderr, "          -m    nearest neighbor 2-matcing\n");
+    fprintf (stderr, "          -p    min spanning tree (prim)\n");
+    fprintf (stderr, "          -o f  write the cycle or edge set to f\n");
+    fprintf (stderr, "          -T    node file is a TSPLIB file\n");
+    fprintf (stderr, "          -0    Max norm for edge lengths\n");
+    fprintf (stderr, "          -1    Euclidean Ceiling norm\n");
+    fprintf (stderr, "          -2    Rounded Euclidean norm (default)\n");
+}
diff --git a/contrib/blossom/concorde97/KDTREE/kdbuild.c b/contrib/blossom/concorde97/KDTREE/kdbuild.c
new file mode 100644
index 0000000000000000000000000000000000000000..3efcf0091044c730fc0e17dc45104ad7ef910909
--- /dev/null
+++ b/contrib/blossom/concorde97/KDTREE/kdbuild.c
@@ -0,0 +1,474 @@
+/***************************************************************************/
+/*                                                                         */
+/*                   ROUTINE FOR BUILDING KDTREES                          */
+/*                                                                         */
+/*  (Based on Jon Bentley's paper "K-d trees for semidynamic point sets")  */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 24, 1995 (cofeb24)                                      */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCkdtree_build (CCkdtree *intree, int ncount, CCdatagroup *dat,  */
+/*                 double *wcoord)                                         */
+/*       -When called, intree should point to a CCkdtree struct that the   */
+/*        funtion will load with the tree it builds. The wcoord array      */
+/*        is used for node weights (like in Held-Karp), it can be NULL.    */
+/*        The node weights must be nonegative (for cutoffs).               */
+/*    void CCkdtree_free (CCkdtree *kt)                                    */
+/*       -Frees the space (including the ptrs) used by kt.                 */
+/*    void CCkdtree_delete (CCkdtree *kt, int k)                           */
+/*       -Deletes the point k from the CCkdtree kt.                        */
+/*    void CCkdtree_undelete (CCkdtree *kt, int k)                         */
+/*       -Puts the previously deleted point k back into kt.                */
+/*    void CCkdtree_delete_all (CCkdtree *kt, int ncount)                  */
+/*       -Deletes all points in kt.                                        */
+/*    void CCkdtree_undelete_all (CCkdtree *kt, int ncount)                */
+/*       -Puts all deleted points back in kt. Used to cleanup trees.       */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*       On a 32 bit machine, a CCkdtree on n nodes needs about 52n bytes  */
+/*    of memory. CCkdtree_build will return 1 if an error occurs (most     */
+/*    likely running out of memory).                                       */
+/*       CCutil_sprand () should be called before calling                  */
+/*    CCkdtree_build ().                                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "kdtree.h"
+
+#define CUTOFF 5
+#define BNDS_DEPTH 5   /* When bnds info is recorded */
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+#define BIGDOUBLE 100000000.0
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    kdtree_free_work (CCkdnode *p),
+    kdtree_free_world (void);
+static unsigned char
+    findmaxspread (int l, int u, CCkdtree *thetree, double *datx,
+           double *daty, double *datw);
+static CCkdnode
+    *build (int l, int u, int *depth, double *current_bnds_x,
+           double *current_bnds_y, CCkdtree *thetree, double *datx,
+           double *daty, double *datw);
+
+#else
+
+static void
+    kdtree_free_work (),
+    kdtree_free_world ();
+static unsigned char
+    findmaxspread ();
+static CCkdnode
+    *build ();
+
+#endif
+
+CC_PTR_ALLOC_ROUTINE (CCkdnode, CCkdnodealloc, CCkdnodechunklist,
+        CCkdnodefreelist)
+CC_PTR_FREE_ROUTINE (CCkdnode, CCkdnodefree, CCkdnodefreelist)
+CC_PTR_FREE_WORLD_ROUTINE (CCkdnode, CCkdnodefree_world, CCkdnodechunklist,
+        CCkdnodefreelist)
+CC_PTR_LEAKS_ROUTINE (CCkdnode, CCkdnode_check_leaks, CCkdnodechunklist,
+        CCkdnodefreelist, empty, char)
+CC_PTR_STATUS_ROUTINE (CCkdnode, CCkdnode_status, CCkdnodechunklist,
+        CCkdnodefreelist)
+
+CC_PTR_ALLOC_ROUTINE (CCkdbnds, CCkdbndsalloc, CCkdbndschunklist,
+        CCkdbndsfreelist)
+CC_PTR_FREE_ROUTINE (CCkdbnds, CCkdbndsfree, CCkdbndsfreelist)
+CC_PTR_FREE_WORLD_ROUTINE (CCkdbnds, CCkdbndsfree_world, CCkdbndschunklist,
+        CCkdbndsfreelist)
+CC_PTR_LEAKS_ROUTINE (CCkdbnds, CCkdbnds_check_leaks, CCkdbndschunklist,
+        CCkdbndsfreelist, x[0], double)
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_build (CCkdtree *intree, int ncount, CCdatagroup *dat,
+            double *wcoord)
+#else
+int CCkdtree_build (intree, ncount, dat, wcoord)
+CCkdtree *intree;
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+#endif
+{
+    int i;
+    int depth;
+    double current_bnds_x[2];
+    double current_bnds_y[2];
+    CCkdtree *thetree;
+
+    if (wcoord != (double *) NULL) {
+        for (i = 0; i < ncount; i++) {
+            if (wcoord[i] < -0.00000001) {
+                fprintf (stderr, "Cannot build with negative node weights\n");
+                return 1;
+            }
+        }
+    }
+
+    thetree = intree;
+    thetree->perm = CC_SAFE_MALLOC (ncount, int);
+    if (!thetree->perm)
+        return 1;
+    for (i = 0; i < ncount; i++)
+        thetree->perm[i] = i;
+
+    thetree->bucketptr = CC_SAFE_MALLOC (ncount, CCkdnode *);
+    if (!thetree->bucketptr) {
+        CC_FREE (thetree->perm, int);
+        return 1;
+    }
+
+    depth = 0;
+    current_bnds_x[0] = -BIGDOUBLE;
+    current_bnds_x[1] =  BIGDOUBLE;
+    current_bnds_y[0] = -BIGDOUBLE;
+    current_bnds_y[1] =  BIGDOUBLE;
+
+    thetree->root = build (0, ncount - 1, &depth, current_bnds_x,
+                           current_bnds_y, thetree, dat->x, dat->y, wcoord);
+    if (!(thetree->root)) {
+        fprintf (stderr, "Unable to build CCkdtree\n");
+        CC_FREE (thetree->perm, int);
+        CC_FREE (thetree->bucketptr, CCkdnode *);
+        return 1;
+    } else {
+        thetree->root->father = (CCkdnode *) NULL;
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCkdtree_free (CCkdtree *kt)
+#else
+void CCkdtree_free (kt)
+CCkdtree *kt;
+#endif
+{
+    int total, onlist;
+
+    if (kt->perm)
+        CC_FREE (kt->perm, int);
+    if (kt->bucketptr)
+        CC_FREE (kt->bucketptr, CCkdnode *);
+    kdtree_free_work (kt->root);
+    kt->root = (CCkdnode *) NULL;
+    if (CCkdnode_status (&total, &onlist)) {
+        printf ("Active Kdtree Nodes: %d\n", total - onlist);
+        fflush (stdout);
+    } else {
+        kdtree_free_world ();
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void kdtree_free_world (void)
+#else
+static void kdtree_free_world ()
+#endif
+{
+    int total, onlist;
+
+    if (CCkdnode_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding CCkdnodes\n", total - onlist);
+    }
+    if (CCkdbnds_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding CCkdbnds\n", total - onlist);
+    }
+    CCkdnodefree_world ();
+    CCkdbndsfree_world ();
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void kdtree_free_work (CCkdnode *p)
+#else
+static void kdtree_free_work (p)
+CCkdnode *p;
+#endif
+{
+    if (p->bucket) {
+        if (p->bnds)
+            CCkdbndsfree (p->bnds);
+        CCkdnodefree (p);
+    } else {
+        kdtree_free_work (p->loson);
+        kdtree_free_work (p->hison);
+        if (p->bnds)
+            CCkdbndsfree (p->bnds);
+        CCkdnodefree (p);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static CCkdnode *build (int l, int u, int *depth, double *current_bnds_x,
+               double *current_bnds_y, CCkdtree *thetree,
+               double *datx, double *daty, double *datw)
+#else
+static CCkdnode *build (l, u, depth, current_bnds_x, current_bnds_y, thetree,
+               datx, daty, datw)
+int l, u;
+int *depth;
+double *current_bnds_x, *current_bnds_y;
+CCkdtree *thetree;
+double *datx, *daty, *datw;
+#endif
+{
+    CCkdnode *p;
+    int i, m;
+    double savebnd;
+
+    (*depth)++;
+    p = CCkdnodealloc ();
+    if (!p) {
+        (*depth)--;
+        return (CCkdnode *) NULL;
+    }
+    p->empty = 0;
+
+    if (u - l + 1 < CUTOFF) {
+        p->bucket = 1;
+        p->lopt = l;
+        p->hipt = u;
+        for (i = l; i <= u; i++)
+            thetree->bucketptr[thetree->perm[i]] = p;
+        p->bnds = (CCkdbnds *) NULL;
+    } else {
+        p->bucket = 0;
+        if (!((*depth) % BNDS_DEPTH)) {
+            p->bnds = CCkdbndsalloc ();
+            if (!p->bnds) {
+                (*depth)--;
+                CCkdnodefree (p);
+                return (CCkdnode *) NULL;
+            }
+            p->bnds->x[0] = current_bnds_x[0];
+            p->bnds->x[1] = current_bnds_x[1];
+            p->bnds->y[0] = current_bnds_y[0];
+            p->bnds->y[1] = current_bnds_y[1];
+        } else {
+            p->bnds = (CCkdbnds *) NULL;
+        }
+
+        p->cutdim = findmaxspread (l, u, thetree, datx, daty, datw);
+        m = (l + u) / 2;
+        switch (p->cutdim) {
+        case 0:
+            CCutil_rselect (thetree->perm, l, u, m, datx);
+            p->cutval = datx[thetree->perm[m]];
+
+            savebnd = current_bnds_x[1];
+            current_bnds_x[1] = p->cutval;
+            p->loson = build (l, m, depth, current_bnds_x, current_bnds_y,
+                              thetree, datx, daty, datw);
+            if (!p->loson)
+                { (*depth)--; CCkdnodefree (p); return (CCkdnode *) NULL; }
+            current_bnds_x[1] = savebnd;
+
+            savebnd = current_bnds_x[0];
+            current_bnds_x[0] = p->cutval;
+            p->hison = build (m + 1, u, depth, current_bnds_x, current_bnds_y,
+                              thetree, datx, daty, datw);
+            if (!p->hison)
+                { (*depth)--; CCkdnodefree (p); return (CCkdnode *) NULL; }
+            current_bnds_x[0] = savebnd;
+
+            break;
+        case 1:
+            CCutil_rselect (thetree->perm, l, u, m, daty);
+            p->cutval = daty[thetree->perm[m]];
+
+            savebnd = current_bnds_y[1];
+            current_bnds_y[1] = p->cutval;
+            p->loson = build (l, m, depth, current_bnds_x, current_bnds_y,
+                              thetree, datx, daty, datw);
+            if (!p->loson)
+                { (*depth)--; CCkdnodefree (p); return (CCkdnode *) NULL; }
+            current_bnds_y[1] = savebnd;
+
+            savebnd = current_bnds_y[0];
+            current_bnds_y[0] = p->cutval;
+            p->hison = build (m + 1, u, depth, current_bnds_x, current_bnds_y,
+                              thetree, datx, daty, datw);
+            if (!p->hison)
+                { (*depth)--; CCkdnodefree (p); return (CCkdnode *) NULL; }
+            current_bnds_y[0] = savebnd;
+
+            break;
+        case 2:
+            CCutil_rselect (thetree->perm, l, u, m, datw);
+            p->cutval = datw[thetree->perm[m]];
+
+            p->loson = build (l, m, depth, current_bnds_x, current_bnds_y,
+                              thetree, datx, daty, datw);
+            if (!p->loson)
+                { (*depth)--; CCkdnodefree (p); return (CCkdnode *) NULL; }
+
+            p->hison = build (m + 1, u, depth, current_bnds_x, current_bnds_y,
+                              thetree, datx, daty, datw);
+            if (!p->hison)
+                { (*depth)--; CCkdnodefree (p); return (CCkdnode *) NULL; }
+
+            break;
+        }
+        p->loson->father = p;
+        p->hison->father = p;
+    }
+    (*depth)--;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static unsigned char findmaxspread (int l, int u, CCkdtree *thetree,
+                                    double *datx, double *daty, double *datw)
+#else
+static unsigned char findmaxspread (l, u, thetree, datx, daty, datw)
+int l, u;
+CCkdtree *thetree;
+double *datx, *daty, *datw;
+#endif
+{
+    int i;
+    double xmax, xmin, xval, xspread;
+    double ymax, ymin, yval, yspread;
+    double wmax, wmin, wval, wspread;
+
+    wmax = (double) 0.0;
+    wmin = (double) 0.0;
+
+    if (datw != (double *) NULL) {
+        wmin = datw[thetree->perm[l]];
+        wmax = wmin;
+    }
+    xmin = datx[thetree->perm[l]];
+    xmax = xmin;
+    ymin = daty[thetree->perm[l]];
+    ymax = ymin;
+    for (i = l + 1; i <= u; i++) {
+        xval = datx[thetree->perm[i]];
+        if (xval < xmin)
+            xmin = xval;
+        else if (xval > xmax)
+            xmax = xval;
+        yval = daty[thetree->perm[i]];
+        if (yval < ymin)
+            ymin = yval;
+        else if (yval > ymax)
+            ymax = yval;
+        if (datw != (double *) NULL) {
+            wval = datw[thetree->perm[i]];
+            if (wval < wmin)
+                wmin = wval;
+            else if (wval > wmax)
+                wmax = wval;
+        }
+    }
+
+    xspread = xmax - xmin;
+    yspread = ymax - ymin;
+
+    if (datw != (double *) NULL) {
+        wspread = (wmax - wmin);
+        if (xspread >= yspread && xspread >= wspread)
+            return (unsigned char) 0;
+        else if (yspread >= xspread && yspread >= wspread)
+            return (unsigned char) 1;
+        else {
+            return (unsigned char) 2;
+        }
+    } else {
+        if (xspread >= yspread)
+            return (unsigned char) 0;
+        else
+            return (unsigned char) 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCkdtree_delete (CCkdtree *kt, int k)
+#else
+void CCkdtree_delete (kt, k)
+CCkdtree *kt;
+int k;
+#endif
+{
+    int j, temp;
+    CCkdnode *p;
+
+    p = kt->bucketptr[k];
+    j = p->lopt;
+    while (kt->perm[j] != k)
+        j++;
+    SWAP (kt->perm[j], kt->perm[p->hipt], temp);
+    (p->hipt)--;
+    if (p->lopt > p->hipt) {
+        p->empty = 1;
+        while ((p = p->father) != (CCkdnode *) NULL &&
+                p->loson->empty && p->hison->empty)
+            p->empty = 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCkdtree_delete_all (CCkdtree *kt, int ncount)
+#else
+void CCkdtree_delete_all (kt, ncount)
+CCkdtree *kt;
+int ncount;
+#endif
+{
+    int k;
+
+    for (k = 0; k < ncount; k++)
+        CCkdtree_delete (kt, k);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCkdtree_undelete (CCkdtree *kt, int k)
+#else
+void CCkdtree_undelete (kt, k)
+CCkdtree *kt;
+int k;
+#endif
+{
+    int j, temp;
+    CCkdnode *p;
+
+    p = kt->bucketptr[k];
+    j = p->lopt;
+    while (kt->perm[j] != k)
+        j++;
+    if (j > p->hipt) {
+        (p->hipt)++;
+        SWAP (kt->perm[j], kt->perm[p->hipt], temp);
+        if (p->empty) {
+            p->empty = 0;
+            while ((p = p->father) != (CCkdnode *) NULL && p->empty)
+                p->empty = 0;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCkdtree_undelete_all (CCkdtree *kt, int ncount)
+#else
+void CCkdtree_undelete_all (kt, ncount)
+CCkdtree *kt;
+int ncount;
+#endif
+{
+    int k;
+
+    for (k = 0; k < ncount; k++)
+        CCkdtree_undelete (kt, k);
+}
diff --git a/contrib/blossom/concorde97/KDTREE/kdnear.c b/contrib/blossom/concorde97/KDTREE/kdnear.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c2e24efec0849a51148eb9538c22654ca81a2e2
--- /dev/null
+++ b/contrib/blossom/concorde97/KDTREE/kdnear.c
@@ -0,0 +1,1438 @@
+/***************************************************************************/
+/*                                                                         */
+/*                 ROUTINES FOR FINDING NEAREST NEIGHBORS                  */
+/*                                                                         */
+/*  (Based on Jon Bentley's paper "K-d trees for semidynamic point sets")  */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 24, 1995  (cofeb24)                                     */
+/*  Changes: August 6 (bico)  -  added wcoord to fixed radius search       */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCkdtree_k_nearest (CCkdtree *kt, int ncount, int k,             */
+/*            CCdatagroup *dat, double *wcoord, int wantlist, int *ocount, */
+/*            int **olist)                                                 */
+/*      RETURNS the k-nearest neighbor graph.                              */
+/*        -kt can be NULL, otherwise it should point to a CCkdtree buildt  */
+/*         by a call to kdbuild ()                                         */
+/*        -ncount is the number of points.                                 */
+/*        -k is the number of nearest neighbors wanted.                    */
+/*        -wcoord is an array of node weights (like Held-Karp), it can     */
+/*         be NULL. The weights should be nonnegative.                     */
+/*        -wantlist is 1 if you want the function to return the edges.     */
+/*        -ocount returns the number of edges (if wantlist is 1) and       */
+/*         olist returns the edgelist is end1 end2 format.                 */
+/*    int CCkdtree_quadrant_k_nearest (CCkdtree *kt, int ncount, int k,    */
+/*           CCdatagroup *dat, double *wcoord,                             */
+/*           int wantlist, int *ocount, int **olist)                       */
+/*      RETURNS the quadrant k-nearest neighbor graph.                     */
+/*        -see CCkdtree_k_nearest.                                         */
+/*    int CCkdtree_node_k_nearest (CCkdtree *kt, int ncount, int n, int k, */
+/*           CCdatagroup *dat, double *wcoord, int *list)                  */
+/*      RETURNS the k nearest points to point n.                           */
+/*        -The k points are return in list (and list must be allocated by  */
+/*         calling routine.                                                */
+/*        -kt is a pointer to a CCkdtree previously built by               */
+/*         CCkdtree_build.                                                 */
+/*    int CCkdtree_node_quadrant_k_nearest (CCkdtree *kt, int ncount,      */
+/*            int n, int k, CCdatagroup *dat, double *wcoord, int *list)   */
+/*      RETURNS the quadrant k nearest point to point n.                   */
+/*        -see CCkdtree_node_k_nearest.                                    */
+/*    int CCkdtree_node_nearest (ktree *kt, int n, CCdatagroup *dat,       */
+/*          double *wcoord)                                                */
+/*      RETURNS the nearest point to point n.                              */
+/*        -kt CANNOT be NULL.                                              */
+/*        -The point is returned as the function value. kt is a pointer    */
+/*         to a CCkdtree (previously buildt by a call to CCkdtree_build)   */
+/*    int CCkdtree_fixed_radius_nearest (CCkdtree *kt, CCdatagroup *dat,   */
+/*           double *wcoord, int n, double rad,                            */
+/*           int (*doit_fn) (int, int, void *), void *pass_param)          */
+/*      ACTION: Calls the function doit_fn (n, a, void *), where a ranges  */
+/*              over all points within distance rad of the point n. The    */
+/*              void * field can be used to bundle a group of parmeters    */
+/*              into pass_param that will be passed to doit_fn.            */
+/*        -kt CANNOT be NULL.                                              */
+/*        -doit_fn can also call CCkdtree_fixed_radius_nearest (no globals */
+/*         are set by the function calls)                                  */
+/*        -pass_param can be NULL or used to point to a structure with     */
+/*         with parameters for doit_fn.                                    */
+/*    int CCkdtree_nearest_neighbor_tour (CCkdtree *kt, int ncount,        */
+/*            int start, CCdatagroup *dat, int *outcycle, double *val)     */
+/*        -kt can be NULL.                                                 */
+/*        -Node weights are not used.                                      */
+/*        -start is the starting node for the tour.                        */
+/*        -if outcycle is not NULL, then it should point to a array of     */
+/*         length at least ncount (allocated by the calling routine). The  */
+/*         cycle will be returned in the array in node node node format.   */
+/*        -the length of the tour is return in val.                        */
+/*    int CCkdtree_nearest_neighbor_2match (CCkdtree *kt, int ncount,      */
+/*           int start, CCdatagroup *dat, int *outmatch, double *val)      */
+/*        -Like CCkdtree_nearest_neighbor_tour. If outmatch is not NULL    */
+/*         then it should point to an array of length at leaast 2*ncount.  */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*       If memory is tight, use CCkdtree_node_k_nearest to get the edges  */
+/*    one node at a time. (CCkdtree_k_nearest () builds a hash table to    */
+/*    avoid duplicate edges, and it will use 8 * nedges bytes.)            */
+/*       CCkdtree_node_nearest returns the nearest point as the function   */
+/*    value; CCkdtree_fixed_radius_nearest returns 1 if doit_fn returns a  */
+/*    a nonzero value, otherwise it returns 0; all other routines return 0 */
+/*    if successful and 1 otherwise.                                       */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "machdefs.h"
+#include "util.h"
+#include "kdtree.h"
+
+#define BIGDOUBLE 100000000.0
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+#define NEAR_HEAP_CUTOFF 100  /* When to switch from list to heap       */
+                              /* On an RS6000, the heap started winning */
+                              /* at 100 (by 200 it was 3 times faster)  */
+
+typedef struct shortedge {
+    int end;
+    double length;
+} shortedge;
+
+typedef struct intptr {
+    int this;
+    struct intptr *next;
+} intptr;
+
+#define Fedgelen(n1, n2)                                                     \
+    (datw != (double *) NULL ?                                               \
+      CCutil_dat_edgelen ((n1), (n2), dat)                                   \
+            + datw[(n1)] + datw[(n2)] :                                      \
+      CCutil_dat_edgelen ((n1), (n2), dat))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    node_k_nearest_work (CCkdtree *thetree, CCdatagroup *dat, double *datw,
+        CCkdnode *p, CCdheap *near_heap, int *heap_names, int *heap_count,
+        int target, int num, shortedge *nearlist, double *worst_on_list,
+        CCkdbnds *box),
+    node_nearest_work (CCkdtree *thetree, CCdatagroup *dat, double *datw,
+         CCkdnode *p, int target, double *ndist, int *nnode);
+static int
+    run_kdtree_k_nearest (CCkdtree *kt, int ncount, int k, CCdatagroup *dat,
+         double *wcoord, int wantlist, int *ocount, int **olist, int doquad),
+    put_in_table (int i, int j, int *added, intptr **table),
+    q_run_it (CCkdtree *thetree, CCdatagroup *dat, double *datw, int *llist,
+         int *lcount, int *list, int target, int num, CCkdbnds *box),
+    run_kdtree_node_k_nearest (CCkdtree *thetree, CCdatagroup *dat,
+         double *datw,
+         int *list, int target, int num, CCkdbnds *box),
+    ball_in_bounds (CCdatagroup *dat, CCkdbnds *bnds, int n, double dist),
+    fixed_radius_nearest_work (CCkdtree *thetree, CCkdnode *p,
+         int (*doit_fn) (int, int, void *),
+         int target, double dist, CCdatagroup *dat, double *wcoord,
+         double xtarget, double ytarget, void *pass_param);
+
+#else
+
+static void
+    node_k_nearest_work (),
+    node_nearest_work ();
+static int
+    run_kdtree_k_nearest (),
+    put_in_table (),
+    q_run_it (),
+    run_kdtree_node_k_nearest (),
+    ball_in_bounds (),
+    fixed_radius_nearest_work ();
+
+#endif
+
+CC_PTR_ALLOC_ROUTINE (intptr, intptralloc, intptrchunklist, intptrfreelist)
+CC_PTR_FREE_ROUTINE (intptr, intptrfree, intptrfreelist)
+CC_PTR_FREE_WORLD_ROUTINE (intptr, intptrfree_world, intptrchunklist,
+        intptrfreelist)
+CC_PTR_LEAKS_ROUTINE (intptr, intptr_check_leaks, intptrchunklist,
+        intptrfreelist, this, int)
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_k_nearest (CCkdtree *kt, int ncount, int k, CCdatagroup *dat,
+        double *wcoord, int wantlist, int *ocount, int **olist)
+#else
+int CCkdtree_k_nearest (kt, ncount, k, dat, wcoord, wantlist, ocount, olist)
+CCkdtree *kt;
+int ncount, k;
+CCdatagroup *dat;
+double *wcoord;
+int wantlist, *ocount, **olist;
+#endif
+{
+    return run_kdtree_k_nearest (kt, ncount, k, dat, wcoord,
+                                 wantlist, ocount, olist, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_quadrant_k_nearest (CCkdtree *kt, int ncount, int k,
+        CCdatagroup *dat, double *wcoord, int wantlist, int *ocount,
+        int **olist)
+#else
+int CCkdtree_quadrant_k_nearest (kt, ncount, k, dat, wcoord, wantlist, ocount,
+        olist)
+CCkdtree *kt;
+int ncount, k;
+CCdatagroup *dat;
+double *wcoord;
+int wantlist, *ocount, **olist;
+#endif
+{
+    return run_kdtree_k_nearest (kt, ncount, k, dat, wcoord,
+                                 wantlist, ocount, olist, 1);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int run_kdtree_k_nearest (CCkdtree *kt, int ncount, int k,
+        CCdatagroup *dat, double *wcoord, int wantlist, int *ocount,
+        int **olist, int doquad)
+#else
+static int run_kdtree_k_nearest (kt, ncount, k, dat, wcoord, wantlist, ocount,
+        olist, doquad)
+CCkdtree *kt;
+int ncount, k;
+CCdatagroup *dat;
+double *wcoord;
+int wantlist, *ocount, **olist;
+int doquad;
+#endif
+{
+    int i, n;
+    intptr *ip, *ipnext;
+    int total, onlist;
+    CCkdtree localkt, *mykt;
+    int added, ntotal = 0;
+    int rval = 0;
+    int *list = (int *) NULL;
+    int goal = (doquad ? (4 * k) : k);
+    int newtree = 0;
+    intptr **table = (intptr **) NULL;
+
+    if (wcoord != (double *) NULL) {
+        for (i = 0; i < ncount; i++) {
+            if (wcoord[i] < -0.00000001) {
+                fprintf (stderr, "Cannot CCkdtree with negative node weights\n");
+                return 1;
+            }
+        }
+    }
+
+    if (wantlist) {
+        *ocount = 0;
+        *olist = (int *) NULL;
+    }
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, wcoord)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        mykt = &localkt;
+        newtree = 1;
+    } else {
+        mykt = kt;
+    }
+
+
+    table = CC_SAFE_MALLOC (ncount, intptr *);
+    if (!table) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++)
+        table[i] = (intptr *) NULL;
+    list = CC_SAFE_MALLOC (goal, int);
+    if (!list) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (n = 0; n < ncount; n++) {
+        if (doquad) {
+            if (CCkdtree_node_quadrant_k_nearest (mykt, ncount, n, k, dat,
+                       wcoord, list)) {
+                rval = 1;
+                goto CLEANUP;
+            }
+        } else {
+            if (CCkdtree_node_k_nearest (mykt, ncount, n, k, dat, wcoord,
+                                         list)) {
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        for (i = 0; i < goal; i++) {
+            if (list[i] != -1) {
+                if (put_in_table (n, list[i], &added, table))  {
+                    rval = 1;
+                    goto CLEANUP;
+                } else {
+                    ntotal += added;
+                }
+            }
+        }
+/*
+        if (n == 0) {
+            printf ("Neighbors of Node %d (%d, %d) :\n", n,
+                                      (int) dat->x[n], (int) dat->y[n]);
+            for (i = 0; i < goal; i++) {
+                if (list[i] != -1) {
+                    printf ("%d  %d (%d, %d)\n", list[i],
+                      CCutil_dat_edgelen (n, list[i], dat),
+                      (int) dat->x[list[i]], (int) dat->y[list[i]]);
+                }
+            }
+        }
+*/
+        if (n % 1000 == 999) {
+            printf (".");
+            fflush (stdout);
+        }
+    }
+    printf (" %d edges\n", ntotal);
+    fflush (stdout);
+
+    if (wantlist) {
+        int j = 0;
+        *olist = CC_SAFE_MALLOC (2 * ntotal, int);
+        if (!(*olist)) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        *ocount = ntotal;
+        for (i = 0; i < ncount; i++) {
+            for (ip = table[i]; ip; ip = ipnext) {
+                ipnext =  ip->next;
+                (*olist)[j++] = i;
+                (*olist)[j++] = ip->this;
+                intptrfree (ip);
+            }
+            table[i] = (intptr *) NULL;
+        }
+    } else {
+        for (i = 0; i < ncount; i++) {
+            for (ip = table[i]; ip; ip = ipnext) {
+                ipnext =  ip->next;
+                intptrfree (ip);
+            }
+            table[i] = (intptr *) NULL;
+        }
+    }
+    if (intptr_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding intptrs in kdnear\n",
+                 total - onlist);
+    }
+
+CLEANUP:
+
+    intptrfree_world ();
+    if (table)
+        CC_FREE (table, intptr *);
+    if (list)
+        CC_FREE (list, int);
+    if (newtree)
+        CCkdtree_free (&localkt);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int put_in_table (int i, int j, int *added, intptr **table)
+#else
+static int put_in_table (i, j, added, table)
+int i, j;
+int *added;
+intptr **table;
+#endif
+{
+    intptr *ip;
+
+    if (j < i) {
+        int temp;
+        SWAP(i, j, temp);
+    }
+
+    for (ip = table[i]; ip; ip = ip->next)
+        if (ip->this == j) {
+            *added = 0;
+            return 0;
+        }
+    ip = intptralloc ();
+    if (!ip) {
+        *added = 0;
+        return 1;
+    }
+    ip->this = j;
+    ip->next = table[i];
+    table[i] = ip;
+    *added = 1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_node_quadrant_k_nearest (CCkdtree *kt, int ncount, int n, int k,
+        CCdatagroup *dat, double *wcoord, int *list)
+#else
+int CCkdtree_node_quadrant_k_nearest (kt, ncount, n, k, dat, wcoord, list)
+CCkdtree *kt;
+int ncount, n, k;
+CCdatagroup *dat;
+double *wcoord;
+int *list;
+#endif
+{
+    CCkdbnds localbnds;
+    int i, lcount = 0;
+    int *llist = (int *) NULL;
+    int rval = 0;
+    CCkdtree localkt;
+    CCkdtree *thetree;
+    int newtree = 0;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, wcoord)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    llist = CC_SAFE_MALLOC (k, int);
+    if (!llist) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    localbnds.x[0] = dat->x[n];
+    localbnds.x[1] = BIGDOUBLE;
+    localbnds.y[0] = dat->y[n];
+    localbnds.y[1] = BIGDOUBLE;
+    if (q_run_it (thetree, dat, wcoord, llist, &lcount, list, n, k,
+                  &localbnds)) {
+        fprintf (stderr, "run_kdtree_node_k_nearest failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    localbnds.x[0] = dat->x[n];
+    localbnds.x[1] = BIGDOUBLE;
+    localbnds.y[0] = -BIGDOUBLE;
+    localbnds.y[1] = dat->y[n];
+    if (q_run_it (thetree, dat, wcoord, llist, &lcount, list, n, k,
+                  &localbnds)) {
+        fprintf (stderr, "run_kdtree_node_k_nearest failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    localbnds.x[0] = -BIGDOUBLE;
+    localbnds.x[1] = dat->x[n];
+    localbnds.y[0] = -BIGDOUBLE;
+    localbnds.y[1] = dat->y[n];
+    if (q_run_it (thetree, dat, wcoord, llist, &lcount, list, n, k,
+                  &localbnds)) {
+        fprintf (stderr, "run_kdtree_node_k_nearest failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    localbnds.x[0] = -BIGDOUBLE;
+    localbnds.x[1] = dat->x[n];
+    localbnds.y[0] = dat->y[n];
+    localbnds.y[1] = BIGDOUBLE;
+    if (q_run_it (thetree, dat, wcoord, llist, &lcount, list, n, k,
+                  &localbnds)) {
+        fprintf (stderr, "run_kdtree_node_k_nearest failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = lcount; i < (4 * k); i++)
+        list[i] = -1;
+
+CLEANUP:
+
+    CC_FREE (llist, int);
+    if (newtree)
+        CCkdtree_free (&localkt);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int q_run_it (CCkdtree *thetree, CCdatagroup *dat, double *datw,
+        int *llist, int *lcount, int *list, int target, int num, CCkdbnds *box)
+#else
+static int q_run_it (thetree, dat, datw, llist, lcount, list, target, num, box)
+CCkdtree *thetree;
+CCdatagroup *dat;
+double *datw;
+int *llist;
+int *lcount;
+int *list;
+int target;
+int num;
+CCkdbnds *box;
+#endif
+{
+    int i, j;
+
+    if (run_kdtree_node_k_nearest (thetree, dat, datw, llist, target, num,
+                                   box))
+        return 1;
+    for (i = 0; i < num; i++) {
+        if (llist[i] != -1) {
+            for (j = 0; j < *lcount; j++)
+                if (list[j] == llist[i])
+                    break;
+            if (j == *lcount)
+                list[(*lcount)++] = llist[i];
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_node_k_nearest (CCkdtree *kt, int ncount, int n, int k,
+        CCdatagroup *dat, double *wcoord, int *list)
+#else
+int CCkdtree_node_k_nearest (kt, ncount, n, k, dat, wcoord, list)
+CCkdtree *kt;
+int ncount, n, k;
+CCdatagroup *dat;
+double *wcoord;
+int *list;
+#endif
+{
+    CCkdtree localkt;
+    CCkdtree *thetree;
+    int newtree = 0;
+    int rval = 0;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, wcoord)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    rval = run_kdtree_node_k_nearest (thetree, dat, wcoord, list, n, k,
+                                      (CCkdbnds *) NULL);
+    if (newtree)
+        CCkdtree_free (&localkt);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int run_kdtree_node_k_nearest (CCkdtree *thetree, CCdatagroup *dat,
+        double *datw, int *list, int target, int num, CCkdbnds *box)
+#else
+static int run_kdtree_node_k_nearest (thetree, dat, datw, list, target, num,
+        box)
+CCkdtree *thetree;
+CCdatagroup *dat;
+double *datw;
+int *list;
+int target;
+int num;
+CCkdbnds *box;
+#endif
+{
+    int i;
+    CCkdnode *p, *lastp;
+    double diff;
+    CCdheap near_heap;
+    int *heap_names =  (int *) NULL;
+    int heap_count = 0;
+    shortedge *nearlist = (shortedge *) NULL;
+    double worst_on_list = BIGDOUBLE;
+
+    if (num >= NEAR_HEAP_CUTOFF) {
+        if (CCutil_dheap_init (&near_heap, num))
+            return 1;
+        heap_names = CC_SAFE_MALLOC (num, int);
+        if (!heap_names) {
+            CCutil_dheap_free (&near_heap);
+            return 1;
+        }
+        heap_count = 0;
+    } else {
+        nearlist = CC_SAFE_MALLOC (num + 1, shortedge);
+        if (!nearlist) {
+            CCutil_dheap_free (&near_heap);
+            CC_FREE (heap_names, int);
+            return 1;
+        }
+        for (i = 0; i < num; i++)
+            nearlist[i].length = BIGDOUBLE;
+        nearlist[num].length = -BIGDOUBLE;
+    }
+
+/*
+    To do top down search just use:
+
+        node_k_nearest_work (thetree->root);
+*/
+
+    p = thetree->bucketptr[target];
+    node_k_nearest_work (thetree, dat, datw, p, &near_heap, heap_names,
+                         &heap_count, target, num, nearlist, &worst_on_list,
+                         box);
+    while (1) {
+        lastp = p;
+        p = p->father;
+        if (p == (CCkdnode *) NULL)
+            break;
+        switch (p->cutdim) {
+        case 0:
+            diff = p->cutval - dat->x[target];
+            if (lastp == p->loson) {    /* So target is on low side */
+               if (worst_on_list > (double) ((int) diff))
+                   if (box == (CCkdbnds *) NULL || p->cutval <= box->x[1])
+                       node_k_nearest_work (thetree, dat, datw, p->hison,
+                              &near_heap, heap_names, &heap_count, target,
+                              num, nearlist, &worst_on_list, box);
+            } else {
+               if (worst_on_list > (double) ((int) -diff))
+                   if (box == (CCkdbnds *) NULL || p->cutval >= box->x[0])
+                       node_k_nearest_work (thetree, dat, datw, p->loson,
+                              &near_heap, heap_names, &heap_count, target,
+                              num, nearlist, &worst_on_list, box);
+            }
+            break;
+        case 1:
+            diff = p->cutval - dat->y[target];
+            if (lastp == p->loson) {
+               if (worst_on_list > (double) ((int) diff))
+                   if (box == (CCkdbnds *) NULL || p->cutval <= box->y[1])
+                       node_k_nearest_work (thetree, dat, datw, p->hison,
+                              &near_heap, heap_names, &heap_count, target,
+                              num, nearlist, &worst_on_list, box);
+            } else {
+               if (worst_on_list > (double) ((int) -diff))
+                   if (box == (CCkdbnds *) NULL || p->cutval >= box->y[0])
+                       node_k_nearest_work (thetree, dat, datw, p->loson,
+                              &near_heap, heap_names, &heap_count, target,
+                              num, nearlist, &worst_on_list, box);
+            }
+            break;
+        case 2:
+            if (lastp == p->loson) {
+                if (worst_on_list > p->cutval + datw[target])
+                    node_k_nearest_work (thetree, dat, datw, p->hison,
+                              &near_heap, heap_names, &heap_count, target,
+                              num, nearlist, &worst_on_list, box);
+            } else {
+                node_k_nearest_work (thetree, dat, datw, p->loson, &near_heap,
+                              heap_names, &heap_count, target, num, nearlist,
+                              &worst_on_list, box);
+            }
+            break;
+        }
+        if (datw == (double *) NULL && p->bnds &&
+               ball_in_bounds (dat, p->bnds, target, worst_on_list))
+              /* Doing extra check for box with quad-nearest appears to slow */
+              /* things down.                                                */
+            break;
+    }
+
+    if (num >= NEAR_HEAP_CUTOFF) {
+        if (heap_count < num) {
+            if (box == (CCkdbnds *) NULL) {
+                fprintf (stderr, "WARNING: There do not exist %d neighbors\n",
+                         num);
+            }
+            for (i = 0; i < heap_count; i++) {
+                list[i] = heap_names[i];
+            }
+            for (; i < num; i++)
+                list[i] = -1;
+        } else {
+            for (i = 0; i < num; i++)
+                list[i] = heap_names[i];
+        }
+    } else {
+        int ntot = 0;
+        for (i = 0; i < num; i++) {
+            if (nearlist[i].length < BIGDOUBLE)
+                list[ntot++] = nearlist[i].end;
+        }
+        if (ntot < num) {
+            if (box == (CCkdbnds *) NULL) {
+                fprintf (stderr, "WARNING: There do not exist %d neighbors\n",
+                         num);
+            }
+            for (i = ntot; i < num; i++)
+                list[i] = -1;
+        }
+    }
+
+    if (num >= NEAR_HEAP_CUTOFF) {
+        CC_FREE (heap_names, int);
+        CCutil_dheap_free (&near_heap);
+    } else {
+        CC_FREE (nearlist, shortedge);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void node_k_nearest_work (CCkdtree *thetree, CCdatagroup *dat,
+        double *datw, CCkdnode *p, CCdheap *near_heap, int *heap_names,
+        int *heap_count, int target, int num, shortedge *nearlist,
+        double *worst_on_list, CCkdbnds *box)
+#else
+static void node_k_nearest_work (thetree, dat, datw, p, near_heap, heap_names,
+        heap_count, target, num, nearlist, worst_on_list, box)
+CCkdtree *thetree;
+CCdatagroup *dat;
+double *datw;
+CCkdnode *p;
+CCdheap *near_heap;
+int *heap_names;
+int *heap_count;
+int target, num;
+shortedge *nearlist;
+double *worst_on_list;
+CCkdbnds *box;
+#endif
+{
+    int i, h, k;
+    double val, thisx, thisdist;
+
+    if (p->bucket) {
+        if (num >= NEAR_HEAP_CUTOFF) {
+            for (i = p->lopt; i <= p->hipt; i++) {
+                if (thetree->perm[i] != target) {
+                    if (box == (CCkdbnds *) NULL ||
+                       (dat->x[thetree->perm[i]] >= box->x[0] &&
+                        dat->x[thetree->perm[i]] <= box->x[1] &&
+                        dat->y[thetree->perm[i]] >= box->y[0] &&
+                        dat->y[thetree->perm[i]] <= box->y[1])) {
+                        thisdist = Fedgelen (thetree->perm[i], target);
+                        if (*heap_count < num) {
+                            near_heap->key[*heap_count] = -thisdist;
+                            heap_names[*heap_count] = thetree->perm[i];
+                            CCutil_dheap_insert (near_heap, *heap_count);
+                            (*heap_count)++;
+                        } else if (*worst_on_list > thisdist) {
+                            h = CCutil_dheap_deletemin (near_heap);
+                            heap_names[h] = thetree->perm[i];
+                            near_heap->key[h] = -thisdist;
+                            CCutil_dheap_insert (near_heap, h);
+                            h = CCutil_dheap_findmin (near_heap);
+                            *worst_on_list = -near_heap->key[h];
+                        }
+                    }
+                }
+            }
+        } else {
+            for (i = p->lopt; i <= p->hipt; i++) {
+                if (thetree->perm[i] != target) {
+                    if (box == (CCkdbnds *) NULL ||
+                       (dat->x[thetree->perm[i]] >= box->x[0] &&
+                        dat->x[thetree->perm[i]] <= box->x[1] &&
+                        dat->y[thetree->perm[i]] >= box->y[0] &&
+                        dat->y[thetree->perm[i]] <= box->y[1])) {
+                        thisdist = Fedgelen (thetree->perm[i], target);
+                        if (*worst_on_list > thisdist) {
+                            for (k = 0; nearlist[k+1].length > thisdist; k++) {
+                                nearlist[k].end = nearlist[k + 1].end;
+                                nearlist[k].length = nearlist[k + 1].length;
+                            }
+                            nearlist[k].length = thisdist;
+                            nearlist[k].end = thetree->perm[i];
+                            *worst_on_list = nearlist[0].length;
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        val = p->cutval;
+        switch (p->cutdim) {
+        case 0:
+            thisx = dat->x[target];
+            if (thisx < val) {
+                node_k_nearest_work (thetree, dat, datw, p->loson, near_heap,
+                        heap_names, heap_count, target, num, nearlist,
+                        worst_on_list, box);
+                /* Truncation for floating point coords */
+                if (*worst_on_list > (double) ((int) (val - thisx)))
+                    if (box == (CCkdbnds *) NULL || val >= box->x[0])
+                        node_k_nearest_work (thetree, dat, datw, p->hison,
+                               near_heap, heap_names, heap_count, target,
+                               num, nearlist, worst_on_list, box);
+            } else {
+                node_k_nearest_work (thetree, dat, datw, p->hison, near_heap,
+                               heap_names, heap_count, target, num, nearlist,
+                               worst_on_list, box);
+                if (*worst_on_list > (double) ((int) (thisx - val)))
+                    if (box == (CCkdbnds *) NULL || val <= box->x[1])
+                        node_k_nearest_work (thetree, dat, datw, p->loson,
+                               near_heap, heap_names, heap_count, target,
+                               num, nearlist, worst_on_list, box);
+            }
+            break;
+        case 1:
+            thisx = dat->y[target];
+            if (thisx < val) {
+                node_k_nearest_work (thetree, dat, datw, p->loson, near_heap,
+                               heap_names, heap_count, target, num, nearlist,
+                               worst_on_list, box);
+                if (*worst_on_list > (double) ((int) (val - thisx)))
+                    if (box == (CCkdbnds *) NULL || val >= box->y[0])
+                        node_k_nearest_work (thetree, dat, datw, p->hison,
+                               near_heap, heap_names, heap_count, target,
+                               num, nearlist, worst_on_list, box);
+            } else {
+                node_k_nearest_work (thetree, dat, datw, p->hison, near_heap,
+                               heap_names, heap_count, target, num, nearlist,
+                               worst_on_list, box);
+                if (*worst_on_list > (double) ((int) (thisx - val)))
+                    if (box == (CCkdbnds *) NULL || val <= box->y[1])
+                        node_k_nearest_work (thetree, dat, datw, p->loson,
+                               near_heap, heap_names, heap_count, target,
+                               num, nearlist, worst_on_list, box);
+            }
+            break;
+        case 2:
+            thisx = datw[target];
+            node_k_nearest_work (thetree, dat, datw, p->loson, near_heap,
+                               heap_names, heap_count, target, num, nearlist,
+                               worst_on_list, box);
+            if (*worst_on_list > val + thisx)
+                node_k_nearest_work (thetree, dat, datw, p->hison, near_heap,
+                               heap_names, heap_count, target, num, nearlist,
+                               worst_on_list, box);
+            break;
+        }
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_node_nearest (CCkdtree *kt, int n, CCdatagroup *dat,
+        double *wcoord)
+#else
+int CCkdtree_node_nearest (kt, n, dat, wcoord)
+CCkdtree *kt;
+int n;
+CCdatagroup *dat;
+double *wcoord;
+#endif
+{
+    CCkdnode *p, *lastp;
+    double diff;
+    double ndist = BIGDOUBLE;
+    int nnode;
+    CCkdtree *thetree = (CCkdtree *) NULL;
+
+    if (kt == (CCkdtree *) NULL) {
+        fprintf (stderr, "ERROR: kt cannot be NULL in CCkdtree_node_nearest)\n");
+        return n;
+    }
+
+    thetree = kt;
+
+    ndist = BIGDOUBLE;
+    nnode = n;
+
+/*
+    To do top down search just use:
+
+        node_nearest_work (kt->root);
+        return nnode;
+*/
+
+    p = kt->bucketptr[n];
+    node_nearest_work (thetree, dat, wcoord, p, n, &ndist, &nnode);
+    while (1) {
+        lastp = p;
+        p = p->father;
+        if (p == (CCkdnode *) NULL)
+            break;
+        switch (p->cutdim) {
+        case 0:
+            diff = p->cutval - dat->x[n];
+            if (lastp == p->loson) {
+                if (ndist > (double) ((int) diff))
+                   node_nearest_work (thetree, dat, wcoord, p->hison, n,
+                                      &ndist, &nnode);
+            } else {
+                if (ndist > (double) ((int) (-diff)))
+                   node_nearest_work (thetree, dat, wcoord, p->loson, n,
+                                      &ndist, &nnode);
+            }
+            break;
+        case 1:
+            diff = p->cutval - dat->y[n];
+            if (lastp == p->loson) {
+                if (ndist > (double) ((int) diff))
+                   node_nearest_work (thetree, dat, wcoord, p->hison, n,
+                                      &ndist, &nnode);
+            } else {
+                if (ndist > (double) ((int) (-diff)))
+                   node_nearest_work (thetree, dat, wcoord, p->loson, n,
+                                      &ndist, &nnode);
+            }
+            break;
+        case 2:
+            if (lastp == p->loson) {
+                if (ndist > p->cutval + wcoord[n])
+                    node_nearest_work (thetree, dat, wcoord, p->hison, n,
+                                      &ndist, &nnode);
+            } else {
+                node_nearest_work (thetree, dat, wcoord, p->loson, n,
+                                   &ndist, &nnode);
+            }
+            break;
+        }
+        if (wcoord == (double *) NULL && p->bnds &&
+               ball_in_bounds (dat, p->bnds, n, ndist))
+            break;
+    }
+    return nnode;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int ball_in_bounds (CCdatagroup *dat, CCkdbnds *bnds, int n, double dist)
+#else
+static int ball_in_bounds (dat, bnds, n, dist)
+CCdatagroup *dat;
+CCkdbnds *bnds;
+int n;
+double dist;
+#endif
+{
+    if ((double) ((int) (dat->x[n] - bnds->x[0])) < dist ||
+        (double) ((int) (bnds->x[1] - dat->x[n])) < dist ||
+        (double) ((int) (dat->y[n] - bnds->y[0])) < dist ||
+        (double) ((int) (bnds->y[1] - dat->y[n])) < dist)
+        return 0;
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void node_nearest_work (CCkdtree *thetree, CCdatagroup *dat,
+        double *datw, CCkdnode *p, int target, double *ndist, int *nnode)
+#else
+static void node_nearest_work (thetree, dat, datw, p, target, ndist, nnode)
+CCkdtree *thetree;
+CCdatagroup *dat;
+double *datw;
+CCkdnode *p;
+int target;
+double *ndist;
+int *nnode;
+#endif
+{
+    int i;
+    double val, thisx, thisdist;
+
+    if (!p->empty) {
+        if (p->bucket) {
+            for (i = p->lopt; i <= p->hipt; i++) {
+                if (thetree->perm[i] != target) {
+                    thisdist = Fedgelen (thetree->perm[i], target);
+                    if (*ndist > thisdist) {
+                        *ndist = thisdist;
+                        *nnode = thetree->perm[i];
+                    }
+                }
+            }
+        } else {
+            val = p->cutval;
+            switch (p->cutdim) {
+            case 0:
+                thisx = dat->x[target];
+                if (thisx < val) {
+                    node_nearest_work (thetree, dat, datw, p->loson, target,
+                                       ndist, nnode);
+                    if (*ndist >  (double) ((int) (val - thisx)))
+                        node_nearest_work (thetree, dat, datw, p->hison,
+                                       target, ndist, nnode);
+                } else {
+                    node_nearest_work (thetree, dat, datw, p->hison, target,
+                                       ndist, nnode);
+                    if (*ndist > (double) ((int) (thisx - val)))
+                        node_nearest_work (thetree, dat, datw, p->loson,
+                                       target, ndist, nnode);
+                }
+                break;
+            case 1:
+                thisx = dat->y[target];
+                if (thisx < val) {
+                    node_nearest_work (thetree, dat, datw, p->loson, target,
+                                       ndist, nnode);
+                    if (*ndist >  (double) ((int) (val - thisx)))
+                        node_nearest_work (thetree, dat, datw, p->hison,
+                                       target, ndist, nnode);
+                } else {
+                    node_nearest_work (thetree, dat, datw, p->hison, target,
+                                       ndist, nnode);
+                    if (*ndist > (double) ((int) (thisx - val)))
+                        node_nearest_work (thetree, dat, datw, p->loson,
+                                       target, ndist, nnode);
+                }
+                break;
+            case 2:
+                thisx = datw[target];
+                node_nearest_work (thetree, dat, datw, p->loson, target, ndist,
+                                       nnode);
+                if (*ndist > val + thisx)
+                    node_nearest_work (thetree, dat, datw, p->hison, target,
+                                       ndist, nnode);
+                break;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_fixed_radius_nearest (CCkdtree *kt, CCdatagroup *dat,
+        double *datw, int n, double rad, int (*doit_fn) (int, int, void *),
+        void *pass_param)
+#else
+int CCkdtree_fixed_radius_nearest (kt, dat, datw, n, rad, doit_fn, pass_param)
+CCkdtree  *kt;
+CCdatagroup *dat;
+double *datw;
+int n;
+double rad;
+int (*doit_fn)();
+void *pass_param;
+#endif
+{
+    CCkdnode *p, *lastp;
+    double dist, diff, xtarget, ytarget;
+    int target;
+
+    if (kt == (CCkdtree *) NULL) {
+        fprintf (stderr, "ERROR: fixed_radius_nearest needs a CCkdtree\n");
+        return 0;
+    }
+
+    dist = (double) rad;
+    target = n;
+    xtarget = dat->x[target];
+    ytarget = dat->y[target];
+
+    p = kt->bucketptr[target];
+    if (fixed_radius_nearest_work (kt, p, doit_fn, target, dist, dat, datw,
+                                   xtarget, ytarget, pass_param))
+        return 1;
+
+    if (datw) {
+        double wdist = dist - datw[target];
+        while (1) {
+            lastp = p;
+            p = p->father;
+            if (p == (CCkdnode *) NULL)
+                return 0;
+            if (p->cutdim == 0)
+                diff = p->cutval - xtarget;
+            else if (p->cutdim == 1)
+                diff = p->cutval - ytarget;
+            else
+                diff = p->cutval;
+            if (lastp == p->loson) {
+                if (wdist > (double) ((int) diff)) {
+                    if (fixed_radius_nearest_work (kt, p->hison, doit_fn,
+                              target, dist, dat, datw, xtarget, ytarget,
+                              pass_param))
+                        return 1;
+                }
+            } else {
+                if (wdist > (double) ((int) -diff)) {
+                    if (fixed_radius_nearest_work (kt, p->loson, doit_fn,
+                              target, dist, dat, datw, xtarget, ytarget,
+                              pass_param))
+                        return 1;
+                }
+            }
+            if (p->bnds &&  /* ball_in_bounds */
+              !((double) ((int) (xtarget - p->bnds->x[0])) < wdist ||
+                (double) ((int) (p->bnds->x[1] - xtarget)) < wdist ||
+                (double) ((int) (ytarget - p->bnds->y[0])) < wdist ||
+                (double) ((int) (p->bnds->y[1] - ytarget)) < wdist))
+                return 0;
+        }
+    } else {
+        while (1) {
+            lastp = p;
+            p = p->father;
+            if (p == (CCkdnode *) NULL)
+                return 0;
+            if (p->cutdim == 0)
+                diff = p->cutval - xtarget;
+            else
+                diff = p->cutval - ytarget;
+
+            if (lastp == p->loson) {
+                if (dist > (double) ((int) diff)) {
+                    if (fixed_radius_nearest_work (kt, p->hison, doit_fn,
+                              target, dist, dat, datw, xtarget, ytarget,
+                              pass_param))
+                        return 1;
+                }
+            } else {
+                if (dist > (double) ((int) -diff) || p->cutdim == 2) {
+                    if (fixed_radius_nearest_work (kt, p->loson, doit_fn,
+                              target, dist, dat, datw, xtarget, ytarget,
+                              pass_param))
+                        return 1;
+                }
+            }
+            if (p->bnds &&  /* ball_in_bounds */
+                !((double) ((int) (xtarget - p->bnds->x[0])) < dist ||
+                  (double) ((int) (p->bnds->x[1] - xtarget)) < dist ||
+                  (double) ((int) (ytarget - p->bnds->y[0])) < dist ||
+                  (double) ((int) (p->bnds->y[1] - ytarget)) < dist))
+                return 0;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int fixed_radius_nearest_work (CCkdtree *thetree, CCkdnode *p,
+        int (*doit_fn) (int, int, void *), int target, double dist,
+        CCdatagroup *dat, double *datw,  double xtarget, double ytarget,
+        void *pass_param)
+#else
+static int fixed_radius_nearest_work (thetree, p, doit_fn, target, dist, dat,
+        datw, xtarget, ytarget, pass_param)
+CCkdtree *thetree;
+CCkdnode *p;
+int (*doit_fn)();
+int target;
+double dist;
+CCdatagroup *dat;
+double *datw;
+double xtarget, ytarget;
+void *pass_param;
+#endif
+{
+    int i, c;
+    double val, thisx, thisdist;
+
+    if (p->empty)
+        return 0;
+
+    if (p->bucket) {
+        for (i = p->lopt; i <= p->hipt; i++) {
+            c = thetree->perm[i];
+            if (c != target) {
+                thisdist = Fedgelen (c, target);
+                if (thisdist < dist) {
+                    if (doit_fn (target, c, pass_param)) {
+                        return 1;
+                    }
+                }
+            }
+        }
+        return 0;
+    } else {
+        if (datw) {
+            double wdist = dist - datw[target];
+
+            val = p->cutval;
+            switch (p->cutdim) {
+            case 0:
+                thisx = xtarget;
+                break;
+            case 1:
+                thisx = ytarget;
+                break;
+            case 2:
+                if (fixed_radius_nearest_work (thetree, p->loson, doit_fn,
+                     target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                    return 1;
+                }
+                if (p->cutval <= wdist) {
+                    if (fixed_radius_nearest_work (thetree, p->hison, doit_fn,
+                         target, dist, dat, datw, xtarget, ytarget,
+                         pass_param)) {
+                        return 1;
+                    }
+                }
+                return 0;
+            default:
+                return 0;
+            }
+            if (thisx < val) {
+                if (fixed_radius_nearest_work (thetree, p->loson, doit_fn,
+                     target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                    return 1;
+                }
+                if (wdist > (double) ((int) (val - thisx))) {
+                    if (fixed_radius_nearest_work (thetree, p->hison, doit_fn,
+                       target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                        return 1;
+                    }
+                }
+            } else {
+                if (fixed_radius_nearest_work (thetree, p->hison, doit_fn,
+                     target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                    return 1;
+                }
+                if (wdist > (double) ((int) (thisx - val))) {
+                    if (fixed_radius_nearest_work (thetree, p->loson, doit_fn,
+                       target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                        return 1;
+                    }
+                }
+            }
+        } else {
+            val = p->cutval;
+            switch (p->cutdim) {
+            case 0:
+                thisx = xtarget;
+                break;
+            case 1:
+                thisx = ytarget;
+                break;
+            case 2:
+            default:
+                fprintf (stderr, "ERROR: split on w without node weights\n");
+                return 0;
+            }
+            if (thisx < val) {
+                if (fixed_radius_nearest_work (thetree, p->loson, doit_fn,
+                     target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                    return 1;
+                }
+                if (dist > (double) ((int) (val - thisx))) {
+                    if (fixed_radius_nearest_work (thetree, p->hison, doit_fn,
+                       target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                        return 1;
+                    }
+                }
+            } else {
+                if (fixed_radius_nearest_work (thetree, p->hison, doit_fn,
+                     target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                    return 1;
+                }
+                if (dist > (double) ((int) (thisx - val))) {
+                    if (fixed_radius_nearest_work (thetree, p->loson, doit_fn,
+                       target, dist, dat, datw, xtarget, ytarget, pass_param)) {
+                        return 1;
+                    }
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_nearest_neighbor_tour (CCkdtree *kt, int ncount, int start,
+        CCdatagroup *dat, int *outcycle, double *val)
+#else
+int CCkdtree_nearest_neighbor_tour (kt, ncount, start, dat, outcycle, val)
+CCkdtree *kt;
+int ncount, start;
+CCdatagroup *dat;
+int *outcycle;
+double *val;
+#endif
+{
+    double len;
+    int i, current, next;
+    CCkdtree localkt, *mykt;
+    int newtree = 0;
+
+    if (ncount < 3) {
+        fprintf (stderr, "Cannot find tour in an %d node graph\n", ncount);
+        return 1;
+    }
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        mykt = &localkt;
+        newtree = 1;
+    } else {
+        mykt = kt;
+    }
+
+    /*
+        printf ("Grow nearest neighbor tour from node %d\n", start);
+        fflush (stdout);
+    */
+
+    len = 0.0;
+    current = start;
+    if (outcycle != (int *) NULL)
+        outcycle[0] = start;
+    for (i = 1; i < ncount; i++) {
+        CCkdtree_delete (mykt, current);
+        next = CCkdtree_node_nearest (mykt, current, dat, (double *) NULL);
+        if (outcycle != (int *) NULL)
+            outcycle [i] = next;
+        len += (double) CCutil_dat_edgelen (current, next, dat);
+        current = next;
+    }
+    len += (double) CCutil_dat_edgelen (current, start, dat);
+    *val = len;
+    if (newtree)
+        CCkdtree_free (&localkt);
+    else
+        CCkdtree_undelete_all (kt, ncount);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_nearest_neighbor_2match (CCkdtree *kt, int ncount, int start,
+        CCdatagroup *dat, int *outmatch, double *val)
+#else
+int CCkdtree_nearest_neighbor_2match (kt, ncount, start, dat, outmatch, val)
+CCkdtree *kt;
+int ncount, start;
+CCdatagroup *dat;
+int *outmatch;
+double *val;
+#endif
+{
+    double len;
+    int i, j, cur, next;
+    CCkdtree localkt, *mykt;
+    double szeit;
+    int count = 0, cyccount = 0;
+    char *mark = (char *) NULL;
+    int newtree = 0;
+    int rval = 0;
+
+    if (ncount < 3) {
+        fprintf (stderr, "Cannot find 2-matching in an %d node graph\n",
+                 ncount);
+        return 1;
+    }
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        mykt = &localkt;
+        newtree = 1;
+    } else {
+        mykt = kt;
+    }
+
+    mark = CC_SAFE_MALLOC (ncount, char);
+    if (!mark) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0 ; i < ncount; i++)
+        mark[i] = 0;
+
+    printf ("Grow nearest neighbor 2-matching from node %d\n", start);
+    fflush (stdout);
+    szeit = CCutil_zeit ();
+    len = 0.0;
+
+    while (count < ncount) {
+        for (j = start; j < ncount && mark[j]; j++);
+        if (j == ncount) {
+            for (j = 0; j < start && mark[j]; j++);
+            if (j == start) {
+                fprintf (stderr, "ERROR in near-2match\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        start = j;
+        mark[start] = 1;
+        CCkdtree_delete (mykt, start);
+        next = CCkdtree_node_nearest (mykt, start, dat, (double *) NULL);
+        mark[next] = 1;
+        len += (double) CCutil_dat_edgelen (start, next, dat);
+        if (outmatch != (int *) NULL) {
+            outmatch[2 * count] = start;
+            outmatch[(2 * count) + 1] = next;
+        }
+        count++;
+        CCkdtree_delete (mykt, next);
+        cur = CCkdtree_node_nearest (mykt, next, dat, (double *) NULL);
+        len += (double) CCutil_dat_edgelen (next, cur, dat);
+        if (outmatch != (int *) NULL) {
+            outmatch[2 * count] = next;
+            outmatch[(2 * count) + 1] = cur;
+        }
+        count++;
+        CCkdtree_undelete (mykt, start);
+        while (cur != start && count < ncount - 3) {
+            mark[cur] = 1;
+            CCkdtree_delete (mykt, cur);
+            next = CCkdtree_node_nearest (mykt, cur, dat, (double *) NULL);
+            len += (double) (*CCutil_dat_edgelen) (cur, next, dat);
+            if (outmatch != (int *) NULL) {
+                outmatch[2 * count] = cur;
+                outmatch[(2 * count) + 1] = next;
+            }
+            count++;
+            cur = next;
+        }
+        CCkdtree_delete (mykt, start);
+
+        if (cur != start) {   /* Not enough nodes for another circuit */
+            while (count < ncount - 1) {
+                mark[cur] = 1;
+                CCkdtree_delete (mykt, cur);
+                next = CCkdtree_node_nearest (mykt, cur, dat, (double *) NULL);
+                len += (double) CCutil_dat_edgelen (cur, next, dat);
+                if (outmatch != (int *) NULL) {
+                    outmatch[2 * count] = cur;
+                    outmatch[(2 * count) + 1] = next;
+                }
+                count++;
+                cur = next;
+            }
+            len += (double) CCutil_dat_edgelen (cur, start, dat);
+            if (outmatch != (int *) NULL) {
+                outmatch[2 * count] = cur;
+                outmatch[(2 * count) + 1] = start;
+            }
+            count++;
+        }
+        cyccount++;
+    }
+
+    *val = len;
+    printf ("%d cycles in 2-matching\n", cyccount);
+    printf ("Running time for Nearest Neighbor 2-match: %.2f\n",
+                                                  CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    else
+        CCkdtree_undelete_all (kt, ncount);
+    if (mark)
+        CC_FREE (mark, char);
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/KDTREE/kdspan.c b/contrib/blossom/concorde97/KDTREE/kdspan.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b9256fc058b323e6ee1136697913aa5e0dceebd
--- /dev/null
+++ b/contrib/blossom/concorde97/KDTREE/kdspan.c
@@ -0,0 +1,1052 @@
+/***************************************************************************/
+/*                                                                         */
+/*            KD-TREE BASED MIN SPANNING TREE AND GREEDY TOUR              */
+/*                                                                         */
+/*  (Based on Jon Bentley's paper "Fast algorithms for geometric           */
+/*   traveling salesman problems", ORSA Journal on Computing.)             */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook (mainly from Jon      */
+/*               Bentley's paper)                                          */
+/*  Date: February 16, 1995 (cofeb16)                                      */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCkdtree_prim_spanningtree (CCkdtree *kt, int ncount,            */
+/*            CCdatagroup *dat, double *wcoord, int *outtree, double *val) */
+/*      RETURNS a min weight spanning tree.                                */
+/*        -kt is a pointer to a CCkdtree built by a call to CCkdtree_build.*/
+/*         If kt is NULL, then CCkdtree_build will be called.              */
+/*        -If wcoord is not NULL, then the array should have nonnegative   */
+/*         values. The code will use Held-Karp style distances.            */
+/*        -If outtree is non NULL, it should point to an array of length   */
+/*         at least 2*ncount - 2. The edges in the min spanning tree will  */
+/*         be returned in the array in end end format.                     */
+/*        -The length of the min tree is returned in val.                  */
+/*    int CCkdtree_greedy_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,*/
+/*           int *outcycle, double *val)                                   */
+/*       RETURNS a greedy tour. (No randomization (expect in building the  */
+/*         CCkdtree) so there is no point in calling this more than once)  */
+/*        -kt can be NULL.                                                 */
+/*        -Does not use node weights.                                      */
+/*        -If outcycle is non NUL, it should point to an array of length   */
+/*         at least ncount. The cycle will be returned in node node node   */
+/*         format.                                                         */
+/*    int CCkdtree_far_add_tour (CCkdtree *kt, int ncount,                 */
+/*            CCdatagroup *dat, int *outcycle, double *val, int start)     */
+/*       RETURNS a farthest addition tour, beginning with node start.      */
+/*        -like CCkdtree_greedy_tour.                                      */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*       Uses around 20n bytes of memory for an n node problem (plus the   */
+/*    memory for a CCkdtree), for a spanning tree, and 33n for a greedy    */
+/*    tour. Both functions return 0 if successful, and nonzero if they     */
+/*    failed (usually due to running out of memory.                        */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "kdtree.h"
+
+typedef struct faobj {
+   struct faobj *next;
+   struct faobj *prev;
+   int           name;
+} faobj;
+
+#define Fedgelen(n1, n2)                                                     \
+    (datw != (double *) NULL ?                                               \
+      CCutil_dat_edgelen ((n1), (n2), dat)                                   \
+            + datw[(n1)] + datw[(n2)] :                                      \
+      CCutil_dat_edgelen ((n1), (n2), dat))
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    add_primheap (CCdheap *prim_heap, CCkdtree *kt, int n, int *neighbor,
+          CCdatagroup *dat, double *datw),
+    greedy_add_primheap (CCdheap *prim_heap, CCkdtree *kt, int n, int *neighbor,
+          CCdatagroup *dat),
+    fa_add_primheap (CCdheap *prim_heap, int n, int len);
+
+#ifdef USE_SPACEFILL
+static int
+    space_fill_curve (int ncount, CCdatagroup *dat, int *outcyc, double *len);
+#endif
+
+#else
+
+static void
+    add_primheap (),
+    greedy_add_primheap (),
+    fa_add_primheap ();
+
+#ifdef USE_SPACEFILL
+static int
+    space_fill_curve (ncount, dat, outcyc, len);
+#endif
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_prim_spanningtree (CCkdtree *kt, int ncount, CCdatagroup *dat,
+           double *wcoord, int *outtree, double *val)
+#else
+int CCkdtree_prim_spanningtree (kt, ncount, dat, wcoord, outtree, val)
+CCkdtree *kt;
+int ncount;
+CCdatagroup *dat;
+double *wcoord;
+int *outtree;
+double *val;
+#endif
+{
+    CCkdtree localkt, *thetree;
+    double len;
+    int i, n;
+    int klist = 0;
+    int newtree = 0;
+    int *neighbor = (int *) NULL;
+    CCdheap prim_heap;
+
+    if (wcoord != (double *) NULL) {
+        for (i = 0; i < ncount; i++) {
+            if (wcoord[i] < -0.00000001) {
+                fprintf (stderr, "Cannot kdtree with negative node weights\n");
+                return 1;
+            }
+        }
+    }
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, wcoord)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    neighbor = CC_SAFE_MALLOC (ncount, int);
+    if (!neighbor)
+        return 1;
+
+    printf ("Find minimum weight spanning tree\n");
+    fflush (stdout);
+
+    CCutil_dheap_init (&prim_heap, ncount);
+    for (i = 0; i < ncount; i++)
+        neighbor[i] = -1;
+
+    CCkdtree_delete (thetree, 0);
+    add_primheap (&prim_heap, thetree, 0, neighbor, dat, wcoord);
+
+    len = 0.0;
+    for (i = 1; i < ncount; i++) {
+        if (i % 10000 == 1) {
+            printf (".");
+            fflush (stdout);
+        }
+        while (1) {
+            n = CCutil_dheap_deletemin (&prim_heap);
+            if (neighbor[neighbor[n]] == -1)
+                break;
+            else
+                add_primheap (&prim_heap, thetree, n, neighbor, dat, wcoord);
+        }
+        if (outtree) {
+            outtree[klist++] = n;
+            outtree[klist++] = neighbor[n];
+        }
+        len += prim_heap.key[n];
+        CCkdtree_delete (thetree, neighbor[n]);
+        add_primheap (&prim_heap, thetree, neighbor[n], neighbor, dat, wcoord);
+        add_primheap (&prim_heap, thetree, n, neighbor, dat, wcoord);
+    }
+    *val = len;
+    printf ("\nLength of Spanning Tree: %.2f\n", len);
+    if (wcoord != (double *) NULL) {
+        double tval = 0.0;
+        for (i = 0; i < ncount; i++)
+            tval += wcoord[i];
+        tval *= 2.0;
+        printf ("TSP BOUND: %.2f\n", len - tval);
+    }
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    else
+        CCkdtree_undelete_all (kt, ncount);
+    CCutil_dheap_free (&prim_heap);
+    if (neighbor) {
+        CC_FREE (neighbor, int);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void add_primheap (CCdheap *prim_heap, CCkdtree *kt, int n,
+        int *neighbor, CCdatagroup *dat, double *datw)
+#else
+static void add_primheap (prim_heap, kt, n, neighbor, dat, datw)
+CCdheap *prim_heap;
+CCkdtree *kt;
+int n;
+int *neighbor;
+CCdatagroup *dat;
+double *datw;
+#endif
+{
+    neighbor[n] = CCkdtree_node_nearest (kt, n, dat, datw);
+    prim_heap->key[n] = (double) Fedgelen (n, neighbor[n]);
+    CCutil_dheap_insert (prim_heap, n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_greedy_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+                        int *outcycle, double *val)
+#else
+int CCkdtree_greedy_tour (kt, ncount, dat, outcycle, val)
+CCkdtree *kt;
+int ncount;
+CCdatagroup *dat;
+int *outcycle;
+double *val;
+#endif
+{
+    CCkdtree localkt, *thetree;
+    double len;
+    int i, x, y;
+    char *degree = (char *) NULL;
+    int *tail = (int *) NULL;
+    int *tcyc = (int *) NULL;
+    int tcount = 0;
+    int rval = 0;
+    int newtree = 0;
+    int *neighbor = (int *) NULL;
+    CCdheap prim_heap;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    printf ("Grow a greedy tour \n");
+    fflush (stdout);
+
+    if (outcycle) {
+        tcyc = CC_SAFE_MALLOC (2 * ncount, int);
+        if (!tcyc) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    neighbor = CC_SAFE_MALLOC (ncount, int);
+    if (!neighbor) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    degree = CC_SAFE_MALLOC (ncount, char);
+    if (!degree) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    tail = CC_SAFE_MALLOC (ncount, int);
+    if (!tail) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    if (CCutil_dheap_init (&prim_heap, ncount)) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        degree[i] = 0;
+        tail[i] = -1;
+        greedy_add_primheap (&prim_heap, thetree, i, neighbor, dat);
+    }
+
+    len = 0.0;
+    for (i = 1; i < ncount; i++) {
+        while (1) {
+            x = CCutil_dheap_deletemin (&prim_heap);
+            if (degree[x] == 2)
+                continue;
+            y = neighbor[x];
+            if (degree[y] < 2 && y != tail[x])
+                break;          /* add (x, y) to the tour */
+            if (tail[x] != -1) {
+                CCkdtree_delete (thetree, tail[x]);
+                greedy_add_primheap (&prim_heap, thetree, x, neighbor, dat);
+                CCkdtree_undelete (thetree, tail[x]);
+            } else {
+                greedy_add_primheap (&prim_heap, thetree, x, neighbor, dat);
+            }
+        }
+        if (tcyc) {
+            tcyc[tcount++] = x;
+            tcyc[tcount++] = y;
+        }
+        len += prim_heap.key[x];
+        (degree[x])++;
+        if (degree[x] == 2)
+            CCkdtree_delete (thetree, x);
+        (degree[y])++;
+        if (degree[y] == 2)
+            CCkdtree_delete (thetree, y);
+        if (tail[x] == -1) {
+            if (tail[y] == -1) {
+                tail[x] = y;
+                tail[y] = x;
+            } else {
+                tail[x] = tail[y];
+                tail[tail[y]] = x;
+            }
+        } else if (tail[y] == -1) {
+            tail[tail[x]] = y;
+            tail[y] = tail[x];
+        } else {
+            tail[tail[x]] = tail[y];
+            tail[tail[y]] = tail[x];
+        }
+        if (degree[x] == 1) {
+            CCkdtree_delete (thetree, tail[x]);
+            greedy_add_primheap (&prim_heap, thetree, x, neighbor, dat);
+            CCkdtree_undelete (thetree, tail[x]);
+        }
+        if (i % 10000 == 9999) {
+            printf (".");
+            fflush (stdout);
+        }
+    }
+    for (x = 0; degree[x] != 1; x++);
+    for (y = x + 1; degree[y] != 1; y++);
+    if (tcyc) {
+        tcyc[tcount++] = x;
+        tcyc[tcount++] = y;
+    }
+    len += (double) CCutil_dat_edgelen (x, y, dat);
+    *val = len;
+    if (ncount >= 10000)
+        printf ("\n");
+    printf ("Length of Greedy Tour: %.2f\n", len);
+    CCutil_dheap_free (&prim_heap);
+
+    if (tcyc) {
+        if (CCutil_edge_to_cycle (ncount, tcyc, outcycle)) {
+            fprintf (stderr, "ERROR: greedy tour is not a tour\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+CLEANUP:
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    else
+        CCkdtree_undelete_all (kt, ncount);
+    if (tcyc)
+        CC_FREE (tcyc, int);
+    if (neighbor)
+        CC_FREE (neighbor, int);
+    if (degree)
+        CC_FREE (degree, char);
+    if (tail)
+        CC_FREE (tail, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void greedy_add_primheap (CCdheap *prim_heap, CCkdtree *kt, int n,
+        int *neighbor, CCdatagroup *dat)
+#else
+static void greedy_add_primheap (prim_heap, kt, n, neighbor, dat)
+CCdheap *prim_heap;
+CCkdtree *kt;
+int n;
+int *neighbor;
+CCdatagroup *dat;
+#endif
+{
+    CCkdtree_delete (kt, n);
+    neighbor[n] = CCkdtree_node_nearest (kt, n, dat, (double *) NULL);
+    CCkdtree_undelete (kt, n);
+    prim_heap->key[n] = (double) CCutil_dat_edgelen (n, neighbor[n], dat);
+    CCutil_dheap_insert (prim_heap, n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_far_add_tour (CCkdtree *kt, int ncount, int start,
+        CCdatagroup *dat, int *outcycle, double *val)
+#else
+int CCkdtree_far_add_tour (kt, ncount, start, dat, outcycle, val)
+CCkdtree *kt;
+int ncount;
+int start;
+CCdatagroup *dat;
+int *outcycle;
+double *val;
+#endif
+{
+    CCkdtree localkt, *thetree;
+    double len = 0.0;
+    int i, x, y, oldx;
+    int rval = 0;
+    int newtree = 0;
+    faobj *supply = (faobj *) NULL;
+    faobj *fa, *fx;
+    int *neighbor = (int *) NULL;
+    CCdheap prim_heap;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    printf ("Grow a farthest addition tour from node %d \n", start);
+    fflush (stdout);
+
+    neighbor = CC_SAFE_MALLOC (ncount, int);
+    if (!neighbor) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    supply  = CC_SAFE_MALLOC (ncount, faobj);
+    if (!supply) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    if (CCutil_dheap_init (&prim_heap, ncount)) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    CCkdtree_delete_all (thetree, ncount);
+    CCkdtree_undelete (thetree, start);
+
+    for (i = 0; i < ncount; i++) {
+        if (i != start) {
+            neighbor[i] = start;
+            fa_add_primheap (&prim_heap, i, CCutil_dat_edgelen (i, start, dat));
+        }
+    }
+
+    fa = &(supply[start]);
+    fa->prev = fa;
+    fa->next = fa;
+    fa->name = start;
+
+    y = CCutil_dheap_deletemin (&prim_heap);
+    CCkdtree_undelete (thetree, y);
+    fa = &(supply[y]);
+    fa->name = y;
+    fa->prev = &(supply[start]);
+    fa->next = &(supply[start]);
+    supply[start].next = fa;
+    supply[start].prev = fa;
+
+    for (i = 2; i < ncount; i++) {
+        while (1) {
+            y = CCutil_dheap_deletemin (&prim_heap);
+            oldx = neighbor[y];
+            x = CCkdtree_node_nearest (thetree, y, dat, (double *) NULL);
+            if (x == oldx)
+                break;
+            fa_add_primheap (&prim_heap, y, CCutil_dat_edgelen (x, y, dat));
+            neighbor[y] = x;
+        }
+        CCkdtree_undelete (thetree, y);
+
+        fa = &(supply[y]);
+        fa->name = y;
+        fx = &(supply[x]);
+        if (CCutil_dat_edgelen (y, fx->next->name, dat) -
+            CCutil_dat_edgelen (x, fx->next->name, dat) <=
+            CCutil_dat_edgelen (y, fx->prev->name, dat) -
+            CCutil_dat_edgelen (x, fx->prev->name, dat)) {
+            fa->prev = fx;
+            fa->next = fx->next;
+            fa->next->prev = fa;
+            fx->next = fa;
+        } else {
+            fa->next = fx;
+            fa->prev = fx->prev;
+            fa->prev->next = fa;
+            fx->prev = fa;
+        }
+        if (i % 10000 == 9999) {
+            printf (".");
+            fflush (stdout);
+        }
+    }
+
+    fx = fa = &(supply[start]);
+    if (outcycle) {
+        i = 0;
+        do {
+            outcycle[i++] = fa->name;
+            len += (double) CCutil_dat_edgelen (fa->name, fa->next->name, dat);
+            fa = fa->next;
+        } while (fa != fx);
+
+    } else {
+        do {
+            len += (double) CCutil_dat_edgelen (fa->name, fa->next->name, dat);
+            fa = fa->next;
+        } while (fa != fx);
+    }
+
+    *val = len;
+    if (ncount >= 10000)
+        printf ("\n");
+    printf ("Length of Farthest Addition Tour: %.2f\n", len);
+    CCutil_dheap_free (&prim_heap);
+
+CLEANUP:
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    else
+        CCkdtree_undelete_all (kt, ncount);
+    if (neighbor)
+        CC_FREE (neighbor, int);
+    if (supply)
+        CC_FREE (supply, faobj);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fa_add_primheap (CCdheap *prim_heap, int n, int len)
+#else
+static void fa_add_primheap (prim_heap, n, len)
+CCdheap *prim_heap;
+int n;
+int len;
+#endif
+{
+    prim_heap->key[n] = (double) -len;
+    CCutil_dheap_insert (prim_heap, n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_qboruvka_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+        int *outcycle, double *val)
+#else
+int CCkdtree_qboruvka_tour (kt, ncount, dat, outcycle, val)
+CCkdtree *kt;
+int ncount;
+CCdatagroup *dat;
+int *outcycle;
+double *val;
+#endif
+{
+    CCkdtree localkt, *thetree;
+    double len;
+    int i, x, y;
+    char *degree = (char *) NULL;
+    int *tail = (int *) NULL;
+    int *tcyc = (int *) NULL;
+    int tcount = 0, count;
+    int rval = 0;
+    int newtree = 0;
+    int *perm = (int *) NULL;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    printf ("Grow a Quick-Boruvka tour \n");
+    fflush (stdout);
+
+    if (outcycle) {
+        tcyc = CC_SAFE_MALLOC (2 * ncount, int);
+        if (!tcyc) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    degree = CC_SAFE_MALLOC (ncount, char);
+    if (!degree) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    tail = CC_SAFE_MALLOC (ncount, int);
+    if (!tail) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    perm = CC_SAFE_MALLOC (ncount, int);
+    if (!perm) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++) {
+#ifndef USE_SPACEFILL
+        perm[i] = i;
+#endif
+        degree[i] = 0;
+        tail[i] = -1;
+
+    }
+#ifndef USE_SPACEFILL
+    CCutil_double_perm_quicksort (perm, dat->x, ncount);
+#endif
+
+#ifdef USE_SPACEFILL
+    if ((dat->norm & CC_NORM_SIZE_BITS) == CC_D2_NORM_SIZE) {
+        double sflen;
+        if (space_fill_curve (ncount, dat, perm, &sflen)) {
+            fprintf (stderr, "space_fill_curve failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    } else {
+        for (i = 0; i < ncount; i++)
+            perm[i] = i;
+        CCutil_double_perm_quicksort (perm, dat->x, ncount);
+    }
+#endif
+
+    len = 0.0;
+    count = 1;
+    while (count < ncount) {
+        for (i = 0;  i < ncount && count < ncount; i++) {
+            x = perm[i];
+            if (degree[x] != 2) {
+                if (tail[x] != -1) {
+                    CCkdtree_delete (thetree, tail[x]);
+                    y = CCkdtree_node_nearest (thetree, x, dat,
+                                               (double *) NULL);
+                    CCkdtree_undelete (thetree, tail[x]);
+                } else
+                    y = CCkdtree_node_nearest (thetree, x, dat,
+                                               (double *) NULL);
+
+                /* add (x, y) to the tour */
+                if (degree[x] != 0)
+                    CCkdtree_delete (thetree, x);
+                if (degree[y] != 0)
+                    CCkdtree_delete (thetree, y);
+                len += (double) CCutil_dat_edgelen (x, y, dat);
+                degree[x]++;
+                degree[y]++;
+                if (tcyc) {
+                    tcyc[tcount++] = x;
+                    tcyc[tcount++] = y;
+                }
+                if (tail[x] == -1) {
+                    if (tail[y] == -1) {
+                        tail[x] = y;
+                        tail[y] = x;
+                    } else {
+                        tail[x] = tail[y];
+                        tail[tail[y]] = x;
+                    }
+                } else if (tail[y] == -1) {
+                    tail[tail[x]] = y;
+                    tail[y] = tail[x];
+                } else {
+                    tail[tail[x]] = tail[y];
+                    tail[tail[y]] = tail[x];
+                }
+                if (count % 10000 == 9999) {
+                    printf (".");
+                    fflush (stdout);
+                }
+                count++;
+            }
+        }
+    }
+    for (x = 0; degree[x] != 1; x++);
+    for (y = x + 1; degree[y] != 1; y++);
+    if (tcyc) {
+        tcyc[tcount++] = x;
+        tcyc[tcount++] = y;
+    }
+    len += (double) CCutil_dat_edgelen (x, y, dat);
+    *val = len;
+    if (ncount >= 10000)
+        printf ("\n");
+    printf ("Length of Quick-Boruvka Tour: %.2f\n", len);
+
+    if (tcyc) {
+        if (CCutil_edge_to_cycle (ncount, tcyc, outcycle)) {
+            fprintf (stderr, "ERROR: greedy tour is not a tour\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+CLEANUP:
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    else
+        CCkdtree_undelete_all (kt, ncount);
+    CC_IFFREE (tcyc, int);
+    CC_IFFREE (degree, char);
+    CC_IFFREE (tail, int);
+    CC_IFFREE (perm, int);
+    return rval;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_boruvka_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+        int *outcycle, double *val)
+#else
+int CCkdtree_boruvka_tour (kt, ncount, dat, outcycle, val)
+CCkdtree *kt;
+int ncount;
+CCdatagroup *dat;
+int *outcycle;
+double *val;
+#endif
+{
+    CCkdtree localkt, *thetree;
+    double len;
+    int i, x, y;
+    char *degree = (char *) NULL;
+    int *tail = (int *) NULL;
+    int *tcyc = (int *) NULL;
+    int tcount = 0, count;
+    int rval = 0;
+    int newtree = 0;
+    int *getem = (int *) NULL;
+    int *getemlen = (int *) NULL;
+    int *perm = (int *) NULL;
+    int getemcount, newgetemcount;
+    int round = 0;
+    int *neighbor = (int *) NULL;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    printf ("Grow a Boruvka tour \n");
+    fflush (stdout);
+
+    if (outcycle) {
+        tcyc = CC_SAFE_MALLOC (2 * ncount, int);
+        if (!tcyc) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    degree = CC_SAFE_MALLOC (ncount, char);
+    if (!degree) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    tail = CC_SAFE_MALLOC (ncount, int);
+    if (!tail) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    neighbor = CC_SAFE_MALLOC (ncount, int);
+    if (!neighbor) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    getem = CC_SAFE_MALLOC (ncount, int);
+    if (!getem) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    getemlen = CC_SAFE_MALLOC (ncount, int);
+    if (!getemlen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    perm = CC_SAFE_MALLOC (ncount, int);
+    if (!perm) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    getemcount = ncount;
+
+    for (i = 0; i < ncount; i++) {
+        degree[i] = 0;
+        tail[i] = -1;
+        getem[i] = i;
+    }
+
+    len = 0.0;
+    count = 1;
+    while (count < ncount) {
+        round++;
+        i = 0;
+        while (i < getemcount) {
+            x = getem[i];
+            if (degree[x] != 2) {
+                if (tail[x] != -1) {
+                    CCkdtree_delete (thetree, tail[x]);
+                    neighbor[i] = CCkdtree_node_nearest (thetree, x, dat,
+                                  (double *) NULL);
+                    CCkdtree_undelete (thetree, tail[x]);
+                } else {
+                    neighbor[i] = CCkdtree_node_nearest (thetree, x, dat,
+                                  (double *) NULL);
+                }
+                getemlen[i] = CCutil_dat_edgelen (x, neighbor[i], dat);
+                perm[i] = i;
+                i++;
+            } else {
+                getem[i] = getem[--getemcount];
+            }
+        }
+        CCutil_int_perm_quicksort (perm, getemlen, getemcount);
+        newgetemcount = 0;
+        for (i = 0;  i < getemcount && count < ncount; i++) {
+            x = getem[perm[i]];
+            if (degree[x] != 2) {
+                y = neighbor[perm[i]];
+                if (degree[y] != 2 && tail[x] != y) {
+                    /* add (x, y) to the tour */
+                    if (degree[x] != 0)
+                        CCkdtree_delete (thetree, x);
+                    else
+                        perm[newgetemcount++] = x;
+                    if (degree[y] != 0)
+                        CCkdtree_delete (thetree, y);
+                    len += (double) CCutil_dat_edgelen (x, y, dat);
+                    degree[x]++;
+                    degree[y]++;
+                    if (tcyc) {
+                        tcyc[tcount++] = x;
+                        tcyc[tcount++] = y;
+                    }
+                    if (tail[x] == -1) {
+                        if (tail[y] == -1) {
+                            tail[x] = y;
+                            tail[y] = x;
+                        } else {
+                            tail[x] = tail[y];
+                            tail[tail[y]] = x;
+                        }
+                    } else if (tail[y] == -1) {
+                        tail[tail[x]] = y;
+                        tail[y] = tail[x];
+                    } else {
+                        tail[tail[x]] = tail[y];
+                        tail[tail[y]] = tail[x];
+                    }
+                    if (count % 10000 == 9999) {
+                        printf (".");
+                        fflush (stdout);
+                    }
+                    count++;
+                } else {
+                    perm[newgetemcount++] = x;
+                }
+            }
+        }
+        getemcount = newgetemcount;
+        {
+            int *temp;
+            SWAP (getem, perm, temp);
+        }
+    }
+    for (x = 0; degree[x] != 1; x++);
+    for (y = x + 1; degree[y] != 1; y++);
+    if (tcyc) {
+        tcyc[tcount++] = x;
+        tcyc[tcount++] = y;
+    }
+    len += (double) CCutil_dat_edgelen (x, y, dat);
+    *val = len;
+    if (ncount >= 10000)
+        printf ("\n");
+    printf ("Length of Boruvka Tour: %.0f  (%d Rounds)\n", len, round);
+
+    if (tcyc) {
+        if (CCutil_edge_to_cycle (ncount, tcyc, outcycle)) {
+            fprintf (stderr, "ERROR: greedy tour is not a tour\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+CLEANUP:
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    else
+        CCkdtree_undelete_all (kt, ncount);
+    if (tcyc)
+        CC_FREE (tcyc, int);
+    if (degree)
+        CC_FREE (degree, char);
+    if (tail)
+        CC_FREE (tail, int);
+    if (neighbor)
+        CC_FREE (neighbor, int);
+    if (getem)
+        CC_FREE (getem, int);
+    if (getemlen)
+        CC_FREE (getemlen, int);
+    if (perm)
+        CC_FREE (perm, int);
+    return rval;
+}
+
+#ifdef USE_SPACEFILL
+#ifdef CC_PROTOTYPE_ANSI
+static int space_fill_curve (int ncount, CCdatagroup *dat, int *outcyc,
+                             double *len)
+#else
+static int space_fill_curve (ncount, dat, outcyc, len)
+int ncount;
+CCdatagroup *dat;
+int *outcyc;
+double *len;
+#endif
+{
+    int i, h, M;
+    int x, y, z;
+    int k, nbits;
+    int *th = (int *) NULL;
+    int *cyc = (int *) NULL;
+    double tx, ty, tM;
+
+    /* From Platzman and Bartholdi, JACM 36 (1989) 719-737. */
+
+    if ((dat->norm & CC_NORM_SIZE_BITS) != CC_D2_NORM_SIZE) {
+        printf ("Need a 2-coordinate norm to use space filling curve\n");
+        fflush (stdout);
+        return 1;
+    }
+
+    th = CC_SAFE_MALLOC (ncount, int);
+    if (!th)
+        return 1;
+
+    if (outcyc != (int *) NULL) {
+        cyc = outcyc;
+    } else {
+        cyc = CC_SAFE_MALLOC (ncount, int);
+        if (!cyc) {
+            CC_FREE (th, int);
+            return 1;
+        }
+    }
+
+    tM = 0.0;
+    tx = 0.0;
+    ty = 0.0;
+
+    for (i = 0; i < ncount; i++) {
+        cyc[i] = i;
+        if (dat->x[i] < tx)
+            tx = dat->x[i];
+        else if (dat->x[i] > tM)
+            tM = dat->x[i];
+
+        if (dat->y[i] < ty)
+            ty = dat->y[i];
+        else if (dat->y[i] > tM)
+            tM = dat->y[i];
+    }
+
+    M = (int) (tM - tx - ty + 1.0);
+
+    nbits = 0;
+    while ((1 << nbits) < ncount)
+       nbits++;
+    nbits += 2;
+
+    for (i = 0; i < ncount; i++) {
+        x = (int) (dat->x[i] - tx);    /* To make coords nonnegative ints */
+        y = (int) (dat->y[i] - ty);
+
+        h = 0;
+        k = 1;
+        if (x > y) {
+            h = 1;
+            x = M - x;
+            y = M - y;
+        }
+
+        while (k < nbits) {
+            h <<= 1;
+            k++;
+
+            if (x + y > M) {
+                h++;
+                z = M - y;
+                y = x;
+                x = z;
+            }
+
+            if (k < nbits) {
+                h <<= 1;
+                k++;
+
+                x <<= 1;
+                y <<= 1;
+
+                if (y > M) {
+                    h++;
+                    z = y - M;
+                    y = M - x;
+                    x = z;
+                }
+            }
+        }
+        th[i] = h;
+    }
+
+    CCutil_int_perm_quicksort (cyc, th, ncount);
+    *len = (double) CCutil_dat_edgelen (cyc[ncount - 1], cyc[0], dat);
+    for (i = 1; i < ncount; i++)
+        (*len) += CCutil_dat_edgelen (cyc[i - 1], cyc[i], dat);
+    printf ("Spacefilling Curve Tour: %.2f\n", *len);
+    fflush (stdout);
+
+    if (th)
+        CC_FREE (th, int);
+    if (!outcyc && cyc)
+        CC_FREE (cyc, int);
+
+    return 0;
+}
+#endif
diff --git a/contrib/blossom/concorde97/KDTREE/kdtwoopt.c b/contrib/blossom/concorde97/KDTREE/kdtwoopt.c
new file mode 100644
index 0000000000000000000000000000000000000000..5cf49e3392fff299912ba08099db1961599388dc
--- /dev/null
+++ b/contrib/blossom/concorde97/KDTREE/kdtwoopt.c
@@ -0,0 +1,1057 @@
+/***************************************************************************/
+/*                                                                         */
+/*                KD-TREE BASED GEOMETRIC 2-OPT ROUTINE                    */
+/*                                                                         */
+/*  (Based on Jon Bentley's paper "Fast algorithms for geometric           */
+/*   traveling salesman problems", ORSA Journal on Computing.)             */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook (mainly from Jon      */
+/*               Bentley's paper)                                          */
+/*  Date: February 16, 1995  (cofeb16)                                     */
+/*        Modified: October 11, 1995 (Bico) - removed globals.             */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCkdtree_twoopt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,*/
+/*           int *incycle, int *outcycle, double *val,                     */
+/*           int run_two_and_a_half_opt, int run_silently)                 */
+/*      RETURNS a 2-opted cycle (well, approximately 2-opted)              */
+/*        -kt can be NULL.                                                 */
+/*        -Does not use node weights.                                      */
+/*        -incycle is the starting cycle.                                  */
+/*        -If outcycle is not NULL, then it should point to an array of    */
+/*         length at least ncount (allocated by the calling routine). The  */
+/*         final tour will be placed in this array.                        */
+/*        -The length of the tour is returned in val.                      */
+/*        -If in_run_two_and_a_half_opt is nonzero,  then some limited     */
+/*         3-swapping is performded.                                       */
+/*        -run_silently (if nonzero then very little info will be printed) */
+/*    int CCkdtree_3opt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,  */
+/*           int *incycle, int *outcycle, double *val, run_silently)       */
+/*      RETURNS an approximately 3-opted tour.                             */
+/*        -kt can be NULL.                                                 */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*     Uses around 13n bytes of memory for an n node problem (plus the     */
+/*  the memory for the CCkdtree). Returns 0 if successful, and nonzero if  */
+/*  it failed (usually due to running out of memory.                       */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "kdtree.h"
+
+#define Edgelen(a, b)  CCutil_dat_edgelen ((a), (b), dat)
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define ADD_TO_ACTIVE_QUEUE(n, ip, q) {                                    \
+    if (!(q)->active[(n)]) {                                               \
+        (q)->active[(n)] = 1;                                              \
+        (ip) = intptralloc ();                                             \
+        (ip)->this = (n);                                                  \
+        (ip)->next = (intptr *) NULL;                                      \
+        if ((q)->bottom)                                                   \
+            (q)->bottom->next = (ip);                                      \
+        else                                                               \
+            (q)->queue = (ip);                                             \
+        (q)->bottom = (ip);                                                \
+    }                                                                      \
+}
+
+typedef struct intptr {
+    int this;
+    struct intptr *next;
+} intptr;
+
+typedef struct optqueue {
+    char *active;
+    intptr *queue;
+    intptr *bottom;
+} optqueue;
+
+typedef struct flipper {
+    int reversed;
+    int cycle_size;
+    int short_size;
+    int *cyc;
+    int *cyc_inv;
+} flipper;
+
+typedef struct twoopt_param {
+    CCdatagroup *dat;
+    optqueue  *activequeue;
+    flipper   *flipstuff;
+    int node_b;
+} twoopt_param;
+
+typedef struct twoopt_and_a_half_param {
+    CCdatagroup *dat;
+    optqueue  *activequeue;
+    flipper   *flipstuff;
+    int node_b;
+} twoopt_and_a_half_param;
+
+typedef struct threeopt_param {
+    CCdatagroup *dat;
+    optqueue  *activequeue;
+    flipper   *flipstuff;
+    int node_a;
+    int node_b;
+    int node_c;
+    int ab_dist;
+    int ac_dist;
+    int cd_dist;
+    CCkdtree *thetree;
+} threeopt_param;
+
+CC_PTR_ALLOC_ROUTINE (intptr, intptralloc, intptrchunklist, intptrfreelist)
+CC_PTR_FREE_ROUTINE (intptr, intptrfree, intptrfreelist)
+CC_PTR_FREE_WORLD_ROUTINE (intptr, intptrfree_world, intptrchunklist,
+        intptrfreelist)
+CC_PTR_LEAKS_ROUTINE (intptr, intptr_check_leaks, intptrchunklist,
+        intptrfreelist, this, int)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    flipper_cycle (flipper *f, int *x),
+    flipper_finish (flipper *f),
+    flipper_flip (flipper *f, int x, int y),
+    randcycle (int ncount, int *cyc),
+    twoopt_free_world (void);
+static int
+    run_two_opt (int ncount, int run_silently, int *tour,
+        int run_two_and_a_half_swap, int *neighbor, CCkdtree *thetree,
+        CCdatagroup *dat, optqueue *activequeue),
+    run_3_opt (int ncount, int run_silently, int *tour, int *neighbor,
+        CCkdtree *thetree, CCdatagroup *dat, optqueue *activequeue),
+    swap_from_node (int a, int run_two_an_a_half_swap, int *neighbor,
+        CCkdtree *thetree, CCdatagroup *dat, optqueue *activequeue,
+        flipper *f),
+    try_two_swap (int a, int c, void *pass_param),
+    try_two_and_a_half_swap (int a, int c, void *pass_param),
+    three_swap_from_node (int a, int *neighbor, CCkdtree *thetree,
+        CCdatagroup *dat, optqueue *activequeue, flipper *f),
+    try_three_swap (int a, int c, void *pass_param),
+    try_three_swap_2 (int a, int c, void *pass_param),
+    flipper_init (flipper *f, int *incyc, int n),
+    flipper_next (flipper *f, int x),
+    flipper_prev (flipper *f, int x),
+    flipper_sequence (flipper *f, int x, int y, int z);
+static double
+    cycle_length (int *cyc, int ncount, CCdatagroup *dat);
+
+#else
+
+static void
+    flipper_cycle (),
+    flipper_finish (),
+    flipper_flip (),
+    randcycle (),
+    twoopt_free_world ();
+static int
+    run_two_opt (),
+    run_3_opt (),
+    swap_from_node (),
+    try_two_swap (),
+    try_two_and_a_half_swap (),
+    three_swap_from_node (),
+    try_three_swap (),
+    try_three_swap_2 (),
+    flipper_init (),
+    flipper_next (),
+    flipper_prev (),
+    flipper_sequence ();
+static double
+    cycle_length ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_twoopt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+        int *incycle, int *outcycle, double *val,
+        int run_two_and_a_half_opt, int run_silently)
+#else
+int CCkdtree_twoopt_tour (kt, ncount, dat, incycle, outcycle, val,
+        run_two_and_a_half_opt, run_silently)
+CCkdtree *kt;
+int ncount;
+CCdatagroup *dat;
+int *incycle, *outcycle;
+double *val;
+int run_two_and_a_half_opt;
+int run_silently;
+#endif
+{
+    CCkdtree localkt;
+    int i;
+    int rval = 0;
+    double szeit;
+    int newtree = 0;
+    intptr *ip;
+    int *tour = (int *) NULL;
+    int *neighbor = (int *) NULL;
+    CCkdtree *thetree = (CCkdtree *) NULL;
+    optqueue activequeue;
+
+    *val = 0.0;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    activequeue.active = (char *) NULL;
+    activequeue.queue = (intptr *) NULL;
+    activequeue.bottom = (intptr *) NULL;
+
+    if (!run_silently) {
+        printf ("Find 2-opt Tour starting with tour of length %.2f\n",
+                   cycle_length (incycle, ncount, dat));
+        fflush (stdout);
+    }
+
+    szeit = CCutil_zeit ();
+    tour = CC_SAFE_MALLOC (ncount, int);
+    if (!tour) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    neighbor = CC_SAFE_MALLOC (ncount, int);
+    if (!neighbor) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    activequeue.active = CC_SAFE_MALLOC (ncount, char);
+    if (!activequeue.active) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++)
+        activequeue.active[i] = 0;
+
+    randcycle (ncount, tour);        /* init active_queue with random order */
+    for (i = 0; i < ncount; i++) {
+        ADD_TO_ACTIVE_QUEUE (tour[i], ip, &activequeue);
+    }
+
+    for (i = 0; i < ncount; i++) {
+        tour[i] = incycle[i];
+    }
+    run_two_opt (ncount, run_silently, tour, run_two_and_a_half_opt,
+                 neighbor, thetree, dat, &activequeue);
+
+    *val = cycle_length (tour, ncount, dat);
+    if (!run_silently) {
+        printf ("Length of Two-opt Cycle: %.2f\n", *val);
+        fflush (stdout);
+    }
+    if (outcycle != (int *) NULL) {
+        for (i = 0; i < ncount; i++)
+            outcycle[i] = tour[i];
+    }
+    if (!run_silently) {
+        printf ("Running time for Two Opt: %.2f\n", CCutil_zeit () - szeit);
+        fflush (stdout);
+    }
+
+CLEANUP:
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    if (tour)
+        CC_FREE (tour, int);
+    if (neighbor)
+        CC_FREE (neighbor, int);
+    if (activequeue.active)
+        CC_FREE (activequeue.active, char);
+    twoopt_free_world ();
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int run_two_opt (int ncount, int run_silently, int *tour,
+        int run_two_and_a_half_opt, int *neighbor,
+        CCkdtree *thetree, CCdatagroup *dat, optqueue *activequeue)
+#else
+static int run_two_opt (ncount, run_silently, tour, run_two_and_a_half_opt,
+        neighbor, thetree, dat, activequeue)
+int ncount;
+int run_silently;
+int *tour;
+int run_two_and_a_half_opt;
+int *neighbor;
+CCkdtree *thetree;
+CCdatagroup *dat;
+optqueue *activequeue;
+#endif
+{
+    int i, hit;
+    int start;
+    intptr *ip;
+    flipper f;
+
+    for (i = 0; i < ncount; i++) {
+        CCkdtree_delete (thetree, i);
+        neighbor[i] = CCkdtree_node_nearest (thetree, i, dat, (double *) NULL);
+        CCkdtree_undelete (thetree, i);
+    }
+
+    flipper_init (&f, tour, ncount);
+    hit = 0;
+    while (activequeue->queue) {
+        ip = activequeue->queue;
+        start = ip->this;
+        activequeue->queue = ip->next;
+        if (ip == activequeue->bottom)
+            activequeue->bottom = (intptr *) NULL;
+        intptrfree (ip);
+        activequeue->active[start] = 0;
+        if (swap_from_node (start, run_two_and_a_half_opt, neighbor,
+                            thetree, dat, activequeue, &f)) {
+            hit++;
+            if (!run_silently && hit % 1000 == 0) {
+                printf (".");
+                fflush (stdout);
+                if (hit % 50000 == 0) {
+                    flipper_cycle (&f, tour);
+                    printf ("\nCurrent length: %.2f\n",
+                            cycle_length (tour, ncount, dat));
+                    fflush (stdout);
+                }
+            }
+        }
+    }
+
+    if (!run_silently) {
+        printf ("\nMade %d swaps\n", hit);
+        fflush (stdout);
+    }
+
+    flipper_cycle (&f, tour);
+    flipper_finish (&f);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void twoopt_free_world (void)
+#else
+static void twoopt_free_world ()
+#endif
+{
+    int total, onlist;
+
+    if (intptr_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding intptrs\n", total - onlist);
+    }
+    intptrfree_world ();
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCkdtree_3opt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+        int *incycle, int *outcycle, double *val, int run_silently)
+#else
+int CCkdtree_3opt_tour (kt, ncount, dat, incycle, outcycle, val, run_silently)
+CCkdtree *kt;
+int ncount;
+CCdatagroup *dat;
+int *incycle, *outcycle;
+double *val;
+int run_silently;
+#endif
+{
+    CCkdtree localkt;
+    int i;
+    int rval = 0;
+    double szeit;
+    int newtree = 0;
+    intptr *ip;
+    int *tour = (int *) NULL;
+    int *neighbor = (int *) NULL;
+    CCkdtree *thetree = (CCkdtree *) NULL;
+    optqueue activequeue;
+
+    *val = 0.0;
+
+    if (kt == (CCkdtree *) NULL) {
+        if (CCkdtree_build (&localkt, ncount, dat, (double *) NULL)) {
+            fprintf (stderr, "Unable to build CCkdtree\n");
+            return 1;
+        }
+        thetree = &localkt;
+        newtree = 1;
+    } else {
+        thetree = kt;
+    }
+
+    activequeue.active = (char *) NULL;
+    activequeue.queue = (intptr *) NULL;
+    activequeue.bottom = (intptr *) NULL;
+
+    if (!run_silently) {
+        printf ("Find 3-opt Tour starting with tour of length %.2f\n",
+                       cycle_length (incycle, ncount, dat));
+        fflush (stdout);
+    }
+
+    szeit = CCutil_zeit ();
+    tour = CC_SAFE_MALLOC (ncount, int);
+    if (!tour) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    activequeue.active = CC_SAFE_MALLOC (ncount, char);
+    if (!activequeue.active) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    neighbor = CC_SAFE_MALLOC (ncount, int);
+    if (!neighbor) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++)
+        activequeue.active[i] = 0;
+
+    randcycle (ncount, tour);        /* init active_queue with random order */
+    for (i = 0; i < ncount; i++) {
+        ADD_TO_ACTIVE_QUEUE (tour[i], ip, &activequeue);
+    }
+
+    for (i = 0; i < ncount; i++) {
+        tour[i] = incycle[i];
+    }
+    run_3_opt (ncount, run_silently, tour, neighbor, thetree, dat,
+               &activequeue);
+
+    *val = cycle_length (tour, ncount, dat);
+    if (!run_silently) {
+        printf ("Length of 3-opt Cycle: %.2f\n", *val);
+        fflush (stdout);
+    }
+    if (outcycle != (int *) NULL) {
+        for (i = 0; i < ncount; i++)
+            outcycle[i] = tour[i];
+    }
+    if (!run_silently) {
+        printf ("Running time for 3-Opt: %.2f\n", CCutil_zeit () - szeit);
+        fflush (stdout);
+    }
+
+CLEANUP:
+
+    if (newtree)
+        CCkdtree_free (&localkt);
+    if (tour)
+        CC_FREE (tour, int);
+    if (activequeue.active)
+        CC_FREE (activequeue.active, char);
+    if (neighbor)
+        CC_FREE (neighbor, int);
+    twoopt_free_world ();
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int run_3_opt (int ncount, int run_silently, int *tour,
+        int *neighbor, CCkdtree *thetree, CCdatagroup *dat,
+        optqueue *activequeue)
+#else
+static int run_3_opt (ncount, run_silently, tour, neighbor, thetree, dat,
+        activequeue)
+int ncount;
+int run_silently;
+int *tour;
+int *neighbor;
+CCkdtree *thetree;
+CCdatagroup *dat;
+optqueue *activequeue;
+#endif
+{
+    int i, hit;
+    int start;
+    intptr *ip;
+    flipper f;
+
+    for (i = 0; i < ncount; i++) {
+        CCkdtree_delete (thetree, i);
+        neighbor[i] = CCkdtree_node_nearest (thetree, i, dat, (double *) NULL);
+        CCkdtree_undelete (thetree, i);
+    }
+
+    flipper_init (&f, tour, ncount);
+    hit = 0;
+    while (activequeue->queue) {
+        ip = activequeue->queue;
+        start = ip->this;
+        activequeue->queue = ip->next;
+        if (ip == activequeue->bottom)
+            activequeue->bottom = (intptr *) NULL;
+        intptrfree (ip);
+        activequeue->active[start] = 0;
+        if (three_swap_from_node (start, neighbor, thetree, dat, activequeue,
+                                  &f)) {
+            hit++;
+            if (!run_silently && hit % 1000 == 0) {
+                printf (".");
+                fflush (stdout);
+                if (hit % 50000 == 0) {
+                    flipper_cycle (&f, tour);
+                    printf ("\nCurrent length: %.2f\n",
+                            cycle_length (tour, ncount, dat));
+                    fflush (stdout);
+                }
+            }
+        }
+    }
+
+    if (!run_silently) {
+        printf ("\nMade %d swaps\n", hit);
+        fflush (stdout);
+    }
+
+    flipper_cycle (&f, tour);
+    flipper_finish (&f);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int swap_from_node (int a, int run_two_and_a_half_opt,
+        int *neighbor, CCkdtree *thetree, CCdatagroup *dat,
+        optqueue *activequeue, flipper *f)
+#else
+static int swap_from_node (a, run_two_and_a_half_opt, neighbor, thetree, dat,
+        activequeue, f)
+int run_two_and_a_half_opt;
+int a;
+int *neighbor;
+CCkdtree *thetree;
+CCdatagroup *dat;
+optqueue *activequeue;
+flipper *f;
+#endif
+{
+    twoopt_param param2;
+    twoopt_param param2h;
+    int b;
+
+    b = flipper_next (f, a);
+    if (neighbor[a] ==b) {
+        return 0;
+    } else {
+        int dist = Edgelen (a, b);
+        if (run_two_and_a_half_opt) {
+            param2h.dat = dat;
+            param2h.activequeue = activequeue;
+            param2h.node_b = b;
+            param2h.flipstuff = f;
+            return CCkdtree_fixed_radius_nearest (thetree, dat, (double *) NULL,
+                 a, (double) dist, try_two_and_a_half_swap,
+                 (void *) (&param2h));
+        } else {
+            param2.dat = dat;
+            param2.activequeue = activequeue;
+            param2.node_b = b;
+            param2.flipstuff = f;
+            return CCkdtree_fixed_radius_nearest (thetree, dat, (double *) NULL,
+                 a, (double) dist, try_two_swap, (void *) (&param2));
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int try_two_swap (int a, int c, void *pass_param)
+#else
+static int try_two_swap (a, c, pass_param)
+int a, c;
+void *pass_param;
+#endif
+{
+    int d;
+    int b = ((twoopt_param *) pass_param)->node_b;
+    CCdatagroup *dat = ((twoopt_param *) pass_param)->dat;
+    optqueue *activequeue = ((twoopt_param *) pass_param)->activequeue;
+    flipper *flipstuff = ((twoopt_param *) pass_param)->flipstuff;
+    intptr *ip;
+
+    d = flipper_next (flipstuff, c);
+
+    if (d == a)
+        return 0;
+
+    if (Edgelen (a, b) + Edgelen (c, d) >
+        Edgelen (a, c) + Edgelen (b, d)) {
+        flipper_flip (flipstuff, d, a);
+        ADD_TO_ACTIVE_QUEUE (a, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (b, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (c, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (d, ip, activequeue);
+        return 1;
+    } else
+        return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int try_two_and_a_half_swap (int a, int c, void *pass_param)
+#else
+static int try_two_and_a_half_swap (a, c, pass_param)
+int a, c;
+void *pass_param;
+#endif
+{
+    int d, e;
+    int b = ((twoopt_and_a_half_param *) pass_param)->node_b;
+    CCdatagroup *dat = ((twoopt_param *) pass_param)->dat;
+    optqueue *activequeue = ((twoopt_param *) pass_param)->activequeue;
+    flipper *flipstuff = ((twoopt_param *) pass_param)->flipstuff;
+    intptr *ip;
+
+    d = flipper_next (flipstuff, c);
+
+    if (d == a)
+        return 0;
+
+    if (Edgelen (a, b) + Edgelen (c, d) >
+        Edgelen (a, c) + Edgelen (b, d)) {
+        flipper_flip (flipstuff, d, a);
+        ADD_TO_ACTIVE_QUEUE (a, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (b, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (c, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (d, ip, activequeue);
+        return 1;
+    } else {
+        e = flipper_prev (flipstuff, c);
+        if (e != b &&
+            Edgelen (a, b) + Edgelen (c, d) + Edgelen (c, e) >
+            Edgelen (a, c) + Edgelen (b, c) + Edgelen (d, e)) {
+            flipper_flip (flipstuff, b, e);
+            flipper_flip (flipstuff, e, c);
+            ADD_TO_ACTIVE_QUEUE (a, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (b, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (c, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (d, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (e, ip, activequeue);
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int three_swap_from_node (int a, int *neighbor, CCkdtree *thetree,
+        CCdatagroup *dat, optqueue *activequeue, flipper *f)
+#else
+static int three_swap_from_node (a, neighbor, thetree, dat, activequeue, f)
+int a;
+int *neighbor;
+CCkdtree *thetree;
+CCdatagroup *dat;
+optqueue *activequeue;
+flipper *f;
+#endif
+{
+    threeopt_param param3;
+    int b, ab;
+
+    b = flipper_next (f, a);
+
+    if (neighbor[a] == b) {
+        return 0;
+    } else {
+        ab = Edgelen (a, b);
+        param3.dat = dat;
+        param3.activequeue = activequeue;
+        param3.node_a = a;
+        param3.node_b = b;
+        param3.thetree = thetree;
+        param3.ab_dist = ab;
+        param3.flipstuff = f;
+        return CCkdtree_fixed_radius_nearest (thetree, dat, (double *) NULL,
+                     a, (double) ab, try_three_swap, (void *) (&param3));
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int try_three_swap (int a, int c, void *pass_param)
+#else
+static int try_three_swap (a, c, pass_param)
+int a, c;
+void *pass_param;
+#endif
+{
+    int d, b, ac, cd;
+    threeopt_param *p = (threeopt_param *) pass_param;
+    CCdatagroup *dat;
+    optqueue *activequeue;
+    intptr *ip;
+
+    dat = p->dat;
+    activequeue = p->activequeue;
+    b = p->node_b;
+    d = flipper_next (p->flipstuff, c);
+
+    ac = Edgelen (a, c);
+    cd = Edgelen (c, d);
+    if (p->ab_dist + cd > ac + Edgelen (b, d)) {
+        flipper_flip (p->flipstuff, d, a);
+        ADD_TO_ACTIVE_QUEUE (a, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (b, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (c, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (d, ip, activequeue);
+        return 1;
+    } else {
+        int e = flipper_prev (p->flipstuff, c);
+        if (e != b && d != a &&
+            p->ab_dist + cd + Edgelen (c, e) >
+            ac + Edgelen (b, c) + Edgelen (d, e)) {
+            flipper_flip (p->flipstuff, b, e);
+            flipper_flip (p->flipstuff, e, c);
+            ADD_TO_ACTIVE_QUEUE (a, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (b, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (c, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (d, ip, activequeue);
+            ADD_TO_ACTIVE_QUEUE (e, ip, activequeue);
+            return 1;
+        } else {
+            p->node_c = c;
+            p->ac_dist = ac;
+            p->cd_dist = cd;
+
+            return CCkdtree_fixed_radius_nearest (p->thetree, dat,
+              (double *) NULL, d, (double) (p->ab_dist + cd - ac),
+              try_three_swap_2, pass_param);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int try_three_swap_2 (int d, int e, void *pass_param)
+#else
+static int try_three_swap_2 (d, e, pass_param)
+int d, e;
+void *pass_param;
+#endif
+{
+    threeopt_param *p = (threeopt_param *) pass_param;
+    CCdatagroup *dat;
+    optqueue *activequeue;
+    int a, b, c, f;
+    intptr *ip;
+
+    a = p->node_a;
+    b = p->node_b;
+    c = p->node_c;
+    dat = p->dat;
+    activequeue = p->activequeue;
+
+    if (e == c)
+        return 0;
+    else if (flipper_sequence (p->flipstuff, b, e, c))
+        f = flipper_next (p->flipstuff, e);
+    else
+        f = flipper_prev (p->flipstuff, e);
+
+    if (p->ab_dist + p->cd_dist + Edgelen (e, f) >
+        p->ac_dist + Edgelen (b, f) + Edgelen (d, e)) {
+        flipper_flip (p->flipstuff, d, a);
+        flipper_flip (p->flipstuff, b, e);
+        ADD_TO_ACTIVE_QUEUE (a, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (b, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (c, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (d, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (e, ip, activequeue);
+        ADD_TO_ACTIVE_QUEUE (f, ip, activequeue);
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double cycle_length (int *cyc, int ncount, CCdatagroup *dat)
+#else
+static double cycle_length (cyc, ncount, dat)
+int *cyc;
+int ncount;
+CCdatagroup *dat;
+#endif
+{
+    int i;
+    double len;
+
+    for (len = 0.0, i = 1; i < ncount; i++)
+        len += CCutil_dat_edgelen (cyc[i - 1], cyc[i], dat);
+    len += CCutil_dat_edgelen (cyc[0], cyc[ncount - 1], dat);
+
+    return len;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void randcycle (int ncount, int *cyc)
+#else
+static void randcycle (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, k, temp;
+
+    for (i = 0; i < ncount; i++)
+        cyc[i] = i;
+
+    for (i = ncount; i > 1; i--) {
+        k = CCutil_lprand () % i;
+        SWAP (cyc[i - 1], cyc[k], temp);
+    }
+}
+
+
+/**********   modified version of flipper3.c **********/
+
+/*
+   flipper routines:
+
+   flipper_init (flipper *f, int n)
+      initializes flipper3 to an initial * cycle from 0 to n-1.
+   flipper_cycle (flipper *f, int *p)
+      places the current * cycle in p.
+   flipper_finish (flipper *f, )
+      frees up space * allocated by flipper.
+   flipper_next (flipper *f, int x)
+      returns the * successor to x in the current cycle.
+   flipper_prev (flipper *f, int x)
+      returns the predecessor of x in the current cycle.
+   flipper_flip (flipper *f, int * x, int y)
+      flips the portion of the cycle from x to y (inclusive).
+   flipper_sequence (flipper *f, int x, int y, int z)
+      returns 1 if x, y, z occur as an increasing
+      subsequence of the cycle, 0 otherwise.
+
+   The basic implementation - uses a raw cycle and its inverse, but flips
+   the short side.
+*/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int flipper_init (flipper *f, int *incyc, int n)
+#else
+static int flipper_init (f, incyc, n)
+flipper *f;
+int *incyc, n;
+#endif
+{
+    int i;
+
+    f->cyc_inv = (int *) NULL;
+    f->cyc = CC_SAFE_MALLOC (n, int);
+    if (!f->cyc)
+        return 1;
+    f->cyc_inv = CC_SAFE_MALLOC (n, int);
+    if (!f->cyc_inv) {
+        CC_FREE (f->cyc, int);
+        return 1;
+    }
+
+    for (i = 0; i < n; i++) {
+        f->cyc[i] = incyc[i];
+        f->cyc_inv[incyc[i]] = i;
+    }
+
+    f->cycle_size = n;
+    f->short_size = n / 2;
+    f->reversed = 0;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper_cycle (flipper *f, int *x)
+#else
+static void flipper_cycle (f, x)
+flipper *f;
+int *x;
+#endif
+{
+    int *p;
+
+    if (f->reversed) {
+        p = f->cyc + f->cycle_size;
+        while (p > f->cyc) {
+            *x++ = *--p;
+        }
+    } else {
+        p = f->cyc + f->cycle_size;
+        x += f->cycle_size;
+        while (p > f->cyc) {
+            *--x = *--p;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper_finish (flipper *f)
+#else
+static void flipper_finish (f)
+flipper *f;
+#endif
+{
+    if (f->cyc)
+        CC_FREE (f->cyc, int);
+    if (f->cyc_inv)
+        CC_FREE (f->cyc_inv, int);
+    f->cycle_size = 0;
+    f->short_size = 0;
+    f->reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int flipper_next (flipper *f, int x)
+#else
+static int flipper_next (f, x)
+flipper *f;
+int x;
+#endif
+{
+    int y;
+
+    if (f->reversed) {
+        y = f->cyc_inv[x] - 1;
+        return (y >= 0) ? f->cyc[y] : f->cyc[f->cycle_size - 1];
+    } else {
+        y = f->cyc_inv[x] + 1;
+        return (y < f->cycle_size) ? f->cyc[y] : f->cyc[0];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int flipper_prev (flipper *f, int x)
+#else
+static int flipper_prev (f, x)
+flipper *f;
+int x;
+#endif
+{
+    int y;
+
+    if (f->reversed) {
+        y = f->cyc_inv[x] + 1;
+        return (y < f->cycle_size) ? f->cyc[y] : f->cyc[0];
+    } else {
+        y = f->cyc_inv[x] - 1;
+        return (y >= 0) ? f->cyc[y] : f->cyc[f->cycle_size - 1];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper_flip (flipper *f, int x, int y)
+#else
+static void flipper_flip (f, x, y)
+flipper *f;
+int x, y;
+#endif
+{
+    int xloc = f->cyc_inv[x];
+    int yloc = f->cyc_inv[y];
+    int temp;
+    int gap;
+
+    if (f->reversed) {
+        SWAP (xloc, yloc, temp);
+    }
+    gap = yloc - xloc;
+    if (gap < 0)
+        gap += f->cycle_size;
+    if (gap > f->short_size) {
+        SWAP (xloc, yloc, temp);
+        f->reversed ^= 1;
+        xloc++;
+        if (xloc >= f->cycle_size)
+            xloc = 0;
+        yloc--;
+        if (yloc < 0)
+            yloc = f->cycle_size - 1;
+        gap = f->cycle_size - gap - 2;
+    }
+
+    if (xloc > yloc) {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = f->cyc[xloc];
+            y = f->cyc[yloc];
+            f->cyc[xloc] = y;
+            f->cyc[yloc] = x;
+            f->cyc_inv[x] = yloc--;
+            f->cyc_inv[y] = xloc++;
+            if (xloc >= f->cycle_size)
+                xloc = 0;
+            if (yloc < 0)
+                yloc = f->cycle_size - 1;
+        }
+    } else {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = f->cyc[xloc];
+            y = f->cyc[yloc];
+            f->cyc[xloc] = y;
+            f->cyc[yloc] = x;
+            f->cyc_inv[x] = yloc--;
+            f->cyc_inv[y] = xloc++;
+        }
+    }
+
+/*
+    while (gap > 0) {
+        SWAP (f->cyc[xloc], f->cyc[yloc], temp);
+        SWAP (f->cyc_inv[cyc[xloc]], f->cyc_inv[cyc[yloc]], temp);
+        xloc++;
+        if (xloc >= f->cycle_size)
+            xloc = 0;
+        yloc--;
+        if (yloc < 0)
+            yloc = f->cycle_size - 1;
+        gap -= 2;
+    }
+*/
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int flipper_sequence (flipper *f, int x, int y, int z)
+#else
+static int flipper_sequence (f, x, y, z)
+flipper *f;
+int x, y, z;
+#endif
+{
+    int xloc = f->cyc_inv[x];
+    int yloc = f->cyc_inv[y];
+    int zloc = f->cyc_inv[z];
+
+    if (f->reversed) {
+        if (xloc >= yloc)
+            return yloc >= zloc || zloc >= xloc;
+        else
+            return yloc >= zloc && zloc >= xloc;
+    } else {
+        if (xloc <= yloc)
+            return yloc <= zloc || zloc <= xloc;
+        else
+            return yloc <= zloc && zloc <= xloc;
+    }
+}
+
+
diff --git a/contrib/blossom/concorde97/LINKERN/Makefile b/contrib/blossom/concorde97/LINKERN/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4faaca30def4564581cf7b97741c5f69b2c74b53
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/Makefile
@@ -0,0 +1,72 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=linkern.a
+LIBSRCS=linkern.c flip_two.c
+ALLSRCS=lk_main.c  linkern.c  flip_ary.c flip_bt0.c flip_bt1.c \
+        flip_bt2.c flip_bt3.c flip_bt4.c flip_bt5.c flip_btc.c \
+        flip_btd.c flip_btr.c flip_ll0.c flip_ll1.c flip_ll2.c \
+        flip_ll3.c flip_ll4.c flip_ll5.c flip_ll6.c flip_ll7.c \
+        flip_ll8.c flip_ll9.c flip_llA.c flip_llB.c flip_llC.c \
+        flip_llD.c flip_sg1.c flip_sg2.c flip_sg3.c flip_sp1.c \
+        flip_sp2.c flip_try.c flip_tw2.c flip_two.c
+
+LIBS=$(ROOT)/EDGEGEN/edgegen.a $(ROOT)/KDTREE/kdtree.a \
+     $(ROOT)/FMATCH/fmatch.a   $(ROOT)/UTIL/util.a
+
+all: linkern $(LIB)
+
+linkern: lk_main.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ -lm
+
+clean:
+	-rm -f *.$o $(LIB) linkern
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+flip_ary.$o: flip_ary.c $(I)/machdefs.h $(I)/util.h     
+flip_bt0.$o: flip_bt0.c $(I)/machdefs.h $(I)/util.h     
+flip_bt1.$o: flip_bt1.c $(I)/machdefs.h $(I)/util.h     
+flip_bt2.$o: flip_bt2.c $(I)/machdefs.h $(I)/util.h     
+flip_bt3.$o: flip_bt3.c $(I)/machdefs.h $(I)/util.h     
+flip_bt4.$o: flip_bt4.c $(I)/machdefs.h $(I)/util.h     
+flip_bt5.$o: flip_bt5.c $(I)/machdefs.h $(I)/util.h     
+flip_btc.$o: flip_btc.c $(I)/machdefs.h $(I)/util.h     
+flip_btd.$o: flip_btd.c $(I)/machdefs.h $(I)/util.h     
+flip_btr.$o: flip_btr.c $(I)/machdefs.h $(I)/util.h     
+flip_ll0.$o: flip_ll0.c $(I)/machdefs.h $(I)/util.h     
+flip_ll1.$o: flip_ll1.c $(I)/machdefs.h $(I)/util.h     
+flip_ll2.$o: flip_ll2.c $(I)/machdefs.h $(I)/util.h     
+flip_ll3.$o: flip_ll3.c $(I)/machdefs.h $(I)/util.h     
+flip_ll4.$o: flip_ll4.c $(I)/machdefs.h $(I)/util.h     
+flip_ll5.$o: flip_ll5.c $(I)/machdefs.h $(I)/util.h     
+flip_ll6.$o: flip_ll6.c $(I)/machdefs.h $(I)/util.h     
+flip_ll7.$o: flip_ll7.c $(I)/machdefs.h $(I)/util.h     
+flip_ll8.$o: flip_ll8.c $(I)/machdefs.h $(I)/util.h     
+flip_ll9.$o: flip_ll9.c $(I)/machdefs.h $(I)/util.h     
+flip_llA.$o: flip_llA.c $(I)/machdefs.h $(I)/util.h     
+flip_llB.$o: flip_llB.c $(I)/machdefs.h $(I)/util.h     
+flip_llC.$o: flip_llC.c $(I)/machdefs.h $(I)/util.h     
+flip_llD.$o: flip_llD.c $(I)/machdefs.h $(I)/util.h     
+flip_sg1.$o: flip_sg1.c $(I)/machdefs.h $(I)/util.h     
+flip_sg2.$o: flip_sg2.c $(I)/machdefs.h $(I)/util.h     
+flip_sg3.$o: flip_sg3.c $(I)/machdefs.h $(I)/util.h     
+flip_sp1.$o: flip_sp1.c $(I)/machdefs.h $(I)/util.h     
+flip_sp2.$o: flip_sp2.c $(I)/machdefs.h $(I)/util.h     
+flip_try.$o: flip_try.c $(I)/machdefs.h $(I)/util.h     
+flip_tw2.$o: flip_tw2.c $(I)/machdefs.h $(I)/util.h     
+flip_two.$o: flip_two.c $(I)/machdefs.h $(I)/util.h     $(I)/linkern.h  
+linkern.$o:  linkern.c  $(I)/machdefs.h $(I)/util.h     $(I)/linkern.h  \
+        $(I)/kdtree.h   
+lk_main.$o:  lk_main.c  $(I)/machdefs.h $(I)/util.h     $(I)/linkern.h  \
+        $(I)/kdtree.h   $(I)/edgegen.h  
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ary.c b/contrib/blossom/concorde97/LINKERN/flip_ary.c
new file mode 100644
index 0000000000000000000000000000000000000000..4dc5b53508f2504cd5837e28fe11745a44a697d5
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ary.c
@@ -0,0 +1,360 @@
+/***************************************************************************/
+/*                                                                         */
+/*       TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Basic Array         */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: April 21, 1995 (but mainly from March, 1990)                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int x, int y)                            */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version uses very little memory, and is reasonably fast      */
+/*   for small problems and for twoopts (but you should have SHORT_SIDE    */
+/*   defined so that the smaller side a flip is carried out.               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#define SHORT_SIDE
+
+/***************************************************************************/
+/*                                                                         */
+/* ARRAY FLIPPER (flipper2):                                               */
+/*                                                                         */
+/*     1. Uses a raw cycle and its inverse.                                */
+/*                                                                         */
+/***************************************************************************/
+
+/***************************************************************************/
+/*                                                                         */
+/* SHORT-SIDE-ARRAY FLIPPER (flipper3):                                    */
+/*                                                                         */
+/*     1. Uses a raw cycle and its inverse, but flips the shorter side.    */
+/*                                                                         */
+/*     2. Define SHORT_SIDE to use this.                                   */
+/*                                                                         */
+/***************************************************************************/
+
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static int cycle_size = 0;
+#ifdef SHORT_SIDE
+static int reversed = 0;
+static int short_size = 0;
+#endif
+static int *flip3_cyc = (int *) NULL;
+static int *flip3_cyc_inv = (int *) NULL;
+
+#ifdef WE_WANT_FLIP_STATS
+int CClinkern_flipper_size (int a, int b);
+#endif WE_WANT_FLIP_STATS
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    flip3_cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!flip3_cyc)
+        return 1;
+    flip3_cyc_inv = CC_SAFE_MALLOC (ncount, int);
+    if (!flip3_cyc_inv) {
+        CC_FREE (cyc, int);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        flip3_cyc[i] = cyc[i];
+        flip3_cyc_inv[cyc[i]] = i;
+    }
+    cycle_size = ncount;
+#ifdef SHORT_SIDE
+    short_size = ncount/2;
+    reversed = 0;
+#endif
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    int *p;
+
+#ifdef SHORT_SIDE
+    if (reversed) {
+        p = flip3_cyc + cycle_size;
+        while (p > flip3_cyc) {
+            *x++ = *--p;
+        }
+    } else {
+#endif
+        p = flip3_cyc + cycle_size;
+        x += cycle_size;
+        while (p > flip3_cyc) {
+            *--x = *--p;
+        }
+#ifdef SHORT_SIDE
+    }
+#endif
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    CC_FREE (flip3_cyc, int);
+    CC_FREE (flip3_cyc_inv, int);
+    cycle_size = 0;
+#ifdef SHORT_SIDE
+    short_size = 0;
+    reversed = 0;
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    int y;
+
+#ifdef SHORT_SIDE
+    if (reversed) {
+        y = flip3_cyc_inv[x] - 1;
+        return (y >= 0) ? flip3_cyc[y] : flip3_cyc[cycle_size-1];
+    } else {
+#endif
+        y = flip3_cyc_inv[x] + 1;
+        return (y < cycle_size) ? flip3_cyc[y] : flip3_cyc[0];
+#ifdef SHORT_SIDE
+    }
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    int y;
+
+#ifdef SHORT_SIDE
+    if (reversed) {
+        y = flip3_cyc_inv[x] + 1;
+        return (y < cycle_size) ? flip3_cyc[y] : flip3_cyc[0];
+    } else {
+#endif
+        y = flip3_cyc_inv[x] - 1;
+        return (y >= 0) ? flip3_cyc[y] : flip3_cyc[cycle_size-1];
+#ifdef SHORT_SIDE
+    }
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int x, int y)
+#else
+void CClinkern_flipper_flip (x, y)
+int x,y;
+#endif
+{
+    int xloc = flip3_cyc_inv[x];
+    int yloc = flip3_cyc_inv[y];
+    int temp;
+    int gap;
+
+#ifdef SHORT_SIDE
+    if (reversed) {
+        SWAP (xloc, yloc, temp);
+    }
+    gap = yloc - xloc;
+    if (gap < 0) gap += cycle_size;
+    if (gap > short_size) {
+        SWAP (xloc, yloc, temp);
+        reversed ^= 1;
+        xloc++;
+        if (xloc >= cycle_size)
+            xloc = 0;
+        yloc--;
+        if (yloc < 0)
+            yloc = cycle_size - 1;
+        gap = cycle_size - gap - 2;
+    }
+
+    if (xloc > yloc) {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip3_cyc[xloc];
+            y = flip3_cyc[yloc];
+            flip3_cyc[xloc] = y;
+            flip3_cyc[yloc] = x;
+            flip3_cyc_inv[x] = yloc--;
+            flip3_cyc_inv[y] = xloc++;
+            if (xloc >= cycle_size)
+                xloc = 0;
+            if (yloc < 0)
+                yloc = cycle_size - 1;
+        }
+    } else {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip3_cyc[xloc];
+            y = flip3_cyc[yloc];
+            flip3_cyc[xloc] = y;
+            flip3_cyc[yloc] = x;
+            flip3_cyc_inv[x] = yloc--;
+            flip3_cyc_inv[y] = xloc++;
+        }
+    }
+#else
+    if (xloc > yloc) {
+        gap = yloc - xloc + cycle_size;
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip3_cyc[xloc];
+            y = flip3_cyc[yloc];
+            flip3_cyc[xloc] = y;
+            flip3_cyc[yloc] = x;
+            flip3_cyc_inv[x] = yloc--;
+            flip3_cyc_inv[y] = xloc++;
+            if (xloc >= cycle_size)
+                xloc = 0;
+            if (yloc < 0)
+                yloc = cycle_size - 1;
+        }
+    } else {
+        gap = yloc - xloc;
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip3_cyc[xloc];
+            y = flip3_cyc[yloc];
+            flip3_cyc[xloc] = y;
+            flip3_cyc[yloc] = x;
+            flip3_cyc_inv[x] = yloc--;
+            flip3_cyc_inv[y] = xloc++;
+        }
+    }
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    int xloc = flip3_cyc_inv[x];
+    int yloc = flip3_cyc_inv[y];
+    int zloc = flip3_cyc_inv[z];
+
+#ifdef SHORT_SIDE
+    if (reversed) {
+        if (xloc >= yloc)
+            return yloc >= zloc || zloc >= xloc;
+        else
+            return yloc >= zloc && zloc >= xloc;
+    } else {
+#endif
+        if (xloc <= yloc)
+            return yloc <= zloc || zloc <= xloc;
+        else
+            return yloc <= zloc && zloc <= xloc;
+#ifdef SHORT_SIDE
+    }
+#endif
+}
+
+#ifdef WE_WANT_FLIP_STATS
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_size (int x, int y)
+#else
+int CClinkern_flipper_size (x, y)
+int x,y;
+#endif
+{
+    int xloc = flip3_cyc_inv[x];
+    int yloc = flip3_cyc_inv[y];
+    int temp, gap;
+
+    if (reversed) {
+        SWAP (xloc, yloc, temp);
+    }
+    gap = yloc - xloc;
+    if (gap < 0) gap += cycle_size;
+    if (gap > short_size) {
+        gap = cycle_size - gap - 2;
+    }
+
+    return gap + 1;
+}
+#endif /* WE_WANT_FLIP_STATS */
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_bt0.c b/contrib/blossom/concorde97/LINKERN/flip_bt0.c
new file mode 100644
index 0000000000000000000000000000000000000000..2dc5aef8ebffbd78a624c33ee9b25428a5135fdb
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_bt0.c
@@ -0,0 +1,556 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define SAVE_NEIGHBORS */
+#define INLINE_CLEAR_TO_ROOT
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+#ifdef INLINE_CLEAR_TO_ROOT
+    struct btree *next;
+#endif
+#ifdef SAVE_NEIGHBORS
+    struct btree *neigh[2];
+#endif
+    int reversed;
+    int value;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right);
+
+static void
+    join (btree *left, btree *i, btree *right),
+    reverse (btree *p),
+    clearrev_toroot (btree *p);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split ();
+
+static void
+    join (),
+    reverse (),
+    clearrev_toroot ();
+
+#endif
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static int btree_size;
+static btree *root = (btree *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+/*
+    printf ("Flipper flags:");
+#ifdef SAVE_NEIGHBORS
+    printf (" SAVE_NEIGHBORS");
+#else
+    printf (" !SAVE_NEIGHBORS");
+#endif
+*/
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    btree_size = ncount;
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].value = i;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            btree_space[cyc[0]].neigh[0] = &btree_space[cyc[ncount-1]];
+            btree_space[cyc[ncount-1]].neigh[1] = &btree_space[cyc[0]];
+        } else {
+            btree_space[cyc[i]].neigh[0] = &btree_space[cyc[i-1]];
+            btree_space[cyc[i-1]].neigh[1] = &btree_space[cyc[i]];
+        }
+#endif
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (!p)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    CC_IFFREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *temp, *temp2;
+    btree *a, *b, *c, *d;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+#ifdef SAVE_NEIGHBORS
+    temp = px->neigh[0];
+    temp2 = py->neigh[1];
+    px->neigh[0] = px->neigh[1];
+    py->neigh[1] = py->neigh[0];
+    py->neigh[0] = temp;
+    px->neigh[1] = temp2;
+    if (temp->neigh[0] == px) temp->neigh[0] = py;
+    else temp->neigh[1] = py;
+    if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+    else temp2->neigh[1] = px;
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d, *e, *f;
+    btree *r;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b */
+        r = split (&e, pz, &f);
+        if (r == c) { /* e z f y d x b */
+            join (e, pz, f);
+            join (d, px, b);
+            join (pz, py, px);
+            root = py;
+            return 0;
+        } else if (r == d) { /* c y e z f x b */
+            join (c, py, e);
+            join (f, px, b);
+            join (py, pz, px);
+            root = pz;
+            return 1;
+        } else { /* c y d x e z f */
+            join (c, py, d);
+            join (e, pz, f);
+            join (py, px, pz);
+            root = px;
+            return 0;
+        }
+    } else { /* a x c y d */
+        r = split (&e, pz, &f);
+        if (r == a) { /* e z f x c y d */
+            join (e, pz, f);
+            join (c, py, d);
+            join (pz, px, py);
+            root = px;
+            return 1;
+        } else if (r == c) { /* a x e z f y d */
+            join (a, px, e);
+            join (f, py, d);
+            join (px, pz, py);
+            root = pz;
+            return 0;
+        } else { /* a x c y e z f */
+            join (a, px, c);
+            join (e, pz, f);
+            join (px, py, pz);
+            root = py;
+            return 1;
+        }
+    }
+}
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   void reverse (btree *p)                                               */
+/*     toggles the reversal bit of node p (and fixes the tree).            */
+/*   void clearrev_toroot (btree *p)                                       */
+/*     clears the reversal bits on the path from p to the root (and fixes  */
+/*     the tree).                                                          */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return (btree *) NULL;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    if ((p->child[0] = make_tree (a, center-1, cyc)) != (btree *) NULL)
+        p->child[0]->parent = p;
+    if ((p->child[1] = make_tree (center+1, b, cyc)) != (btree *) NULL)
+        p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+    btree *isave = i;
+
+    clearrev_toroot (i);
+    l = i->child[0];
+    r = i->child[1];
+    i->child[0] = (btree *) NULL;
+    i->child[1] = (btree *) NULL;
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            if (r) r->parent = p;
+            r = p;
+        } else {
+            p->child[1] = l;
+            if (l) l->parent = p;
+            l = p;
+        }
+        i = p;
+    }
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+    if (isave) isave->parent = (btree *) NULL;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void reverse (btree *p)
+#else
+static void reverse (p)
+btree *p;
+#endif
+{
+    btree *t;
+
+    SWAP(p->child[0], p->child[1], t);
+    if (p->child[0]) p->child[0]->reversed ^= 1;
+    if (p->child[1]) p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], t);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clearrev_toroot (btree *p)
+#else
+static void clearrev_toroot (p)
+btree *p;
+#endif
+{
+#ifndef INLINE_CLEAR_TO_ROOT
+    if (p->parent) clearrev_toroot (p->parent);
+    if (p->reversed) reverse (p);
+#else
+    p->next = (btree *) NULL;
+    while (p->parent) {
+        p->parent->next = p;
+        p = p->parent;
+    }
+    while (p) {
+        if (p->reversed) reverse (p);
+        p = p->next;
+    }
+#endif
+}
+
+
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_bt1.c b/contrib/blossom/concorde97/LINKERN/flip_bt1.c
new file mode 100644
index 0000000000000000000000000000000000000000..ce966c4b7a408dc31422736eeeda3416c03056b9
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_bt1.c
@@ -0,0 +1,615 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                              - added tests for depth    */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes CClinkern_flipper1 to an initial cycle given in cyc.    */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define SAVE_NEIGHBORS */
+#define INLINE_CLEAR_TO_ROOT
+#define REPORT_DEPTH
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+#ifdef INLINE_CLEAR_TO_ROOT
+    struct btree *next;
+#endif
+#ifdef SAVE_NEIGHBORS
+    struct btree *neigh[2];
+#endif
+    int reversed;
+    int value;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right);
+
+static void
+    join (btree *left, btree *i, btree *right),
+    reverse (btree *p),
+    clearrev_toroot (btree *p);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split ();
+
+static void
+    join (),
+    reverse (),
+    clearrev_toroot ();
+
+#endif
+
+#ifdef    REPORT_DEPTH
+
+static double probecount = 1.0;
+static double probedepth = 1.0;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    find_depth (int x);
+#else
+static void
+    find_depth ();
+#endif
+
+#endif /* REPORT_DEPTH */
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static int btree_size;
+static btree *root = (btree *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+/*
+    printf ("Flipper flags:");
+#ifdef SAVE_NEIGHBORS
+    printf (" SAVE_NEIGHBORS");
+#else
+    printf (" !SAVE_NEIGHBORS");
+#endif
+*/
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    btree_size = ncount;
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].value = i;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            btree_space[cyc[0]].neigh[0] = &btree_space[cyc[ncount-1]];
+            btree_space[cyc[ncount-1]].neigh[1] = &btree_space[cyc[0]];
+        } else {
+            btree_space[cyc[i]].neigh[0] = &btree_space[cyc[i-1]];
+            btree_space[cyc[i-1]].neigh[1] = &btree_space[cyc[i]];
+        }
+#endif
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (!p)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    printf ("Number of Probes: %.0f   Average Depth: %.2f\n",
+             probecount, probedepth / probecount);
+    fflush (stdout);
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (btree_space)
+        CC_FREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef REPORT_DEPTH
+#ifdef CC_PROTOTYPE_ANSI
+static void find_depth (int x)
+#else
+static void find_depth (x)
+int x;
+#endif
+{
+    btree *q = btree_space + x;
+
+    probecount += 1.0;
+    while (q) {
+        probedepth += 1.0;
+        q = q->parent;
+    }
+}
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *temp, *temp2;
+    btree *a, *b, *c, *d;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+#endif
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+#ifdef SAVE_NEIGHBORS
+    temp = px->neigh[0];
+    temp2 = py->neigh[1];
+    px->neigh[0] = px->neigh[1];
+    py->neigh[1] = py->neigh[0];
+    py->neigh[0] = temp;
+    px->neigh[1] = temp2;
+    if (temp->neigh[0] == px) temp->neigh[0] = py;
+    else temp->neigh[1] = py;
+    if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+    else temp2->neigh[1] = px;
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d, *e, *f;
+    btree *r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+    find_depth (z);
+#endif
+
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b */
+        r = split (&e, pz, &f);
+        if (r == c) { /* e z f y d x b */
+            join (e, pz, f);
+            join (d, px, b);
+            join (pz, py, px);
+            root = py;
+            return 0;
+        } else if (r == d) { /* c y e z f x b */
+            join (c, py, e);
+            join (f, px, b);
+            join (py, pz, px);
+            root = pz;
+            return 1;
+        } else { /* c y d x e z f */
+            join (c, py, d);
+            join (e, pz, f);
+            join (py, px, pz);
+            root = px;
+            return 0;
+        }
+    } else { /* a x c y d */
+        r = split (&e, pz, &f);
+        if (r == a) { /* e z f x c y d */
+            join (e, pz, f);
+            join (c, py, d);
+            join (pz, px, py);
+            root = px;
+            return 1;
+        } else if (r == c) { /* a x e z f y d */
+            join (a, px, e);
+            join (f, py, d);
+            join (px, pz, py);
+            root = pz;
+            return 0;
+        } else { /* a x c y e z f */
+            join (a, px, c);
+            join (e, pz, f);
+            join (px, py, pz);
+            root = py;
+            return 1;
+        }
+    }
+}
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   void reverse (btree *p)                                               */
+/*     toggles the reversal bit of node p (and fixes the tree).            */
+/*   void clearrev_toroot (btree *p)                                       */
+/*     clears the reversal bits on the path from p to the root (and fixes  */
+/*     the tree).                                                          */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return (btree *) NULL;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    if ((p->child[0] = make_tree (a, center-1, cyc)) != (btree *) NULL)
+        p->child[0]->parent = p;
+    if ((p->child[1] = make_tree (center+1, b, cyc)) != (btree *) NULL)
+        p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+    btree *isave = i;
+
+    clearrev_toroot (i);
+    l = i->child[0];
+    r = i->child[1];
+    i->child[0] = (btree *) NULL;
+    i->child[1] = (btree *) NULL;
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            if (r) r->parent = p;
+            r = p;
+        } else {
+            p->child[1] = l;
+            if (l) l->parent = p;
+            l = p;
+        }
+        i = p;
+    }
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+    if (isave) isave->parent = (btree *) NULL;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void reverse (btree *p)
+#else
+static void reverse (p)
+btree *p;
+#endif
+{
+    btree *t;
+
+    SWAP(p->child[0], p->child[1], t);
+    if (p->child[0]) p->child[0]->reversed ^= 1;
+    if (p->child[1]) p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], t);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clearrev_toroot (btree *p)
+#else
+static void clearrev_toroot (p)
+btree *p;
+#endif
+{
+#ifndef INLINE_CLEAR_TO_ROOT
+    if (p->parent) clearrev_toroot (p->parent);
+    if (p->reversed) reverse (p);
+#else
+    p->next = (btree *) NULL;
+    while (p->parent) {
+        p->parent->next = p;
+        p = p->parent;
+    }
+    while (p) {
+        if (p->reversed) reverse (p);
+        p = p->next;
+    }
+#endif
+}
+
+
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_bt2.c b/contrib/blossom/concorde97/LINKERN/flip_bt2.c
new file mode 100644
index 0000000000000000000000000000000000000000..1b8d4264af41aec84588b3a0bbe0980eca79d962
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_bt2.c
@@ -0,0 +1,858 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                              - added tests for depth    */
+/*                                              - added splays for seq     */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define SAVE_NEIGHBORS */
+/* #define INLINE_CLEAR_TO_ROOT */
+#define REPORT_DEPTH
+#define USE_SPLAY_SEQUENCE
+#define USE_SPLAY_FLIPS
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+#ifdef INLINE_CLEAR_TO_ROOT
+    struct btree *next;
+#endif
+#ifdef SAVE_NEIGHBORS
+    struct btree *neigh[2];
+#endif
+    int reversed;
+    int value;
+    int mark;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right);
+
+static void
+    join (btree *left, btree *i, btree *right),
+    reverse (btree *p),
+    clearrev_toroot (btree *p);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split ();
+
+static void
+    join (),
+    reverse (),
+    clearrev_toroot ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    rotate (btree *x, btree *px),
+    splay (btree *x);
+
+#else
+
+static void
+    rotate (),
+    splay ();
+
+#endif
+
+#ifdef    REPORT_DEPTH
+
+static double probecount = 1.0;
+static double probedepth = 1.0;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    find_depth (int x);
+#else
+static void
+    find_depth ();
+#endif
+
+#endif /* REPORT_DEPTH */
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static int btree_size;
+static btree *root = (btree *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+/*
+    printf ("Flipper flags:");
+#ifdef SAVE_NEIGHBORS
+    printf (" SAVE_NEIGHBORS");
+#else
+    printf (" !SAVE_NEIGHBORS");
+#endif
+*/
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    btree_size = ncount;
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].value = i;
+        btree_space[i].mark = 0;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            btree_space[cyc[0]].neigh[0] = &btree_space[cyc[ncount-1]];
+            btree_space[cyc[ncount-1]].neigh[1] = &btree_space[cyc[0]];
+        } else {
+            btree_space[cyc[i]].neigh[0] = &btree_space[cyc[i-1]];
+            btree_space[cyc[i-1]].neigh[1] = &btree_space[cyc[i]];
+        }
+#endif
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (!p)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+#ifdef REPORT_DEPTH
+    printf ("Number of Probes: %.0f   Average Depth: %.2f\n",
+             probecount, probedepth / probecount);
+    fflush (stdout);
+#endif
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (btree_space)
+        CC_FREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef REPORT_DEPTH
+#ifdef CC_PROTOTYPE_ANSI
+static void find_depth (int x)
+#else
+static void find_depth (x)
+int x;
+#endif
+{
+    btree *q = btree_space + x;
+
+    probecount += 1.0;
+    while (q) {
+        probedepth += 1.0;
+        q = q->parent;
+    }
+}
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef USE_SPLIT_FLIPS
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+#ifdef SAVE_NEIGHBORS
+    btree *temp, *temp2;
+#endif
+    btree *a, *b, *c, *d;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+#endif
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+#ifdef SAVE_NEIGHBORS
+    temp = px->neigh[0];
+    temp2 = py->neigh[1];
+    px->neigh[0] = px->neigh[1];
+    py->neigh[1] = py->neigh[0];
+    py->neigh[0] = temp;
+    px->neigh[1] = temp2;
+    if (temp->neigh[0] == px) temp->neigh[0] = py;
+    else temp->neigh[1] = py;
+    if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+    else temp2->neigh[1] = px;
+#endif
+}
+#endif  /* USE_SPLIT_FLIPS */
+
+#ifdef USE_SPLAY_FLIPS
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *temp;
+#ifdef SAVE_NEIGHBORS
+    btree *temp2;
+#endif
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    splay (px);
+    px->mark = 1;
+    splay (py);
+    px->mark = 0;
+
+    if (px->reversed)
+        reverse (px);
+    if (py->reversed)
+        reverse (py);
+    if (px->child[1] == py) {
+#ifdef SAVE_NEIGHBORS
+        temp = px->neigh[0];
+        temp2 = py->neigh[1];
+        px->neigh[0] = px->neigh[1];
+        py->neigh[1] = py->neigh[0];
+        py->neigh[0] = temp;
+        px->neigh[1] = temp2;
+        if (temp->neigh[0] == px) temp->neigh[0] = py;
+        else temp->neigh[1] = py;
+        if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+        else temp2->neigh[1] = px;
+#endif
+        if (py->child[0])
+            py->child[0]->reversed ^= 1;
+        SWAP (px->child[0], py->child[0], temp);
+        if (px->child[0])
+            px->child[0]->parent = px;
+        if (py->child[0])
+            py->child[0]->parent = py;
+        px->child[1] = py->child[1];
+        if (px->child[1])
+            px->child[1]->parent = px;
+        py->child[1] = px;
+        px->parent = py;
+        py->parent = (btree *) NULL;
+        root = py;
+    } else {
+#ifdef SAVE_NEIGHBORS
+        temp = px->neigh[0];
+        temp2 = py->neigh[1];
+        py->neigh[1] = temp;
+        px->neigh[0] = temp2;
+        if (temp->neigh[0] == px) temp->neigh[0] = py;
+        else temp->neigh[1] = py;
+        if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+        else temp2->neigh[1] = px;
+#endif
+        px->reversed ^= 1;
+        py->child[1]->reversed ^= 1;
+    }
+}
+#endif  /* USE_SPLAY_FLIPS */
+
+#ifdef USE_SPLIT_SEQUENCE
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d, *e, *f;
+    btree *r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+    find_depth (z);
+#endif
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b */
+        r = split (&e, pz, &f);
+        if (r == c) { /* e z f y d x b */
+            join (e, pz, f);
+            join (d, px, b);
+            join (pz, py, px);
+            root = py;
+            return 0;
+        } else if (r == d) { /* c y e z f x b */
+            join (c, py, e);
+            join (f, px, b);
+            join (py, pz, px);
+            root = pz;
+            return 1;
+        } else { /* c y d x e z f */
+            join (c, py, d);
+            join (e, pz, f);
+            join (py, px, pz);
+            root = px;
+            return 0;
+        }
+    } else { /* a x c y d */
+        r = split (&e, pz, &f);
+        if (r == a) { /* e z f x c y d */
+            join (e, pz, f);
+            join (c, py, d);
+            join (pz, px, py);
+            root = px;
+            return 1;
+        } else if (r == c) { /* a x e z f y d */
+            join (a, px, e);
+            join (f, py, d);
+            join (px, pz, py);
+            root = pz;
+            return 0;
+        } else { /* a x c y e z f */
+            join (a, px, c);
+            join (e, pz, f);
+            join (px, py, pz);
+            root = py;
+            return 1;
+        }
+    }
+}
+#endif
+
+#ifdef USE_SPLAY_SEQUENCE
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    splay (px);
+    px->mark = 1;
+    splay (pz);
+    px->mark = 0;
+
+    if (px->reversed)
+        reverse (px);
+    if (pz->reversed)
+        reverse (pz);
+
+    for (;;) {
+        if (py->parent == px) {
+            return px->child[1] == py;
+        } else if (py->parent == pz) {
+            return pz->child[0] == py;
+        } else {
+            py = py->parent;
+        }
+    }
+}
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   void reverse (btree *p)                                               */
+/*     toggles the reversal bit of node p (and fixes the tree).            */
+/*   void clearrev_toroot (btree *p)                                       */
+/*     clears the reversal bits on the path from p to the root (and fixes  */
+/*     the tree).                                                          */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return (btree *) NULL;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    if ((p->child[0] = make_tree (a, center-1, cyc)) != (btree *) NULL)
+        p->child[0]->parent = p;
+    if ((p->child[1] = make_tree (center+1, b, cyc)) != (btree *) NULL)
+        p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+    btree *isave = i;
+
+    clearrev_toroot (i);
+    l = i->child[0];
+    r = i->child[1];
+    i->child[0] = (btree *) NULL;
+    i->child[1] = (btree *) NULL;
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            if (r) r->parent = p;
+            r = p;
+        } else {
+            p->child[1] = l;
+            if (l) l->parent = p;
+            l = p;
+        }
+        i = p;
+    }
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+    if (isave) isave->parent = (btree *) NULL;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void reverse (btree *p)
+#else
+static void reverse (p)
+btree *p;
+#endif
+{
+    btree *t;
+
+    SWAP(p->child[0], p->child[1], t);
+    if (p->child[0]) p->child[0]->reversed ^= 1;
+    if (p->child[1]) p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], t);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clearrev_toroot (btree *p)
+#else
+static void clearrev_toroot (p)
+btree *p;
+#endif
+{
+#ifndef INLINE_CLEAR_TO_ROOT
+    if (p->parent) clearrev_toroot (p->parent);
+    if (p->reversed) reverse (p);
+#else
+    p->next = (btree *) NULL;
+    while (p->parent) {
+        p->parent->next = p;
+        p = p->parent;
+    }
+    while (p) {
+        if (p->reversed) reverse (p);
+        p = p->next;
+    }
+#endif
+}
+
+
+/************************* SPLAY STUFF ****************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static void rotate (btree *x, btree *px)
+#else
+static void rotate (x, px)
+btree *x, *px;
+#endif
+{
+    btree *b;
+
+    if (px->child[0] == x) {
+        b = x->child[1];
+        if (b)
+            b->parent = px;
+        x->child[1] = px;
+        x->parent = px->parent;
+        if (x->parent) {
+            if (x->parent->child[0] == px) {
+                x->parent->child[0] = x;
+            } else {
+                x->parent->child[1] = x;
+            }
+        }
+        px->child[0] = b;
+        px->parent = x;
+    } else {
+        b = x->child[0];
+        if (b)
+            b->parent = px;
+        x->child[0] = px;
+        x->parent = px->parent;
+        if (x->parent) {
+            if (x->parent->child[0] == px) {
+                x->parent->child[0] = x;
+            } else {
+                x->parent->child[1] = x;
+            }
+        }
+        px->child[1] = b;
+        px->parent = x;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void splay (btree *x)
+#else
+static void splay (x)
+btree *x;
+#endif
+{
+    btree *px;
+    btree *ppx;
+
+    for (;;) {
+        px = x->parent;
+        if (!px) {
+            root = x;
+            return;
+        }
+        if (px->mark)
+            return;
+        ppx = px->parent;
+        if (!ppx) {
+            if (px->reversed)
+                reverse (px);
+            if (x->reversed)
+                reverse (x);
+            rotate (x, px);
+            root = x;
+            return;
+        }
+        if (ppx->mark) {
+            if (px->reversed)
+                reverse (px);
+            if (x->reversed)
+                reverse (x);
+            rotate (x, px);
+            return;
+        }
+        if (ppx->reversed)
+            reverse (ppx);
+        if (px->reversed)
+            reverse (px);
+        if (x->reversed)
+            reverse (x);
+        if (ppx->child[0] == px) {
+            if (px->child[0] == x) {
+                rotate (px, ppx);
+                rotate (x, px);
+            } else {
+                rotate (x, px);
+                rotate (x, ppx);
+            }
+        } else {
+            if (px->child[1] == x) {
+                rotate (px, ppx);
+                rotate (x, px);
+            } else {
+                rotate (x, px);
+                rotate (x, ppx);
+            }
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_bt3.c b/contrib/blossom/concorde97/LINKERN/flip_bt3.c
new file mode 100644
index 0000000000000000000000000000000000000000..8dd63a140b4f6dec357086736be0e10fac23816e
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_bt3.c
@@ -0,0 +1,617 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                              - added dummy children     */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define SAVE_NEIGHBORS */
+/* #define INLINE_CLEAR_TO_ROOT */
+/* #define REPORT_DEPTH */
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+#ifdef INLINE_CLEAR_TO_ROOT
+    struct btree *next;
+#endif
+#ifdef SAVE_NEIGHBORS
+    struct btree *neigh[2];
+#endif
+    int reversed;
+    int value;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right);
+
+static void
+    join (btree *left, btree *i, btree *right),
+    reverse (btree *p),
+    clearrev_toroot (btree *p);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split ();
+
+static void
+    join (),
+    reverse (),
+    clearrev_toroot ();
+
+#endif
+
+#ifdef    REPORT_DEPTH
+
+static double probecount = 1.0;
+static double probedepth = 1.0;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    find_depth (int x);
+#else
+static void
+    find_depth ();
+#endif
+
+#endif /* REPORT_DEPTH */
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static int btree_size;
+static btree *root = (btree *) NULL;
+static btree dummy_leaf;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+/*
+    printf ("Flipper flags:");
+#ifdef SAVE_NEIGHBORS
+    printf (" SAVE_NEIGHBORS");
+#else
+    printf (" !SAVE_NEIGHBORS");
+#endif
+*/
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    btree_size = ncount;
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].value = i;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            btree_space[cyc[0]].neigh[0] = &btree_space[cyc[ncount-1]];
+            btree_space[cyc[ncount-1]].neigh[1] = &btree_space[cyc[0]];
+        } else {
+            btree_space[cyc[i]].neigh[0] = &btree_space[cyc[i-1]];
+            btree_space[cyc[i-1]].neigh[1] = &btree_space[cyc[i]];
+        }
+#endif
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (p == &dummy_leaf)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+#ifdef REPORT_DEPTH
+    printf ("Number of Probes: %.0f   Average Depth: %.2f\n",
+             probecount, probedepth / probecount);
+    fflush (stdout);
+#endif
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (btree_space)
+        CC_FREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef REPORT_DEPTH
+#ifdef CC_PROTOTYPE_ANSI
+static void find_depth (int x)
+#else
+static void find_depth (x)
+int x;
+#endif
+{
+    btree *q = btree_space + x;
+
+    probecount += 1.0;
+    while (q) {
+        probedepth += 1.0;
+        q = q->parent;
+    }
+}
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext != &dummy_leaf) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext != &dummy_leaf) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+#ifdef SAVE_NEIGHBORS
+    btree *temp, *temp2;
+#endif
+    btree *a, *b, *c, *d;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+#endif
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+#ifdef SAVE_NEIGHBORS
+    temp = px->neigh[0];
+    temp2 = py->neigh[1];
+    px->neigh[0] = px->neigh[1];
+    py->neigh[1] = py->neigh[0];
+    py->neigh[0] = temp;
+    px->neigh[1] = temp2;
+    if (temp->neigh[0] == px) temp->neigh[0] = py;
+    else temp->neigh[1] = py;
+    if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+    else temp2->neigh[1] = px;
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d, *e, *f;
+    btree *r;
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+    find_depth (z);
+#endif
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b */
+        r = split (&e, pz, &f);
+        if (r == c) { /* e z f y d x b */
+            join (e, pz, f);
+            join (d, px, b);
+            join (pz, py, px);
+            root = py;
+            return 0;
+        } else if (r == d) { /* c y e z f x b */
+            join (c, py, e);
+            join (f, px, b);
+            join (py, pz, px);
+            root = pz;
+            return 1;
+        } else { /* c y d x e z f */
+            join (c, py, d);
+            join (e, pz, f);
+            join (py, px, pz);
+            root = px;
+            return 0;
+        }
+    } else { /* a x c y d */
+        r = split (&e, pz, &f);
+        if (r == a) { /* e z f x c y d */
+            join (e, pz, f);
+            join (c, py, d);
+            join (pz, px, py);
+            root = px;
+            return 1;
+        } else if (r == c) { /* a x e z f y d */
+            join (a, px, e);
+            join (f, py, d);
+            join (px, pz, py);
+            root = pz;
+            return 0;
+        } else { /* a x c y e z f */
+            join (a, px, c);
+            join (e, pz, f);
+            join (px, py, pz);
+            root = py;
+            return 1;
+        }
+    }
+}
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   void reverse (btree *p)                                               */
+/*     toggles the reversal bit of node p (and fixes the tree).            */
+/*   void clearrev_toroot (btree *p)                                       */
+/*     clears the reversal bits on the path from p to the root (and fixes  */
+/*     the tree).                                                          */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return &dummy_leaf;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    p->child[0] = make_tree (a, center-1, cyc);
+    p->child[0]->parent = p;
+    p->child[1] = make_tree (center+1, b, cyc);
+    p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    left->parent = i;
+    right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+    btree *isave = i;
+
+    clearrev_toroot (i);
+    l = i->child[0];
+    r = i->child[1];
+    i->child[0] = &dummy_leaf;
+    i->child[1] = &dummy_leaf;
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            r->parent = p;
+            r = p;
+        } else {
+            p->child[1] = l;
+            l->parent = p;
+            l = p;
+        }
+        i = p;
+    }
+    l->parent = (btree *) NULL;
+    r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+    isave->parent = (btree *) NULL;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void reverse (btree *p)
+#else
+static void reverse (p)
+btree *p;
+#endif
+{
+    btree *t;
+
+    SWAP(p->child[0], p->child[1], t);
+    p->child[0]->reversed ^= 1;
+    p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], t);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clearrev_toroot (btree *p)
+#else
+static void clearrev_toroot (p)
+btree *p;
+#endif
+{
+#ifndef INLINE_CLEAR_TO_ROOT
+    if (p->parent) clearrev_toroot (p->parent);
+    if (p->reversed) reverse (p);
+#else
+    p->next = (btree *) NULL;
+    while (p->parent) {
+        p->parent->next = p;
+        p = p->parent;
+    }
+    while (p) {
+        if (p->reversed) reverse (p);
+        p = p->next;
+    }
+#endif
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_bt4.c b/contrib/blossom/concorde97/LINKERN/flip_bt4.c
new file mode 100644
index 0000000000000000000000000000000000000000..11772e176405952689c7b56d45b2aef7bdf5152e
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_bt4.c
@@ -0,0 +1,1310 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                              - added dummy children     */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define TRACE */
+/* #define NEIGHTRACE */
+#define SAVE_NEIGHBORS
+/* #define REPORT_DEPTH */
+#define DUMMY_LEAF
+#define NO_CLEAR_TO_ROOT
+/* #define INLINE_CLEAR_TO_ROOT */
+/* #define INLINE_CLEAR_TO_ROOT2 */
+#define SKIMPY_NULLS
+/* #define MUNCHED_SEQUENCE_CODE */
+#define SEQUENCE_2SPLIT
+#define UGLY_SPLIT
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+#ifdef INLINE_CLEAR_TO_ROOT
+    struct btree *next;
+#endif
+#ifdef SAVE_NEIGHBORS
+    struct btree *neigh[2];
+#endif
+    int reversed;
+    int value;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right),
+    *find_root (btree *i);
+
+static void
+    join (btree *left, btree *i, btree *right),
+    reverse (btree *p),
+    clearrev_toroot (btree *p);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split (),
+    *find_root ();
+
+static void
+    join (),
+    reverse (),
+    clearrev_toroot ();
+
+#endif
+
+#ifdef    REPORT_DEPTH
+
+static double probecount = 1.0;
+static double probedepth = 1.0;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    find_depth (int x);
+#else
+static void
+    find_depth ();
+#endif
+
+#endif /* REPORT_DEPTH */
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static int btree_size;
+static btree *root = (btree *) NULL;
+#ifdef DUMMY_LEAF
+static btree dummy_leaf;
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    printf ("Flipper flags:");
+#ifdef SAVE_NEIGHBORS
+    printf (" SAVE_NEIGHBORS");
+#endif
+#ifdef DUMMY_LEAF
+    printf (" DUMMY_LEAF");
+#endif
+#ifdef NO_CLEAR_TO_ROOT
+    printf (" NO_CLEAR_TO_ROOT");
+#else
+#ifdef INLINE_CLEAR_TO_ROOT
+    printf (" INLINE_CLEAR_TO_ROOT");
+#else
+#ifdef INLINE_CLEAR_TO_ROOT2
+    printf (" INLINE_CLEAR_TO_ROOT2");
+#endif
+#endif
+#endif
+#ifdef SKIMPY_NULLS
+    printf (" SKIMPY_NULLS");
+#endif
+#ifdef SEQUENCE_2SPLIT
+    printf (" SEQUENCE_2SPLIT");
+#else
+#ifdef MUNCHED_SEQUENCE_CODE
+    printf (" MUNCHED_SEQUENCE_CODE");
+#endif
+#endif
+#ifdef UGLY_SPLIT
+    printf (" UGLY_SPLIT");
+#endif
+    printf ("\n");
+    fflush (stdout);
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    btree_size = ncount;
+    if (!btree_space)
+        return 1;
+
+#ifdef TRACE
+    printf ("init:");
+    for (i=0; i<ncount; i++) {
+        printf (" %d", cyc[i]);
+    }
+    printf ("\n");
+    fflush (stdout);
+#endif /* TRACE */
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].value = i;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            btree_space[cyc[0]].neigh[0] = &btree_space[cyc[ncount-1]];
+            btree_space[cyc[ncount-1]].neigh[1] = &btree_space[cyc[0]];
+        } else {
+            btree_space[cyc[i]].neigh[0] = &btree_space[cyc[i-1]];
+            btree_space[cyc[i-1]].neigh[1] = &btree_space[cyc[i]];
+        }
+#endif
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+#ifdef DUMMY_LEAF
+    if (p == &dummy_leaf)
+#else
+    if (p == (btree *) NULL)
+#endif
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+#ifdef REPORT_DEPTH
+    printf ("Number of Probes: %.0f   Average Depth: %.2f\n",
+             probecount, probedepth / probecount);
+    fflush (stdout);
+#endif
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (btree_space)
+        CC_FREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef REPORT_DEPTH
+#ifdef CC_PROTOTYPE_ANSI
+static void find_depth (int x)
+#else
+static void find_depth (x)
+int x;
+#endif
+{
+    btree *q = btree_space + x;
+
+    probecount += 1.0;
+    while (q) {
+        probedepth += 1.0;
+        q = q->parent;
+    }
+}
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef TRACE
+    printf ("next %d", x);
+    fflush (stdout);
+#endif /* TRACE */
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+#ifdef TRACE
+    printf ("==> %d (%d)\n", p->neigh[1-r] - btree_space, p->neigh[1-r]->value);
+    fflush (stdout);
+#endif /* TRACE */
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+#ifdef DUMMY_LEAF
+    if (pnext != &dummy_leaf) {
+#else
+    if (pnext) {
+#endif
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+#ifdef DUMMY_LEAF
+            if (pnext == &dummy_leaf) {
+#else
+            if (!pnext) {
+#endif
+#ifdef TRACE
+                printf ("==> %d (%d)\n", p - btree_space, p->value);
+                fflush (stdout);
+#endif /* TRACE */
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+#ifdef TRACE
+                printf ("==> %d (%d)\n", pnext - btree_space, pnext->value);
+                fflush (stdout);
+#endif /* TRACE */
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+#ifdef DUMMY_LEAF
+            if (pnext == &dummy_leaf) {
+#else
+            if (!pnext) {
+#endif
+#ifdef TRACE
+                printf ("==> %d (%d)\n", p - btree_space, p->value);
+                fflush (stdout);
+#endif /* TRACE */
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+#ifdef TRACE
+    printf ("prev %d", x);
+    fflush (stdout);
+#endif /* TRACE */
+#ifdef REPORT_DEPTH
+    find_depth (x);
+#endif
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+#ifdef TRACE
+    printf ("==> %d (%d)\n", p->neigh[r] - btree_space, p->neigh[r]->value);
+    fflush (stdout);
+#endif /* TRACE */
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+#ifdef DUMMY_LEAF
+    if (pnext != &dummy_leaf) {
+#else
+    if (pnext) {
+#endif
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+#ifdef DUMMY_LEAF
+            if (pnext == &dummy_leaf) {
+#else
+            if (!pnext) {
+#endif
+#ifdef TRACE
+                printf ("==> %d (%d)\n", p - btree_space, p->value);
+                fflush (stdout);
+#endif /* TRACE */
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+#ifdef TRACE
+                printf ("==> %d (%d)\n", pnext - btree_space, pnext->value);
+                fflush (stdout);
+#endif /* TRACE */
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+#ifdef DUMMY_LEAF
+            if (pnext == &dummy_leaf) {
+#else
+            if (!pnext) {
+#endif
+#ifdef TRACE
+                printf ("==> %d (%d)\n", p - btree_space, p->value);
+                fflush (stdout);
+#endif /* TRACE */
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+#ifdef SAVE_NEIGHBORS
+    btree *temp, *temp2;
+#endif
+    btree *a, *b, *c, *d;
+
+#ifdef TRACE
+    printf ("flip %d-%d %d-%d\n", xprev, x, y, ynext);
+    fflush (stdout);
+#endif /* TRACE */
+
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+#endif
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+#ifdef SAVE_NEIGHBORS
+#ifdef NEIGHTRACE
+    printf ("neigh before:");
+    printf (" %d-%d-%d", px->neigh[0]-btree_space,px-btree_space,px->neigh[1]-btree_space);
+    printf (" %d-%d-%d", py->neigh[0]-btree_space,py-btree_space,py->neigh[1]-btree_space);
+    printf (" %d-%d-%d", px->neigh[0]->neigh[0]-btree_space,px->neigh[0]-btree_space,px->neigh[0]->neigh[1]-btree_space);
+    printf (" %d-%d-%d", px->neigh[1]->neigh[0]-btree_space,px->neigh[1]-btree_space,px->neigh[1]->neigh[1]-btree_space);
+    printf (" %d-%d-%d", py->neigh[0]->neigh[0]-btree_space,py->neigh[0]-btree_space,py->neigh[0]->neigh[1]-btree_space);
+    printf (" %d-%d-%d", py->neigh[1]->neigh[0]-btree_space,py->neigh[1]-btree_space,py->neigh[1]->neigh[1]-btree_space);
+    printf ("\n");
+    fflush (stdout);
+#endif
+
+    temp = px->neigh[0];
+    temp2 = py->neigh[1];
+    px->neigh[0] = px->neigh[1];
+    py->neigh[1] = py->neigh[0];
+    py->neigh[0] = temp;
+    px->neigh[1] = temp2;
+    if (temp->neigh[0] == px) temp->neigh[0] = py;
+    else temp->neigh[1] = py;
+    if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+    else temp2->neigh[1] = px;
+#ifdef NEIGHTRACE
+    printf ("neigh after:");
+    printf (" %d-%d-%d", px->neigh[0]-btree_space,px-btree_space,px->neigh[1]-btree_space);
+    printf (" %d-%d-%d", py->neigh[0]-btree_space,py-btree_space,py->neigh[1]-btree_space);
+    printf (" %d-%d-%d", px->neigh[0]->neigh[0]-btree_space,px->neigh[0]-btree_space,px->neigh[0]->neigh[1]-btree_space);
+    printf (" %d-%d-%d", px->neigh[1]->neigh[0]-btree_space,px->neigh[1]-btree_space,px->neigh[1]->neigh[1]-btree_space);
+    printf (" %d-%d-%d", py->neigh[0]->neigh[0]-btree_space,py->neigh[0]-btree_space,py->neigh[0]->neigh[1]-btree_space);
+    printf (" %d-%d-%d", py->neigh[1]->neigh[0]-btree_space,py->neigh[1]-btree_space,py->neigh[1]->neigh[1]-btree_space);
+    printf ("\n");
+    fflush (stdout);
+#endif
+#endif
+}
+
+#if defined(MUNCHED_SEQUENCE_CODE) || defined(SEQUENCE_2SPLIT)
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d, *e, *f;
+    btree *r;
+
+#ifdef TRACE
+    printf ("sequence %d %d %d", x, y, z);
+    fflush (stdout);
+#endif /* TRACE */
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+    find_depth (z);
+#endif
+
+    if (y == z || x == z || x == y) {
+#ifdef TRACE
+        printf (" ==> 1\n");
+        fflush (stdout);
+#endif /* TRACE */
+        return 1;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, pz, &d) == a) { /* c z d x b */
+#ifdef SEQUENCE_2SPLIT
+        r = find_root (py);
+        join (c,pz,d);
+        join (pz,px,b);
+        root = px;
+#ifdef TRACE
+        printf (" ==> %d\n", r!=d);
+        fflush (stdout);
+#endif /* TRACE */
+        return (r!=d);
+#else /* SEQUENCE_2SPLIT */
+        r = split (&e, py, &f);
+        if (r == c) { /* e y f z d x b */
+            join (e, py, f);
+            join (py, pz, d);
+            join (pz, px, b);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 1\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 1;
+        } else if (r == d) { /* c z e y f x b */
+            join (c, pz, e);
+            join (pz, py, f);
+            join (py, px, b);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 0\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 0;
+        } else { /* c z d x e y f */
+            join (c, pz, d);
+            join (e, py, f);
+            join (pz, px, py);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 1\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 1;
+        }
+#endif /* SEQUENCE_2SPLIT */
+    } else { /* a x c z d */
+#ifdef SEQUENCE_2SPLIT
+        r = find_root (py);
+        join (c,pz,d);
+        join (a,px,pz);
+        root = px;
+#ifdef TRACE
+        printf (" ==> %d\n", r==c);
+        fflush (stdout);
+#endif /* TRACE */
+        return (r==c);
+#else /* SEQUENCE_2SPLIT */
+        r = split (&e, py, &f);
+        if (r == a) { /* e y f x c z d */
+            join (e, py, f);
+            join (c, pz, d);
+            join (py, px, pz);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 0\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 0;
+        } else if (r == c) { /* a x e y f z d */
+            join (e, py, f);
+            join (py, pz, d);
+            join (a, px, pz);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 1\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 1;
+        } else { /* a x c z e y f */
+            join (e, py, f);
+            join (c, pz, py);
+            join (a, px, pz);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 0\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 0;
+        }
+#endif /* SEQUENCE_2SPLIT */
+    }
+}
+
+#else /* defined(MUNCHED_SEQUENCE_CODE) || defined(SEQUENCE_2SPLIT) */
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d, *e, *f;
+    btree *r;
+
+#ifdef TRACE
+    printf ("sequence %d %d %d", x, y, z);
+    fflush (stdout);
+#endif /* TRACE */
+#ifdef REPORT_DEPTH
+    find_depth (x);
+    find_depth (y);
+    find_depth (z);
+#endif
+
+    if (y == z || x == z || x == y) {
+#ifdef TRACE
+        printf (" ==> 1\n");
+        fflush (stdout);
+#endif /* TRACE */
+        return 1;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b */
+        r = split (&e, pz, &f);
+        if (r == c) { /* e z f y d x b */
+            join (e, pz, f);
+            join (d, px, b);
+            join (pz, py, px);
+            root = py;
+#ifdef TRACE
+            printf (" ==> 0\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 0;
+        } else if (r == d) { /* c y e z f x b */
+            join (c, py, e);
+            join (f, px, b);
+            join (py, pz, px);
+            root = pz;
+#ifdef TRACE
+            printf (" ==> 1\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 1;
+        } else { /* c y d x e z f */
+            join (c, py, d);
+            join (e, pz, f);
+            join (py, px, pz);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 0\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 0;
+        }
+    } else { /* a x c y d */
+        r = split (&e, pz, &f);
+        if (r == a) { /* e z f x c y d */
+            join (e, pz, f);
+            join (c, py, d);
+            join (pz, px, py);
+            root = px;
+#ifdef TRACE
+            printf (" ==> 1\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 1;
+        } else if (r == c) { /* a x e z f y d */
+            join (a, px, e);
+            join (f, py, d);
+            join (px, pz, py);
+            root = pz;
+#ifdef TRACE
+            printf (" ==> 0\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 0;
+        } else { /* a x c y e z f */
+            join (a, px, c);
+            join (e, pz, f);
+            join (px, py, pz);
+            root = py;
+#ifdef TRACE
+            printf (" ==> 1\n");
+            fflush (stdout);
+#endif /* TRACE */
+            return 1;
+        }
+    }
+}
+
+#endif /* defined(MUNCHED_SEQUENCE_CODE) || defined(SEQUENCE_2SPLIT) */
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   void reverse (btree *p)                                               */
+/*     toggles the reversal bit of node p (and fixes the tree).            */
+/*   void clearrev_toroot (btree *p)                                       */
+/*     clears the reversal bits on the path from p to the root (and fixes  */
+/*     the tree).                                                          */
+/*   btree *find_root (btree *i)                                           */
+/*     returns the root of the tree containing i                           */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef TRACE
+void dump_tree (btree *r, int rev)
+{
+    if (!r) {
+        printf ("()");
+        return;
+    }
+    rev ^= r->reversed;
+    putchar ('(');
+    if (r->child[rev]) dump_tree (r->child[rev], rev);
+    printf (" %d%s ", r-btree_space, r->reversed?"R":"");
+    if (r->child[1-rev]) dump_tree (r->child[1-rev], rev);
+    putchar (')');
+}
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+#ifdef  DUMMY_LEAF
+        return &dummy_leaf;
+#else
+        return (btree *) NULL;
+#endif
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    p->child[0] = make_tree (a, center-1, cyc);
+#ifdef  DUMMY_LEAF
+    p->child[0]->parent = p;
+#else
+    if (p->child[0]) p->child[0]->parent = p;
+#endif
+    p->child[1] = make_tree (center+1, b, cyc);
+#ifdef  DUMMY_LEAF
+    p->child[1]->parent = p;
+#else
+    if (p->child[1]) p->child[1]->parent = p;
+#endif
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+#ifdef TRACE
+    printf ("join ");
+    dump_tree (left, 0);
+    printf (" %d ", i - btree_space);
+    dump_tree (right, 0);
+    printf ("\n");
+    fflush (stdout);
+#endif /* TRACE */
+#ifdef DUMMY_LEAF
+    left->parent = i;
+    right->parent = i;
+#else
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+#endif
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+#ifdef SKIMPY_NULLS
+    i->parent = (btree *) NULL;
+#endif
+#ifdef TRACE
+    printf ("==> ");
+    dump_tree (i, 0);
+    printf ("\n");
+    fflush (stdout);
+#endif /* TRACE */
+}
+
+#ifdef UGLY_SPLIT
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+#if defined(SAVE_NEIGHBORS) && defined(NO_CLEAR_TO_ROOT)
+    int rev = i->reversed;
+    btree *t;
+#endif
+
+#ifdef TRACE
+    printf ("split %d ", i - btree_space);
+    dump_tree (find_root (i), 0);
+    printf ("\n");
+    fflush (stdout);
+#endif /* TRACE */
+
+#ifdef NO_CLEAR_TO_ROOT
+    if (i->reversed) {
+        l = i->child[1];
+        r = i->child[0];
+#ifdef DUMMY_LEAF
+        l->reversed ^= 1;
+        r->reversed ^= 1;
+#else
+        if (l) l->reversed ^= 1;
+        if (r) r->reversed ^= 1;
+#endif
+#ifndef SKIMPY_NULLS
+        i->reversed = 0;
+#endif
+    } else {
+        l = i->child[0];
+        r = i->child[1];
+    }
+#else
+    clearrev_toroot (i);
+    l = i->child[0];
+    r = i->child[1];
+#endif
+
+#ifndef SKIMPY_NULLS
+#ifdef  DUMMY_LEAF
+    i->child[0] = &dummy_leaf;
+    i->child[1] = &dummy_leaf;
+#else
+    i->child[0] = (btree *) NULL;
+    i->child[1] = (btree *) NULL;
+#endif
+#endif
+
+    p = i->parent;
+    if (!p) {p = i; goto FINISH;}
+    else if (p->child[0] == i) goto START_0;
+    else goto START_1;
+
+I_IS_L:
+    if (p->parent == (btree *) NULL) goto FINISH;
+    p = p->parent;
+    if (p->child[1] == l) {
+#ifdef NO_CLEAR_TO_ROOT
+        if (p->reversed) {
+            l = r;
+            r = p;
+#ifdef DUMMY_LEAF
+            l->reversed ^= 1;
+#else
+            if (l) l->reversed ^= 1;
+#endif
+#ifdef SAVE_NEIGHBORS
+            rev ^= 1;
+#endif
+            goto I_IS_R;
+        } else {
+            l = p;
+            goto I_IS_L;
+        }
+#else
+        l = p;
+        goto I_IS_L;
+#endif
+    } else {
+START_0:
+        p->child[0] = r;
+#ifdef DUMMY_LEAF
+        r->parent = p;
+#else
+        if (r) r->parent = p;
+#endif
+#ifdef NO_CLEAR_TO_ROOT
+        if (p->reversed) {
+            r = l;
+            l = p;
+#ifdef DUMMY_LEAF
+            r->reversed ^= 1;
+#else
+            if (r) r->reversed ^= 1;
+#endif
+#ifdef SAVE_NEIGHBORS
+            rev ^= 1;
+#endif
+            goto I_IS_L;
+        } else {
+            r = p;
+            goto I_IS_R;
+        }
+#else
+        r = p;
+        goto I_IS_R;
+#endif
+    }
+I_IS_R:
+    if (p->parent == (btree *) NULL) goto FINISH;
+    p = p->parent;
+    if (p->child[0] == r) {
+#ifdef NO_CLEAR_TO_ROOT
+        if (p->reversed) {
+            r = l;
+            l = p;
+#ifdef DUMMY_LEAF
+            r->reversed ^= 1;
+#else
+            if (r) r->reversed ^= 1;
+#endif
+#ifdef SAVE_NEIGHBORS
+            rev ^= 1;
+#endif
+            goto I_IS_L;
+        } else {
+            r = p;
+            goto I_IS_R;
+        }
+#else
+        r = p;
+        goto I_IS_R;
+#endif
+    } else {
+START_1:
+        p->child[1] = l;
+#ifdef DUMMY_LEAF
+        l->parent = p;
+#else
+        if (l) l->parent = p;
+#endif
+#ifdef NO_CLEAR_TO_ROOT
+        if (p->reversed) {
+            l = r;
+            r = p;
+#ifdef DUMMY_LEAF
+            l->reversed ^= 1;
+#else
+            if (l) l->reversed ^= 1;
+#endif
+#ifdef SAVE_NEIGHBORS
+            rev ^= 1;
+#endif
+            goto I_IS_R;
+        } else {
+            l = p;
+            goto I_IS_L;
+        }
+#else
+        l = p;
+        goto I_IS_L;
+#endif
+    }
+
+FINISH:
+#ifdef DUMMY_LEAF
+    l->parent = (btree *) NULL;
+    r->parent = (btree *) NULL;
+#else
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+#endif
+    *left = l;
+    *right = r;
+#ifndef SKIMPY_NULLS
+    i->parent = (btree *) NULL;
+#endif
+#if defined(SAVE_NEIGHBORS) && defined(NO_CLEAR_TO_ROOT)
+    if (rev) SWAP (i->neigh[0], i->neigh[1], t);
+#endif
+
+#ifdef TRACE
+    printf ("==> ");
+    dump_tree (l, 0);
+    printf (" %d ", i - btree_space);
+    dump_tree (r, 0);
+    printf (" ret %d\n", p - btree_space);
+    fflush (stdout);
+#endif /* TRACE */
+    return p;
+}
+
+#else /* UGLY_SPLIT */
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+#if defined(SAVE_NEIGHBORS) || !defined(SKIMPY_NULLS)
+    btree *isave = i;
+#endif
+#if defined(SAVE_NEIGHBORS) && defined(NO_CLEAR_TO_ROOT)
+    int rev = i->reversed;
+#endif
+
+#ifdef TRACE
+    printf ("split %d ", i - btree_space);
+    dump_tree (find_root (i), 0);
+    printf ("\n");
+    fflush (stdout);
+#endif /* TRACE */
+
+#ifdef NO_CLEAR_TO_ROOT
+    if (i->reversed) {
+        l = i->child[1];
+        r = i->child[0];
+#ifdef DUMMY_LEAF
+        l->reversed ^= 1;
+        r->reversed ^= 1;
+#else
+        if (l) l->reversed ^= 1;
+        if (r) r->reversed ^= 1;
+#endif
+#ifndef SKIMPY_NULLS
+        i->reversed = 0;
+#endif
+    } else {
+        l = i->child[0];
+        r = i->child[1];
+    }
+#else
+    clearrev_toroot (i);
+    l = i->child[0];
+    r = i->child[1];
+#endif
+
+#ifndef SKIMPY_NULLS
+#ifdef  DUMMY_LEAF
+    i->child[0] = &dummy_leaf;
+    i->child[1] = &dummy_leaf;
+#else
+    i->child[0] = (btree *) NULL;
+    i->child[1] = (btree *) NULL;
+#endif
+#endif
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+#ifdef DUMMY_LEAF
+            r->parent = p;
+#else
+            if (r) r->parent = p;
+#endif
+#ifdef NO_CLEAR_TO_ROOT
+            if (p->reversed) {
+                r = l;
+                l = p;
+#ifdef DUMMY_LEAF
+                r->reversed ^= 1;
+#else
+                if (r) r->reversed ^= 1;
+#endif
+#ifdef SAVE_NEIGHBORS
+                rev ^= 1;
+#endif
+            } else {
+                r = p;
+            }
+#else
+            r = p;
+#endif
+        } else {
+            p->child[1] = l;
+#ifdef DUMMY_LEAF
+            l->parent = p;
+#else
+            if (l) l->parent = p;
+#endif
+#ifdef NO_CLEAR_TO_ROOT
+            if (p->reversed) {
+                l = r;
+                r = p;
+#ifdef DUMMY_LEAF
+                l->reversed ^= 1;
+#else
+                if (l) l->reversed ^= 1;
+#endif
+#ifdef SAVE_NEIGHBORS
+                rev ^= 1;
+#endif
+            } else {
+                l = p;
+            }
+#else
+            l = p;
+#endif
+        }
+        i = p;
+    }
+#ifdef DUMMY_LEAF
+    l->parent = (btree *) NULL;
+    r->parent = (btree *) NULL;
+#else
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+#endif
+    *left = l;
+    *right = r;
+#ifndef SKIMPY_NULLS
+    isave->parent = (btree *) NULL;
+#endif
+#if defined(SAVE_NEIGHBORS) && defined(NO_CLEAR_TO_ROOT)
+    if (rev) SWAP (isave->neigh[0], isave->neigh[1], p);
+#endif
+
+#ifdef TRACE
+    printf ("==> ");
+    dump_tree (l, 0);
+    printf (" %d ", isave - btree_space);
+    dump_tree (r, 0);
+    printf (" ret %d\n", i - btree_space);
+    fflush (stdout);
+#endif /* TRACE */
+    return i;
+}
+
+#endif /* UGLY_SPLIT */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void reverse (btree *p)
+#else
+static void reverse (p)
+btree *p;
+#endif
+{
+    btree *t;
+
+    SWAP(p->child[0], p->child[1], t);
+#ifdef DUMMY_LEAF
+    p->child[0]->reversed ^= 1;
+    p->child[1]->reversed ^= 1;
+#else
+    if (p->child[0]) p->child[0]->reversed ^= 1;
+    if (p->child[1]) p->child[1]->reversed ^= 1;
+#endif
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], t);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clearrev_toroot (btree *p)
+#else
+static void clearrev_toroot (p)
+btree *p;
+#endif
+{
+#ifdef INLINE_CLEAR_TO_ROOT
+    p->next = (btree *) NULL;
+    while (p->parent) {
+        p->parent->next = p;
+        p = p->parent;
+    }
+    while (p) {
+        if (p->reversed) reverse (p);
+        p = p->next;
+    }
+#else
+#ifdef INLINE_CLEAR_TO_ROOT2
+    int rev;
+    btree *q;
+
+    for (q = p, rev = 0; q; q = q->parent) rev ^= q->reversed;
+    if (rev) reverse(p);
+    while (p->parent) {
+      if (p->reversed) reverse(p->parent);
+      p = p->parent;
+    }
+#else
+    if (p->parent) clearrev_toroot (p->parent);
+    if (p->reversed) reverse (p);
+#endif
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *find_root (btree *i)
+#else
+static btree *find_root (i)
+btree *i;
+#endif
+{
+    while (i->parent) i = i->parent;
+    return i;
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_bt5.c b/contrib/blossom/concorde97/LINKERN/flip_bt5.c
new file mode 100644
index 0000000000000000000000000000000000000000..02ae7301dad7dedfd8df205b91b321712b28fd0b
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_bt5.c
@@ -0,0 +1,700 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                              - Uses SKIMPY_NULLS,       */
+/*                                                NO_CLEAR_TO_ROOT, and    */
+/*                                                SEQUENCE_2SPLIT          */
+/*                                              - Adds splays              */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#define USE_SPLAY_SEQUENCE
+#define USE_SPLAY_FLIPS
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+    int reversed;
+    int mark;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right),
+    *find_root (btree *i);
+
+static void
+    join (btree *left, btree *i, btree *right);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split (),
+    *find_root ();
+
+static void
+    join ();
+
+#endif
+
+#if defined(USE_SPLAY_SEQUENCE) || defined(USE_SPLAY_FLIPS)
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    rotate (btree *x, btree *px),
+    splay (btree *x),
+    reverse (btree *p);
+
+#else
+
+static void
+    rotate (),
+    splay (),
+    reverse ();
+
+#endif
+#endif
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static btree *root = (btree *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    printf ("SIZE OF BTREE: %d\n", sizeof (btree));
+    fflush (stdout);
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].mark = 0;
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (p == (btree *) NULL)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p - btree_space;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (btree_space)
+        CC_FREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext - btree_space;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext - btree_space;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    }
+}
+
+
+#ifdef USE_SPLAY_FLIPS
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *temp;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    splay (px);
+    px->mark = 1;
+    splay (py);
+    px->mark = 0;
+
+    splay (px);
+    px->mark = 1;
+    splay (py);
+    px->mark = 0;
+
+    if (px->reversed)
+        reverse (px);
+    if (py->reversed)
+        reverse (py);
+    if (px->child[1] == py) {
+        if (py->child[0])
+            py->child[0]->reversed ^= 1;
+        SWAP (px->child[0], py->child[0], temp);
+        if (px->child[0])
+            px->child[0]->parent = px;
+        if (py->child[0])
+            py->child[0]->parent = py;
+        px->child[1] = py->child[1];
+        if (px->child[1])
+            px->child[1]->parent = px;
+        py->child[1] = px;
+        px->parent = py;
+        py->parent = (btree *) NULL;
+        root = py;
+    } else {
+        px->reversed ^= 1;
+        py->child[1]->reversed ^= 1;
+    }
+}
+
+#else
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *a, *b, *c, *d;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+}
+#endif
+
+#ifdef USE_SPLAY_SEQUENCE
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    splay (px);
+    px->mark = 1;
+    splay (pz);
+    px->mark = 0;
+
+    if (px->reversed)
+        reverse (px);
+    if (pz->reversed)
+        reverse (pz);
+
+    for (;;) {
+        if (py->parent == px) {
+            return px->child[1] == py;
+        } else if (py->parent == pz) {
+            return pz->child[0] == py;
+        } else {
+            py = py->parent;
+        }
+    }
+}
+
+#else
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d;
+    btree *r;
+
+    if (y == z || x == z || x == y) {
+        return 1;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, pz, &d) == a) { /* c z d x b */
+        r = find_root (py);
+        join (c,pz,d);
+        join (pz,px,b);
+        root = px;
+        return (r!=d);
+    } else { /* a x c z d */
+        r = find_root (py);
+        join (c,pz,d);
+        join (a,px,pz);
+        root = px;
+        return (r==c);
+    }
+}
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   btree *find_root (btree *i)                                           */
+/*     returns the root of the tree containing i                           */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return (btree *) NULL;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    p->child[0] = make_tree (a, center-1, cyc);
+    if (p->child[0]) p->child[0]->parent = p;
+    p->child[1] = make_tree (center+1, b, cyc);
+    if (p->child[1]) p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+    i->parent = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+
+    if (i->reversed) {
+        l = i->child[1];
+        r = i->child[0];
+        if (l) l->reversed ^= 1;
+        if (r) r->reversed ^= 1;
+    } else {
+        l = i->child[0];
+        r = i->child[1];
+    }
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            if (r) r->parent = p;
+            if (p->reversed) {
+                r = l;
+                l = p;
+                if (r) r->reversed ^= 1;
+            } else {
+                r = p;
+            }
+        } else {
+            p->child[1] = l;
+            if (l) l->parent = p;
+            if (p->reversed) {
+                l = r;
+                r = p;
+                if (l) l->reversed ^= 1;
+            } else {
+                l = p;
+            }
+        }
+        i = p;
+    }
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *find_root (btree *i)
+#else
+static btree *find_root (i)
+btree *i;
+#endif
+{
+    while (i->parent) i = i->parent;
+    return i;
+}
+
+
+/**************************** SPLAY STUFF ****************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static void rotate (btree *x, btree *px)
+#else
+static void rotate (x, px)
+btree *x, *px;
+#endif
+{
+    btree *b;
+
+    if (px->child[0] == x) {
+        b = x->child[1];
+        if (b)
+            b->parent = px;
+        x->child[1] = px;
+        x->parent = px->parent;
+        if (x->parent) {
+            if (x->parent->child[0] == px) {
+                x->parent->child[0] = x;
+            } else {
+                x->parent->child[1] = x;
+            }
+        }
+        px->child[0] = b;
+        px->parent = x;
+    } else {
+        b = x->child[0];
+        if (b)
+            b->parent = px;
+        x->child[0] = px;
+        x->parent = px->parent;
+        if (x->parent) {
+            if (x->parent->child[0] == px) {
+                x->parent->child[0] = x;
+            } else {
+                x->parent->child[1] = x;
+            }
+        }
+        px->child[1] = b;
+        px->parent = x;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void splay (btree *x)
+#else
+static void splay (x)
+btree *x;
+#endif
+{
+    btree *px;
+    btree *ppx;
+
+    for (;;) {
+        px = x->parent;
+        if (!px) {
+            root = x;
+            return;
+        }
+        if (px->mark)
+            return;
+        ppx = px->parent;
+        if (!ppx) {
+            if (px->reversed)
+                reverse (px);
+            if (x->reversed)
+                reverse (x);
+            rotate (x, px);
+            root = x;
+            return;
+        }
+        if (ppx->mark) {
+            if (px->reversed)
+                reverse (px);
+            if (x->reversed)
+                reverse (x);
+            rotate (x, px);
+            return;
+        }
+        if (ppx->reversed)
+            reverse (ppx);
+        if (px->reversed)
+            reverse (px);
+        if (x->reversed)
+            reverse (x);
+        if (ppx->child[0] == px) {
+            if (px->child[0] == x) {
+                rotate (px, ppx);
+                rotate (x, px);
+            } else {
+                rotate (x, px);
+                rotate (x, ppx);
+            }
+        } else {
+            if (px->child[1] == x) {
+                rotate (px, ppx);
+                rotate (x, px);
+            } else {
+                rotate (x, px);
+                rotate (x, ppx);
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void reverse (btree *p)
+#else
+static void reverse (p)
+btree *p;
+#endif
+{
+    btree *t;
+
+    SWAP(p->child[0], p->child[1], t);
+    if (p->child[0]) p->child[0]->reversed ^= 1;
+    if (p->child[1]) p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_btc.c b/contrib/blossom/concorde97/LINKERN/flip_btc.c
new file mode 100644
index 0000000000000000000000000000000000000000..9023e6547bbf796aa06bded8c697dfd25ef06be2
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_btc.c
@@ -0,0 +1,459 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                              - Uses SKIMPY_NULLS,       */
+/*                                                NO_CLEAR_TO_ROOT, and    */
+/*                                                SEQUENCE_2SPLIT          */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+    int reversed;
+    int value;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right),
+    *find_root (btree *i);
+
+static void
+    join (btree *left, btree *i, btree *right);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split (),
+    *find_root ();
+
+static void
+    join ();
+
+#endif
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static int btree_size;
+static btree *root = (btree *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    btree_size = ncount;
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].value = i;
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (p == (btree *) NULL)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (btree_space)
+        CC_FREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *a, *b, *c, *d;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d;
+    btree *r;
+
+    if (y == z || x == z || x == y) {
+        return 1;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, pz, &d) == a) { /* c z d x b */
+        r = find_root (py);
+        join (c,pz,d);
+        join (pz,px,b);
+        root = px;
+        return (r!=d);
+    } else { /* a x c z d */
+        r = find_root (py);
+        join (c,pz,d);
+        join (a,px,pz);
+        root = px;
+        return (r==c);
+    }
+}
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   btree *find_root (btree *i)                                           */
+/*     returns the root of the tree containing i                           */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return (btree *) NULL;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    p->child[0] = make_tree (a, center-1, cyc);
+    if (p->child[0]) p->child[0]->parent = p;
+    p->child[1] = make_tree (center+1, b, cyc);
+    if (p->child[1]) p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+    i->parent = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+
+    if (i->reversed) {
+        l = i->child[1];
+        r = i->child[0];
+        if (l) l->reversed ^= 1;
+        if (r) r->reversed ^= 1;
+    } else {
+        l = i->child[0];
+        r = i->child[1];
+    }
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            if (r) r->parent = p;
+            if (p->reversed) {
+                r = l;
+                l = p;
+                if (r) r->reversed ^= 1;
+            } else {
+                r = p;
+            }
+        } else {
+            p->child[1] = l;
+            if (l) l->parent = p;
+            if (p->reversed) {
+                l = r;
+                r = p;
+                if (l) l->reversed ^= 1;
+            } else {
+                l = p;
+            }
+        }
+        i = p;
+    }
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *find_root (btree *i)
+#else
+static btree *find_root (i)
+btree *i;
+#endif
+{
+    while (i->parent) i = i->parent;
+    return i;
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_btd.c b/contrib/blossom/concorde97/LINKERN/flip_btd.c
new file mode 100644
index 0000000000000000000000000000000000000000..b9b9d93fb6a357fcc8f9727189770761c57b5af8
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_btd.c
@@ -0,0 +1,458 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                              - Uses SKIMPY_NULLS,       */
+/*                                                NO_CLEAR_TO_ROOT, and    */
+/*                                                SEQUENCE_2SPLIT          */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+    int reversed;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right),
+    *find_root (btree *i);
+
+static void
+    join (btree *left, btree *i, btree *right);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split (),
+    *find_root ();
+
+static void
+    join ();
+
+#endif
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static btree *root = (btree *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    printf ("SIZE OF BTREE: %d\n", sizeof (btree));
+    fflush (stdout);
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (p == (btree *) NULL)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p - btree_space;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (btree_space)
+        CC_FREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext - btree_space;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext - btree_space;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p - btree_space;
+            }
+            p = pnext;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *a, *b, *c, *d;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d;
+    btree *r;
+
+    if (y == z || x == z || x == y) {
+        return 1;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, pz, &d) == a) { /* c z d x b */
+        r = find_root (py);
+        join (c,pz,d);
+        join (pz,px,b);
+        root = px;
+        return (r!=d);
+    } else { /* a x c z d */
+        r = find_root (py);
+        join (c,pz,d);
+        join (a,px,pz);
+        root = px;
+        return (r==c);
+    }
+}
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   btree *find_root (btree *i)                                           */
+/*     returns the root of the tree containing i                           */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return (btree *) NULL;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    p->child[0] = make_tree (a, center-1, cyc);
+    if (p->child[0]) p->child[0]->parent = p;
+    p->child[1] = make_tree (center+1, b, cyc);
+    if (p->child[1]) p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+    i->parent = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+
+    if (i->reversed) {
+        l = i->child[1];
+        r = i->child[0];
+        if (l) l->reversed ^= 1;
+        if (r) r->reversed ^= 1;
+    } else {
+        l = i->child[0];
+        r = i->child[1];
+    }
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            if (r) r->parent = p;
+            if (p->reversed) {
+                r = l;
+                l = p;
+                if (r) r->reversed ^= 1;
+            } else {
+                r = p;
+            }
+        } else {
+            p->child[1] = l;
+            if (l) l->parent = p;
+            if (p->reversed) {
+                l = r;
+                r = p;
+                if (l) l->reversed ^= 1;
+            } else {
+                l = p;
+            }
+        }
+        i = p;
+    }
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *find_root (btree *i)
+#else
+static btree *find_root (i)
+btree *i;
+#endif
+{
+    while (i->parent) i = i->parent;
+    return i;
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_btr.c b/contrib/blossom/concorde97/LINKERN/flip_btr.c
new file mode 100644
index 0000000000000000000000000000000000000000..2dc5aef8ebffbd78a624c33ee9b25428a5135fdb
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_btr.c
@@ -0,0 +1,556 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Binary Trees (unbalanced)*/
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define SAVE_NEIGHBORS */
+#define INLINE_CLEAR_TO_ROOT
+
+typedef struct btree {
+    struct btree *parent;
+    struct btree *child[2];
+#ifdef INLINE_CLEAR_TO_ROOT
+    struct btree *next;
+#endif
+#ifdef SAVE_NEIGHBORS
+    struct btree *neigh[2];
+#endif
+    int reversed;
+    int value;
+} btree;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    cycle_fillin(int *x, int i, btree *p, int r);
+
+static btree
+    *make_tree (int a, int b, int *cyc),
+    *split (btree **left, btree *i, btree **right);
+
+static void
+    join (btree *left, btree *i, btree *right),
+    reverse (btree *p),
+    clearrev_toroot (btree *p);
+
+#else
+
+static int
+    cycle_fillin();
+
+static btree
+    *make_tree (),
+    *split ();
+
+static void
+    join (),
+    reverse (),
+    clearrev_toroot ();
+
+#endif
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+static btree *btree_space = (btree *) NULL;
+static int btree_size;
+static btree *root = (btree *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+/*
+    printf ("Flipper flags:");
+#ifdef SAVE_NEIGHBORS
+    printf (" SAVE_NEIGHBORS");
+#else
+    printf (" !SAVE_NEIGHBORS");
+#endif
+*/
+
+    btree_space = CC_SAFE_MALLOC (ncount, btree);
+    btree_size = ncount;
+    if (!btree_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        btree_space[i].reversed = 0;
+        btree_space[i].value = i;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            btree_space[cyc[0]].neigh[0] = &btree_space[cyc[ncount-1]];
+            btree_space[cyc[ncount-1]].neigh[1] = &btree_space[cyc[0]];
+        } else {
+            btree_space[cyc[i]].neigh[0] = &btree_space[cyc[i-1]];
+            btree_space[cyc[i-1]].neigh[1] = &btree_space[cyc[i]];
+        }
+#endif
+    }
+
+    root = make_tree (0, ncount - 1, cyc);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cycle_fillin(int *x, int i, btree *p, int r)
+#else
+static int cycle_fillin(x, i, p, r)
+int *x;
+int i;
+btree *p;
+int r;
+#endif
+{
+    if (!p)
+        return i;
+
+    r ^= p->reversed;
+    i = cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    return cycle_fillin (x, 0, root, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    CC_IFFREE (btree_space, btree);
+
+    root = (btree *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    btree *p = btree_space + x;
+    btree *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; pnext; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed;
+        pnext = p->parent;
+        while (pnext) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *temp, *temp2;
+    btree *a, *b, *c, *d;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root->reversed ^= 1;
+        return;
+    }
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b ==> b^r x d y c^r */
+        if (b) b->reversed ^= 1;
+        if (c) c->reversed ^= 1;
+        join (d,py,c);
+        join (b,px,py);
+        root = px;
+    } else { /* a x c y d  ==> a y c^r x d */
+        if (c) c->reversed ^= 1;
+        join (a,py,c);
+        join (py,px,d);
+        root = px;
+    }
+#ifdef SAVE_NEIGHBORS
+    temp = px->neigh[0];
+    temp2 = py->neigh[1];
+    px->neigh[0] = px->neigh[1];
+    py->neigh[1] = py->neigh[0];
+    py->neigh[0] = temp;
+    px->neigh[1] = temp2;
+    if (temp->neigh[0] == px) temp->neigh[0] = py;
+    else temp->neigh[1] = py;
+    if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+    else temp2->neigh[1] = px;
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    btree *px = btree_space + x;
+    btree *py = btree_space + y;
+    btree *pz = btree_space + z;
+    btree *a, *b, *c, *d, *e, *f;
+    btree *r;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    split (&a, px, &b);
+    if (split (&c, py, &d) == a) { /* c y d x b */
+        r = split (&e, pz, &f);
+        if (r == c) { /* e z f y d x b */
+            join (e, pz, f);
+            join (d, px, b);
+            join (pz, py, px);
+            root = py;
+            return 0;
+        } else if (r == d) { /* c y e z f x b */
+            join (c, py, e);
+            join (f, px, b);
+            join (py, pz, px);
+            root = pz;
+            return 1;
+        } else { /* c y d x e z f */
+            join (c, py, d);
+            join (e, pz, f);
+            join (py, px, pz);
+            root = px;
+            return 0;
+        }
+    } else { /* a x c y d */
+        r = split (&e, pz, &f);
+        if (r == a) { /* e z f x c y d */
+            join (e, pz, f);
+            join (c, py, d);
+            join (pz, px, py);
+            root = px;
+            return 1;
+        } else if (r == c) { /* a x e z f y d */
+            join (a, px, e);
+            join (f, py, d);
+            join (px, pz, py);
+            root = pz;
+            return 0;
+        } else { /* a x c y e z f */
+            join (a, px, c);
+            join (e, pz, f);
+            join (px, py, pz);
+            root = py;
+            return 1;
+        }
+    }
+}
+
+/***************************************************************************/
+/*                                                                         */
+/*                REVERSIBLE BINARY TREE ROUTINES (UNBALANCED)             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 16, 1995                                                */
+/*                                                                         */
+/*                                                                         */
+/*   btree *make_tree (int a, int b, int *cyc)                             */
+/*     builds a binary tree for cyc[a..b] and returns the root.            */
+/*     This assumes that btree_space has been allocated and initialized.   */
+/*   void join (btree *left, btree *i, btree *right)                       */
+/*     makes left and right the children of i.                             */
+/*   btree *split (btree **left, btree *i, btree **right)                  */
+/*     splits the tree into *left (nodes < i) and *right (nodes > i)       */
+/*     returns the root of the (old) tree containing i.                    */
+/*   void reverse (btree *p)                                               */
+/*     toggles the reversal bit of node p (and fixes the tree).            */
+/*   void clearrev_toroot (btree *p)                                       */
+/*     clears the reversal bits on the path from p to the root (and fixes  */
+/*     the tree).                                                          */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *make_tree (int a, int b, int *cyc)
+#else
+static btree *make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    btree *p;
+    int center;
+
+    if (b < a)
+        return (btree *) NULL;
+
+    center = (a + b)/2;
+    p = btree_space + cyc[center];
+    if ((p->child[0] = make_tree (a, center-1, cyc)) != (btree *) NULL)
+        p->child[0]->parent = p;
+    if ((p->child[1] = make_tree (center+1, b, cyc)) != (btree *) NULL)
+        p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void join (btree *left, btree *i, btree *right)
+#else
+static void join (left, i, right)
+btree *left;
+btree *i;
+btree *right;
+#endif
+{
+    if (left) left->parent = i;
+    if (right) right->parent = i;
+    i->child[0] = left;
+    i->child[1] = right;
+    i->reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static btree *split (btree **left, btree *i, btree **right)
+#else
+static btree *split (left, i, right)
+btree **left;
+btree *i;
+btree **right;
+#endif
+{
+    btree *l;
+    btree *r;
+    btree *p;
+    btree *isave = i;
+
+    clearrev_toroot (i);
+    l = i->child[0];
+    r = i->child[1];
+    i->child[0] = (btree *) NULL;
+    i->child[1] = (btree *) NULL;
+
+    while ((p = i->parent) != (btree *) NULL) {
+        if (p->child[0] == i) {
+            p->child[0] = r;
+            if (r) r->parent = p;
+            r = p;
+        } else {
+            p->child[1] = l;
+            if (l) l->parent = p;
+            l = p;
+        }
+        i = p;
+    }
+    if (l) l->parent = (btree *) NULL;
+    if (r) r->parent = (btree *) NULL;
+    *left = l;
+    *right = r;
+    if (isave) isave->parent = (btree *) NULL;
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void reverse (btree *p)
+#else
+static void reverse (p)
+btree *p;
+#endif
+{
+    btree *t;
+
+    SWAP(p->child[0], p->child[1], t);
+    if (p->child[0]) p->child[0]->reversed ^= 1;
+    if (p->child[1]) p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], t);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clearrev_toroot (btree *p)
+#else
+static void clearrev_toroot (p)
+btree *p;
+#endif
+{
+#ifndef INLINE_CLEAR_TO_ROOT
+    if (p->parent) clearrev_toroot (p->parent);
+    if (p->reversed) reverse (p);
+#else
+    p->next = (btree *) NULL;
+    while (p->parent) {
+        p->parent->next = p;
+        p = p->parent;
+    }
+    while (p) {
+        if (p->reversed) reverse (p);
+        p = p->next;
+    }
+#endif
+}
+
+
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll0.c b/contrib/blossom/concorde97/LINKERN/flip_ll0.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c1067ae541d6256e5936d41487569ceef9006ae
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll0.c
@@ -0,0 +1,252 @@
+/***************************************************************************/
+/*                                                                         */
+/*    TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Basic Linked List      */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 0  (flip_ll0.c):                                   */
+/*                                                                         */
+/*     1. Uses linked list with known prev and next.                       */
+/*     2. No reversal bit.                                                 */
+/*     2. Next and prev given explicitly.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+typedef struct llnode {
+    struct llnode *next;
+    struct llnode *prev;
+    int            name;
+    int            mark;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    dump_cycle (void);
+
+#else
+
+static void
+    dump_cycle ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static cycle_size = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].name = cyc[0];
+    lltour[cyc[0]].mark = 0;
+    lltour[cyc[0]].next = &(lltour[cyc[1]]);
+    lltour[cyc[0]].prev = &(lltour[cyc[ncount - 1]]);
+    lltour[cyc[ncount - 1]].name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].mark = 0;
+    lltour[cyc[ncount - 1]].next = &(lltour[cyc[0]]);
+    lltour[cyc[ncount - 1]].prev = &(lltour[cyc[ncount - 2]]);
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].name = cyc[i];
+        lltour[cyc[i]].mark = 0;
+        lltour[cyc[i]].next = &(lltour[cyc[i + 1]]);
+        lltour[cyc[i]].prev = &(lltour[cyc[i - 1]]);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_cycle (void)
+#else
+static void dump_cycle ()
+#endif
+{
+    llnode *n, *ns;
+
+    printf ("TOUR:\n");
+
+
+    n = ns = &(lltour[0]);
+
+    do {
+        printf ("%2d ", n->name);
+        n = n->next;
+    } while (n != ns);
+
+    printf ("\n");
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    llnode *n, *start;
+    int k = 0;
+
+    n = start = &(lltour[0]);
+
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start && k < cycle_size);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    return lltour[x].next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    return lltour[x].prev->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    llnode *nxprev = &(lltour[xprev]);
+    llnode *nynext = &(lltour[ynext]);
+    llnode *nx = &(lltour[x]);
+    llnode *ny = &(lltour[y]);
+    llnode *n, *next;
+
+    if (x == y)
+        return;
+
+    next = nx->next;
+    nx->next = nx->prev;
+    nx->prev = next;
+
+    do {
+        n = next;
+        next = n->next;
+        n->next = n->prev;
+        n->prev = next;
+    } while (n != ny);
+
+    if (nxprev != ny) {
+        ny->prev = nxprev;
+        nx->next = nynext;
+        nxprev->next = ny;
+        nynext->prev = nx;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    llnode *n;
+
+    if (x == z) {
+        return 1;
+    } else {
+        lltour[y].mark = 1;
+        lltour[z].mark = 1;
+
+        n = &(lltour[x]);
+
+        while (!n->mark) {
+            n = n->next;
+        }
+        lltour[y].mark = 0;
+        lltour[z].mark = 0;
+
+        return (n->name == y);
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll1.c b/contrib/blossom/concorde97/LINKERN/flip_ll1.c
new file mode 100644
index 0000000000000000000000000000000000000000..d44a486113553ceec5bc8953928a1a2df7dcb7fb
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll1.c
@@ -0,0 +1,258 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked List with Node Bit */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version is a real dud - the node bit idea takes longer than  */
+/*   simply swapping the next and prev fields as in flip_ll0.              */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 1  (flip_ll1.c):                                   */
+/*                                                                         */
+/*     1. Uses linked list with known prev and next.                       */
+/*     2. No reversal bit.                                                 */
+/*     3. Node bits to distingish between prev and next.                   */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+typedef struct llnode {
+    struct llnode *neigh[2];    /* 0 is next, 1 is prev */
+    int            name;
+    char           dir;
+    char           mark;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    dump_cycle (void);
+
+#else
+
+static void
+    dump_cycle ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static cycle_size = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].name = cyc[0];
+    lltour[cyc[0]].dir = 0;
+    lltour[cyc[0]].mark = 0;
+    lltour[cyc[0]].neigh[0] = &(lltour[cyc[1]]);
+    lltour[cyc[0]].neigh[1] = &(lltour[cyc[ncount - 1]]);
+    lltour[cyc[ncount - 1]].name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].dir = 0;
+    lltour[cyc[ncount - 1]].mark = 0;
+    lltour[cyc[ncount - 1]].neigh[0] = &(lltour[cyc[0]]);
+    lltour[cyc[ncount - 1]].neigh[1] = &(lltour[cyc[ncount - 2]]);
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].name = cyc[i];
+        lltour[cyc[i]].dir = 0;
+        lltour[cyc[i]].mark = 0;
+        lltour[cyc[i]].neigh[0] = &(lltour[cyc[i + 1]]);
+        lltour[cyc[i]].neigh[1] = &(lltour[cyc[i - 1]]);
+    }
+
+/*
+    dump_cycle ();
+*/
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_cycle (void)
+#else
+static void dump_cycle ()
+#endif
+{
+    llnode *n, *ns;
+
+    printf ("TOUR:\n");
+
+
+    n = ns = &(lltour[0]);
+
+    do {
+        printf ("%2d ", n->name);
+        n = n->neigh[(int) n->dir];
+    } while (n != ns);
+
+    printf ("\n");
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    llnode *n, *start;
+    int k = 0;
+
+    n = start = &(lltour[0]);
+
+    do {
+        x[k++] = n->name;
+        n = n->neigh[(int) n->dir];
+    } while (n != start && k < cycle_size);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    return lltour[x].neigh[(int) lltour[x].dir]->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    return lltour[x].neigh[(int) ((lltour[x].dir)^1)]->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    llnode *nxprev = &(lltour[xprev]);
+    llnode *nynext = &(lltour[ynext]);
+    llnode *nx = &(lltour[x]);
+    llnode *ny = &(lltour[y]);
+    llnode *n;
+
+    if (x == y)
+        return;
+
+    n = nx;
+    n->dir ^= 1;
+
+    do {
+        n = n->neigh[n->dir^1];
+        n->dir ^= 1;
+    } while (n != ny);
+
+    if (nxprev != ny) {
+        ny->neigh[(int) ny->dir^1] = nxprev;
+        nx->neigh[(int) nx->dir] = nynext;
+        nxprev->neigh[(int) nxprev->dir] = ny;
+        nynext->neigh[(int) nynext->dir^1] = nx;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    llnode *n;
+
+    if (x == z) {
+        return 1;
+    } else {
+        lltour[y].mark = 1;
+        lltour[z].mark = 1;
+
+        n = &(lltour[x]);
+
+        while (!n->mark) {
+            n = n->neigh[(int) n->dir];
+        }
+        lltour[y].mark = 0;
+        lltour[z].mark = 0;
+
+        return (n->name == y);
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll2.c b/contrib/blossom/concorde97/LINKERN/flip_ll2.c
new file mode 100644
index 0000000000000000000000000000000000000000..9f6a828671472cf903e164622757d1dbdd246260
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll2.c
@@ -0,0 +1,325 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Basic Linked List w/ Rev  */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version uses very little memory, and is reasonably fast      */
+/*   for small problems and for twoopts (but you should have SHORT_SIDE    */
+/*   defined so that the smaller side a flip is carried out.               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 0  (flip_ll0.c):                                   */
+/*                                                                         */
+/*     1. Uses linked list with known prev and next.                       */
+/*     2. Tour reversal bit.                                               */
+/*     2. Next and prev given explicitly.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+typedef struct llnode {
+    struct llnode *next;
+    struct llnode *prev;
+    int            name;
+    int            mark;
+} llnode;
+
+static llnode *lltour = (llnode *) NULL;
+static cycle_size = 0;
+static int reversed = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    reversed = 0;
+    lltour[cyc[0]].name = cyc[0];
+    lltour[cyc[0]].mark = 0;
+    lltour[cyc[0]].next = &(lltour[cyc[1]]);
+    lltour[cyc[0]].prev = &(lltour[cyc[ncount - 1]]);
+    lltour[cyc[ncount - 1]].name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].mark = 0;
+    lltour[cyc[ncount - 1]].next = &(lltour[cyc[0]]);
+    lltour[cyc[ncount - 1]].prev = &(lltour[cyc[ncount - 2]]);
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].name = cyc[i];
+        lltour[cyc[i]].mark = 0;
+        lltour[cyc[i]].next = &(lltour[cyc[i + 1]]);
+        lltour[cyc[i]].prev = &(lltour[cyc[i - 1]]);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    llnode *n, *start;
+    int k = 0;
+
+    n = start = &(lltour[0]);
+
+    if (reversed) {
+        do {
+            x[k++] = n->name;
+            n = n->prev;
+        } while (n != start && k < cycle_size);
+    } else {
+        do {
+            x[k++] = n->name;
+            n = n->next;
+        } while (n != start && k < cycle_size);
+    }
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (reversed)
+        return lltour[x].prev->name;
+    else
+        return lltour[x].next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (reversed)
+        return lltour[x].next->name;
+    else
+        return lltour[x].prev->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    llnode *nxprev = &(lltour[xprev]);
+    llnode *nynext = &(lltour[ynext]);
+    llnode *nx = &(lltour[x]);
+    llnode *ny = &(lltour[y]);
+    llnode *n, *next, *prev;
+
+    if (x == y)
+        return;
+
+    if (reversed) {
+        next = nx->prev;
+        prev = nxprev->next;
+
+        while (next != ny && prev != nynext) {
+            next = next->prev;
+            prev = prev->next;
+        }
+
+        if (next == ny) {
+            next = nx->prev;
+            nx->prev = nx->next;
+            nx->next = next;
+            do {
+                n = next;
+                next = n->prev;
+                n->prev = n->next;
+                n->next = next;
+            } while (n != ny);
+            if (nxprev != ny) {
+                ny->next = nxprev;
+                nx->prev = nynext;
+                nxprev->prev = ny;
+                nynext->next = nx;
+            }
+        } else {
+            prev = nxprev->next;
+            nxprev->next = nxprev->prev;
+            nxprev->prev = prev;
+            do {
+                n = prev;
+                prev = n->next;
+                n->next = n->prev;
+                n->prev = prev;
+            } while (n != nynext);
+            if (nxprev != ny) {
+                ny->prev = nxprev;
+                nx->next = nynext;
+                nxprev->next = ny;
+                nynext->prev = nx;
+            }
+            reversed = 0;
+        }
+    } else {
+        next = nx->next;
+        prev = nxprev->prev;
+
+        while (next != ny && prev != nynext) {
+            next = next->next;
+            prev = prev->prev;
+        }
+
+        if (next == ny) {
+            next = nx->next;
+            nx->next = nx->prev;
+            nx->prev = next;
+            do {
+                n = next;
+                next = n->next;
+                n->next = n->prev;
+                n->prev = next;
+            } while (n != ny);
+            if (nxprev != ny) {
+                ny->prev = nxprev;
+                nx->next = nynext;
+                nxprev->next = ny;
+                nynext->prev = nx;
+            }
+        } else {
+            prev = nxprev->prev;
+            nxprev->prev = nxprev->next;
+            nxprev->next = prev;
+            do {
+                n = prev;
+                prev = n->prev;
+                n->prev = n->next;
+                n->next = prev;
+            } while (n != nynext);
+            if (nxprev != ny) {
+                ny->next = nxprev;
+                nx->prev = nynext;
+                nxprev->prev = ny;
+                nynext->next = nx;
+            }
+            reversed = 1;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    llnode *next, *prev;
+
+    if (x == z) {
+        return 1;
+    } else {
+        lltour[y].mark = 1;
+        lltour[z].mark = 1;
+
+        next = prev = &(lltour[x]);
+
+        while (!next->mark && !prev->mark) {
+            next = next->next;
+            prev = prev->prev;
+        }
+
+        if (reversed) {
+            if (prev->mark) {
+                lltour[y].mark = 0;
+                lltour[z].mark = 0;
+                return (prev->name == y);
+            } else {
+                lltour[y].mark = 0;
+                lltour[z].mark = 0;
+                return (next->name == z);
+            }
+        } else {
+            if (next->mark) {
+                lltour[y].mark = 0;
+                lltour[z].mark = 0;
+                return (next->name == y);
+            } else {
+                lltour[y].mark = 0;
+                lltour[z].mark = 0;
+                return (prev->name == z);
+            }
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll3.c b/contrib/blossom/concorde97/LINKERN/flip_ll3.c
new file mode 100644
index 0000000000000000000000000000000000000000..311b0e95263b9495769aaf7c1bf0b8adf7297a2e
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll3.c
@@ -0,0 +1,341 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked List w/ Neighbors  */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version should be very slow, since next and prev have to     */
+/*   hunt down an orientation node (since each node knows its neighbors    */
+/*   but not the direction). Flips will be fast, but there are not enough  */
+/*   enough of them to compensate for the next and prevs.                  */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 3  (flip_ll3.c):                                   */
+/*                                                                         */
+/*     1. Uses linked list with neighbors.                                 */
+/*     2. Need to track down a node of known orientation (the extra info   */
+/*        in the flips provides this).                                     */
+/*     3. The hunt is done by a seqeunce of if tests, moving along the     */
+/*        linked list, checking that we reach new nodes).                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+typedef struct llnode {
+    struct llnode *next;
+    struct llnode *prev;
+    int            name;
+    char           orient;
+    char           mark;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    dump_cycle (void);
+static int
+    find_orientation (llnode *n);
+
+#else
+
+static void
+    dump_cycle ();
+static int
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static llnode *orientnodes[2];
+static cycle_size = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].name = cyc[0];
+    lltour[cyc[0]].mark = 0;
+    lltour[cyc[0]].orient = 0;
+    lltour[cyc[0]].next = &(lltour[cyc[1]]);
+    lltour[cyc[0]].prev = &(lltour[cyc[ncount - 1]]);
+    lltour[cyc[ncount - 1]].name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].mark = 0;
+    lltour[cyc[ncount - 1]].orient = 0;
+    lltour[cyc[ncount - 1]].next = &(lltour[cyc[0]]);
+    lltour[cyc[ncount - 1]].prev = &(lltour[cyc[ncount - 2]]);
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].name = cyc[i];
+        lltour[cyc[i]].mark = 0;
+        lltour[cyc[i]].orient = 0;
+        lltour[cyc[i]].next = &(lltour[cyc[i + 1]]);
+        lltour[cyc[i]].prev = &(lltour[cyc[i - 1]]);
+    }
+    orientnodes[0] = &(lltour[cyc[0]]);
+    orientnodes[1] = &(lltour[cyc[ncount/2]]);
+    lltour[cyc[0]].orient = 1;
+    lltour[cyc[ncount/2]].orient = 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (llnode *s)
+#else
+static int find_orientation (s)
+llnode *s;
+#endif
+{
+    /* Returns 0 if next is next and 1 if next is really prev */
+
+    llnode *n, *p;
+
+    if (s->orient)
+        return 0;
+
+    p = s;
+    n = p->next;
+
+    while (!n->orient) {
+        if (n->next == p) {
+            p = n;
+            n = n->prev;
+        } else {
+            p = n;
+            n = n->next;
+        }
+    }
+    return (p != n->prev);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    llnode *n, *p, *start;
+    int k = 0;
+
+    p = start = &(lltour[0]);
+    n = (find_orientation (start) ? start->prev : start->next);
+
+    x[k++] = start->name;
+
+    do {
+        x[k++] = n->name;
+        if (n->next == p) {
+            p = n;
+            n = n->prev;
+        } else {
+            p = n;
+            n = n->next;
+        }
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (&(lltour[x])))
+        return lltour[x].prev->name;
+    else
+        return lltour[x].next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (&(lltour[x])))
+        return lltour[x].next->name;
+    else
+        return lltour[x].prev->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    llnode *nxprev = &(lltour[xprev]);
+    llnode *nynext = &(lltour[ynext]);
+    llnode *nx = &(lltour[x]);
+    llnode *ny = &(lltour[y]);
+
+    if (x == y) {
+        return;
+    }
+
+    orientnodes[0]->orient = 0;
+    orientnodes[1]->orient = 0;
+    orientnodes[0] = nxprev;
+    orientnodes[1] = nynext;
+    nxprev->orient = 1;
+    nynext->orient = 1;
+
+    if (nxprev == ny) {
+        if (nx->prev == ny) {
+            nx->prev = nx->next;
+            nx->next = ny;
+        }
+        if (ny->next == nx) {
+            ny->next = ny->prev;
+            ny->prev = nx;
+        }
+    } else {
+        if (nxprev->prev == nx)
+            nxprev->prev = nxprev->next;
+        nxprev->next = ny;
+
+        if (nynext->next == ny)
+            nynext->next = nynext->prev;
+        nynext->prev = nx;
+
+        if (nx->prev == nxprev)
+            nx->prev = nynext;
+        else
+            nx->next = nynext;
+
+        if (ny->next == nynext)
+            ny->next = nxprev;
+        else
+            ny->prev = nxprev;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    llnode *n, *p;
+
+    if (x == z || x == y) {
+        return 1;
+    } else {
+        lltour[y].mark = 1;
+        lltour[z].mark = 1;
+
+        p = &(lltour[x]);
+        n = (find_orientation (p) ? p->prev : p->next);
+
+        while (!n->mark) {
+            if (n->next == p) {
+                p = n;
+                n = n->prev;
+            } else {
+                p = n;
+                n = n->next;
+            }
+        }
+        lltour[y].mark = 0;
+        lltour[z].mark = 0;
+
+        return (n->name == y);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_cycle (void)
+#else
+static void dump_cycle ()
+#endif
+{
+    int *getit, i;
+
+    getit = CC_SAFE_MALLOC (cycle_size, int);
+    CClinkern_flipper_cycle (getit);
+
+    printf ("TOUR: ");
+
+    for (i = 0; i < cycle_size; i++)
+        printf ("%2d ", getit[i]);
+    printf ("\n");
+    fflush (stdout);
+
+    CC_FREE (getit, int);
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll4.c b/contrib/blossom/concorde97/LINKERN/flip_ll4.c
new file mode 100644
index 0000000000000000000000000000000000000000..44710410cbc26e6eec0875a02860f96d24f17cb9
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll4.c
@@ -0,0 +1,398 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked Lists (fwd & bwd)  */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version should be slow, since next and prev have to          */
+/*   hunt down an orientation node (since each node knows its neighbors    */
+/*   but not the direction), like flip_ll3, but the two copies of the tour */
+/*   (one in each direction) lets us avoid lost of if tests during the     */
+/*   hunt.                                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 4  (flip_ll4.c):                                   */
+/*                                                                         */
+/*     1. Uses two linked lists (forward and backward)                     */
+/*     2. Need to track down a node of known orientation (the extra info   */
+/*        in the flips provides this).                                     */
+/*     3. The hunt is done by a moving along one of the tours, till we hit */
+/*        an orientation node that will tell us if we are on the forward   */
+/*        or backward tour.                                                */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           dir;
+    char           orient;
+    char           mark;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  fwd;
+    struct oneway  bwd;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    find_orientation (int s);
+
+#else
+
+static int
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static llnode *orientnodes[2];
+static cycle_size = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].fwd.name = cyc[0];
+    lltour[cyc[0]].fwd.mark = 0;
+    lltour[cyc[0]].fwd.dir = FORWARD_TOUR;
+    lltour[cyc[0]].fwd.orient = 0;
+    lltour[cyc[0]].fwd.next = &(lltour[cyc[1]].fwd);
+    lltour[cyc[0]].bwd.name = cyc[0];
+    lltour[cyc[0]].bwd.mark = 0;
+    lltour[cyc[0]].bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[0]].bwd.orient = 0;
+    lltour[cyc[0]].bwd.next = &(lltour[cyc[ncount - 1]].bwd);
+    lltour[cyc[ncount - 1]].fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].fwd.mark = 0;
+    lltour[cyc[ncount - 1]].fwd.dir = FORWARD_TOUR;
+    lltour[cyc[ncount - 1]].fwd.orient = 0;
+    lltour[cyc[ncount - 1]].fwd.next = &(lltour[cyc[0]].fwd);
+    lltour[cyc[ncount - 1]].bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].bwd.mark = 0;
+    lltour[cyc[ncount - 1]].bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[ncount - 1]].bwd.orient = 0;
+    lltour[cyc[ncount - 1]].bwd.next = &(lltour[cyc[ncount - 2]].bwd);
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].fwd.name = cyc[i];
+        lltour[cyc[i]].fwd.mark = 0;
+        lltour[cyc[i]].fwd.dir = FORWARD_TOUR;
+        lltour[cyc[i]].fwd.orient = 0;
+        lltour[cyc[i]].fwd.next = &(lltour[cyc[i + 1]].fwd);
+        lltour[cyc[i]].bwd.name = cyc[i];
+        lltour[cyc[i]].bwd.mark = 0;
+        lltour[cyc[i]].bwd.dir = BACKWARD_TOUR;
+        lltour[cyc[i]].bwd.orient = 0;
+        lltour[cyc[i]].bwd.next = &(lltour[cyc[i - 1]].bwd);
+    }
+    orientnodes[0] = &(lltour[cyc[0]]);
+    orientnodes[1] = &(lltour[cyc[ncount/2]]);
+    lltour[cyc[0]].fwd.orient = 1;
+    lltour[cyc[0]].bwd.orient = 1;
+    lltour[cyc[ncount/2]].fwd.orient = 1;
+    lltour[cyc[ncount/2]].bwd.orient = 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = &(lltour[s].fwd);
+
+    while (!n->orient)
+        n = n->next;
+
+    return (n->dir != FORWARD_TOUR);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    n = start = (find_orientation (0) ? &(lltour[0].bwd) : &(lltour[0].fwd));
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd.next->name;
+    else
+        return lltour[x].fwd.next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd.next->name;
+    else
+        return lltour[x].bwd.next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    int xnext, yprev;
+
+    if (x == y)
+        return;
+
+    orientnodes[0]->fwd.orient = 0;
+    orientnodes[0]->bwd.orient = 0;
+    orientnodes[1]->fwd.orient = 0;
+    orientnodes[1]->bwd.orient = 0;
+    orientnodes[0] = &(lltour[x]);
+    orientnodes[1] = &(lltour[y]);
+    orientnodes[0]->fwd.orient = 1;
+    orientnodes[0]->bwd.orient = 1;
+    orientnodes[1]->fwd.orient = 1;
+    orientnodes[1]->bwd.orient = 1;
+
+    if (lltour[x].bwd.next->name == xprev)
+        xnext = lltour[x].fwd.next->name;
+    else
+        xnext = lltour[x].bwd.next->name;
+
+    if (lltour[y].bwd.next->name == ynext)
+        yprev = lltour[y].fwd.next->name;
+    else
+        yprev = lltour[y].bwd.next->name;
+
+    if (xprev == y) {
+        if (lltour[xnext].fwd.next->name == x) {
+            lltour[xnext].fwd.next = &(lltour[x].fwd);
+            lltour[x].bwd.next = &(lltour[xnext].bwd);
+        } else {
+            lltour[xnext].bwd.next = &(lltour[x].fwd);
+            lltour[x].bwd.next = &(lltour[xnext].fwd);
+        }
+
+        if (lltour[yprev].fwd.next->name == y) {
+            lltour[yprev].fwd.next = &(lltour[y].bwd);
+            lltour[y].fwd.next = &(lltour[yprev].bwd);
+        } else {
+            lltour[yprev].bwd.next = &(lltour[y].bwd);
+            lltour[y].fwd.next = &(lltour[yprev].fwd);
+        }
+
+        lltour[x].fwd.next = &(lltour[y].fwd);
+        lltour[y].bwd.next = &(lltour[x].bwd);
+    } else if (xnext == y) {
+        if (lltour[xprev].fwd.next->name == x) {
+            lltour[xprev].fwd.next = &(lltour[y].fwd);
+            lltour[y].bwd.next = &(lltour[xprev].bwd);
+        } else {
+            lltour[xprev].bwd.next = &(lltour[y].fwd);
+            lltour[y].bwd.next = &(lltour[xprev].fwd);
+        }
+
+        if (lltour[ynext].bwd.next->name == y) {
+            lltour[ynext].bwd.next = &(lltour[x].bwd);
+            lltour[x].fwd.next = &(lltour[ynext].fwd);
+        } else {
+            lltour[ynext].fwd.next = &(lltour[x].bwd);
+            lltour[x].fwd.next = &(lltour[ynext].bwd);
+        }
+
+        lltour[x].bwd.next = &(lltour[y].bwd);
+        lltour[y].fwd.next = &(lltour[x].fwd);
+    } else {
+        if (xnext == yprev) {
+            if (lltour[xnext].bwd.next->name == x) {
+                lltour[xnext].bwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].fwd);
+                lltour[xnext].fwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].bwd);
+            } else {
+                lltour[xnext].fwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].bwd);
+                lltour[xnext].bwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].fwd);
+            }
+        } else {
+            if (lltour[xnext].bwd.next->name == x) {
+                lltour[xnext].bwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].fwd);
+            } else {
+                lltour[xnext].fwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].bwd);
+            }
+            if (lltour[yprev].fwd.next->name == y) {
+                lltour[yprev].fwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].bwd);
+            } else {
+                lltour[yprev].bwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].fwd);
+            }
+        }
+
+        if (xprev == ynext) {
+            if (lltour[xprev].fwd.next->name == x) {
+                lltour[xprev].fwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].bwd);
+                lltour[xprev].bwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[xprev].fwd);
+            } else {
+                lltour[xprev].bwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].fwd);
+                lltour[xprev].fwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[xprev].bwd);
+            }
+        } else {
+            if (lltour[ynext].bwd.next->name == y) {
+                lltour[ynext].bwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[ynext].fwd);
+            } else {
+                lltour[ynext].fwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[ynext].bwd);
+            }
+            if (lltour[xprev].fwd.next->name == x) {
+                lltour[xprev].fwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].bwd);
+            } else {
+                lltour[xprev].bwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].fwd);
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *n;
+
+    if (x == z || x == y) {
+        return 1;
+    } else {
+        lltour[y].fwd.mark = 1;
+        lltour[y].bwd.mark = 1;
+        lltour[z].fwd.mark = 1;
+        lltour[z].bwd.mark = 1;
+
+        if (find_orientation (x))
+            n = &(lltour[x].bwd);
+        else
+            n = &(lltour[x].fwd);
+
+        while (!n->mark) {
+            n = n->next;
+        }
+        lltour[y].fwd.mark = 0;
+        lltour[y].bwd.mark = 0;
+        lltour[z].fwd.mark = 0;
+        lltour[z].bwd.mark = 0;
+
+        return (n->name == y);
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll5.c b/contrib/blossom/concorde97/LINKERN/flip_ll5.c
new file mode 100644
index 0000000000000000000000000000000000000000..cef43db5563a04f6352076a906611b0013c77021
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll5.c
@@ -0,0 +1,355 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked Lists (fwd & bwd)  */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       Like flip_ll4, but with fwd and bwd pointers.                     */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 5  (flip_ll5.c):                                   */
+/*                                                                         */
+/*     1. Same as flip_ll4, but fwd and bwd are now pointers.              */
+/*     2. The code is easier, and flips should be faster, but the hunts    */
+/*        should be slower(?).                                             */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           dir;
+    char           orient;
+    char           mark;
+    char           express;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct llnode  *next_express;
+    struct llnode  *prev_express;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    find_orientation (int s);
+
+#else
+
+static int
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static llnode *orientnodes[2];
+static cycle_size = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[0]].actual_fwd.orient = 0;
+    lltour[cyc[0]].actual_fwd.express = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[0]].actual_bwd.orient = 0;
+    lltour[cyc[0]].actual_bwd.express = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_fwd.orient = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_bwd.orient = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.dir = FORWARD_TOUR;
+        lltour[cyc[i]].actual_fwd.orient = 0;
+        lltour[cyc[i]].actual_fwd.express = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.dir = BACKWARD_TOUR;
+        lltour[cyc[i]].actual_bwd.orient = 0;
+        lltour[cyc[i]].actual_bwd.express = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+    orientnodes[0] = &(lltour[cyc[0]]);
+    orientnodes[1] = &(lltour[cyc[ncount/2]]);
+    lltour[cyc[0]].fwd->orient = 1;
+    lltour[cyc[0]].bwd->orient = 1;
+    lltour[cyc[ncount/2]].fwd->orient = 1;
+    lltour[cyc[ncount/2]].bwd->orient = 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->orient)
+        n = n->next;
+
+    return (n != lltour[n->name].fwd);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    start = (find_orientation (0) ? lltour[0].bwd : lltour[0].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd->next->name;
+    else
+        return lltour[x].fwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd->next->name;
+    else
+        return lltour[x].bwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    int xnext, yprev;
+    oneway *otemp;
+
+    if (x == y)
+        return;
+
+    orientnodes[0]->fwd->orient = 0;
+    orientnodes[0]->bwd->orient = 0;
+    orientnodes[1]->fwd->orient = 0;
+    orientnodes[1]->bwd->orient = 0;
+    orientnodes[0] = &(lltour[x]);
+    orientnodes[1] = &(lltour[y]);
+    orientnodes[0]->fwd->orient = 1;
+    orientnodes[0]->bwd->orient = 1;
+    orientnodes[1]->fwd->orient = 1;
+    orientnodes[1]->bwd->orient = 1;
+
+    if (lltour[x].bwd->next->name == xprev)
+        xnext = lltour[x].fwd->next->name;
+    else
+        xnext = lltour[x].bwd->next->name;
+
+    if (lltour[y].bwd->next->name == ynext)
+        yprev = lltour[y].fwd->next->name;
+    else
+        yprev = lltour[y].bwd->next->name;
+
+    if (xprev == y) {
+        if (lltour[x].fwd->next->name != y) {
+            SWAP (lltour[x].fwd, lltour[x].bwd, otemp);
+        }
+        if (lltour[y].bwd->next->name != x) {
+            SWAP (lltour[y].fwd, lltour[y].bwd, otemp);
+        }
+    } else {
+        if (lltour[x].bwd->next->name == xprev) {
+            SWAP (lltour[x].fwd, lltour[x].bwd, otemp);
+        }
+        if (lltour[y].fwd->next->name == ynext) {
+            SWAP (lltour[y].fwd, lltour[y].bwd, otemp);
+        }
+        if (xprev == ynext) {
+            if (lltour[ynext].fwd->next->name == y) {
+                lltour[y].bwd->next = lltour[ynext].bwd;
+                lltour[x].fwd->next = lltour[ynext].fwd;
+            } else {
+                lltour[y].bwd->next = lltour[ynext].fwd;
+                lltour[x].fwd->next = lltour[ynext].bwd;
+            }
+        } else {
+            if (lltour[ynext].fwd->next->name == y) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            }
+
+            if (lltour[xprev].fwd->next->name == x) {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *n;
+
+    if (x == z || x == y) {
+        return 1;
+    } else {
+        lltour[y].fwd->mark = 1;
+        lltour[y].bwd->mark = 1;
+        lltour[z].fwd->mark = 1;
+        lltour[z].bwd->mark = 1;
+
+        if (find_orientation (x))
+            n = lltour[x].bwd;
+        else
+            n = lltour[x].fwd;
+
+        while (!n->mark) {
+            n = n->next;
+        }
+        lltour[y].fwd->mark = 0;
+        lltour[y].bwd->mark = 0;
+        lltour[z].fwd->mark = 0;
+        lltour[z].bwd->mark = 0;
+
+        return (n->name == y);
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll6.c b/contrib/blossom/concorde97/LINKERN/flip_ll6.c
new file mode 100644
index 0000000000000000000000000000000000000000..24ffba99f6afc7c972a030dc540ef8a69cdcfb8c
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll6.c
@@ -0,0 +1,467 @@
+/***************************************************************************/
+/*                                                                         */
+/*  TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked Lists (express)   */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version uses 2-levels.                                       */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 6  (flip_ll6.c):                                   */
+/*                                                                         */
+/*     1. Like flip_ll5, but with an "express lane" subcircuit of about    */
+/*        sqrt (n) nodes. All nodes in the express lane have their fwd and */
+/*        and bwd pointers correctly oriented.                             */
+/*     2. The express lane is maintained as a linked list with explicit    */
+/*        nexts and prevs.                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           dir;
+    char           mark;
+    char           express;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct llnode  *next_express;
+    struct llnode  *prev_express;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    express_flip (int a, int b),
+    dump_cycle (void);
+static int
+    find_orientation (int s);
+
+#else
+
+static void
+    express_flip (),
+    dump_cycle ();
+static int
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static cycle_size = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j;
+    int groupsize;
+
+    cycle_size = ncount;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[0]].actual_fwd.express = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[0]].actual_bwd.express = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_fwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_bwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.dir = FORWARD_TOUR;
+        lltour[cyc[i]].actual_fwd.express = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.dir = BACKWARD_TOUR;
+        lltour[cyc[i]].actual_bwd.express = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+
+    groupsize = (int) sqrt ((double) ncount);
+    lltour[cyc[0]].actual_fwd.express = 1;
+    lltour[cyc[0]].actual_bwd.express = 1;
+    lltour[cyc[0]].next_express = &(lltour[cyc[groupsize]]);
+    i = groupsize;
+    j = ncount - groupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.express = 1;
+        lltour[cyc[i]].actual_bwd.express = 1;
+        lltour[cyc[i]].prev_express = &(lltour[cyc[i - groupsize]]);
+        lltour[cyc[i]].next_express = &(lltour[cyc[i + groupsize]]);
+        i += groupsize;
+    }
+    lltour[cyc[i]].actual_fwd.express = 1;
+    lltour[cyc[i]].actual_bwd.express = 1;
+    lltour[cyc[i]].next_express = &(lltour[cyc[0]]);
+    lltour[cyc[i]].prev_express = &(lltour[cyc[i - groupsize]]);
+    lltour[cyc[0]].prev_express = &(lltour[cyc[i]]);
+
+
+/*
+    dump_cycle ();
+*/
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_cycle (void)
+#else
+static void dump_cycle ()
+#endif
+{
+    int *getit, i;
+
+    getit = CC_SAFE_MALLOC (cycle_size, int);
+    CClinkern_flipper_cycle (getit);
+
+    printf ("TOUR: ");
+
+    for (i = 0; i < cycle_size; i++)
+        printf ("%2d ", getit[i]);
+    printf ("\n");
+    fflush (stdout);
+
+    {
+        llnode *n, *start;
+        oneway *p;
+
+        printf ("Express TOUR: ");
+        p = (find_orientation (getit[0]) ? lltour[getit[0]].bwd :
+                                           lltour[getit[0]].fwd);
+        while (!p->express)
+            p = p->next;
+
+        n = start = &(lltour[p->name]);
+        do {
+            printf ("%d ", n->fwd->name);
+            n = n->next_express;
+        } while (n != start);
+        printf ("\n");
+        fflush (stdout);
+    }
+
+    CC_FREE (getit, int);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->express)
+        n = n->next;
+
+    return (n != lltour[n->name].fwd);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    start = (find_orientation (0) ? lltour[0].bwd : lltour[0].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd->next->name;
+    else
+        return lltour[x].fwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd->next->name;
+    else
+        return lltour[x].bwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp;
+
+    if (x == y)
+        return;
+
+    if (lltour[x].bwd->next->name == xprev)
+        o = lltour[x].fwd;
+    else
+        o = lltour[x].bwd;
+
+    while (!o->express && o->name != y)
+        o = o->next;
+
+    if (o->express) {
+        if (lltour[y].fwd->next->name == ynext)
+            p = lltour[y].bwd;
+        else
+            p = lltour[y].fwd;
+        while (!p->express)
+            p = p->next;
+        express_flip (o->name, p->name);
+    }
+
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd->next->name == y) {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].fwd;
+            }
+        } else {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].fwd;
+            }
+        }
+
+        if (lltour[xprev].fwd->next->name == x) {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            }
+        } else {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    } else if (x != ynext) {
+        if (lltour[xprev].fwd->express) {
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip (int ix, int iy)
+#else
+static void express_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    llnode *x = &(lltour[ix]);
+    llnode *y = &(lltour[iy]);
+    llnode *xprev, *ynext;
+    llnode *n, *next;
+    oneway *otemp;
+
+    if (ix == iy) {
+        SWAP (x->fwd, x->bwd, otemp);
+        return;
+    }
+
+    xprev = x->prev_express;
+    ynext = y->next_express;
+
+    next = x->next_express;
+    x->next_express = x->prev_express;
+    x->prev_express = next;
+    SWAP (x->fwd, x->bwd, otemp);
+
+    do {
+        n = next;
+        next = n->next_express;
+        n->next_express = n->prev_express;
+        n->prev_express = next;
+        SWAP (n->fwd, n->bwd, otemp);
+    } while (n != y);
+
+    if (xprev != y) {
+        y->prev_express = xprev;
+        x->next_express = ynext;
+        xprev->next_express = y;
+        ynext->prev_express = x;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *next, *prev;
+
+    if (x == z || x == y) {
+        return 1;
+    } else {
+        lltour[y].fwd->mark = 1;
+        lltour[y].bwd->mark = 1;
+        lltour[z].fwd->mark = 1;
+        lltour[z].bwd->mark = 1;
+
+        if (find_orientation (x)) {
+            next = lltour[x].bwd;
+            prev = lltour[x].fwd;
+        } else {
+            next = lltour[x].fwd;
+            prev = lltour[x].bwd;
+        }
+
+        while (!next->mark && !prev->mark) {
+            next = next->next;
+            prev = prev->next;
+        }
+
+        if (next->mark) {
+            lltour[y].fwd->mark = 0;
+            lltour[y].bwd->mark = 0;
+            lltour[z].fwd->mark = 0;
+            lltour[z].bwd->mark = 0;
+            return (next->name == y);
+        } else {
+            lltour[y].fwd->mark = 0;
+            lltour[y].bwd->mark = 0;
+            lltour[z].fwd->mark = 0;
+            lltour[z].bwd->mark = 0;
+            return (prev->name == z);
+        }
+    }
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll7.c b/contrib/blossom/concorde97/LINKERN/flip_ll7.c
new file mode 100644
index 0000000000000000000000000000000000000000..aefb72d4df5371d56dd348eec4b077a42ac37290
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll7.c
@@ -0,0 +1,520 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked Lists (fwd & bwd)  */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       Like FLIPPER 6, but with reversal bit for the express cycle, and  */
+/*   and smaller groupsize (since flipping should be faster on bigger      */
+/*   cycles, so we can use the smaller groupsize to pick up the speed of   */
+/*   of the orientation finding routines).                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 7  (flip_ll7.c):                                   */
+/*                                                                         */
+/*     1. Like flip_ll6, but with reversal and smaller groupsize.          */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           dir;
+    char           mark;
+    char           express;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct llnode  *next_express;
+    struct llnode  *prev_express;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    express_flip (int a, int b);
+static int
+    find_orientation (int s);
+
+#else
+
+static void
+    express_flip ();
+static int
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static int cycle_size = 0;
+static int reversed = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j;
+    int groupsize;
+
+    cycle_size = ncount;
+    reversed = 0;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[0]].actual_fwd.express = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[0]].actual_bwd.express = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_fwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_bwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.dir = FORWARD_TOUR;
+        lltour[cyc[i]].actual_fwd.express = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.dir = BACKWARD_TOUR;
+        lltour[cyc[i]].actual_bwd.express = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+
+    groupsize = (int) (sqrt ((double) ncount) / 4.0);
+    if (groupsize < 3)
+        groupsize = 3;
+    lltour[cyc[0]].actual_fwd.express = 1;
+    lltour[cyc[0]].actual_bwd.express = 1;
+    lltour[cyc[0]].next_express = &(lltour[cyc[groupsize]]);
+    i = groupsize;
+    j = ncount - groupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.express = 1;
+        lltour[cyc[i]].actual_bwd.express = 1;
+        lltour[cyc[i]].prev_express = &(lltour[cyc[i - groupsize]]);
+        lltour[cyc[i]].next_express = &(lltour[cyc[i + groupsize]]);
+        i += groupsize;
+    }
+    lltour[cyc[i]].actual_fwd.express = 1;
+    lltour[cyc[i]].actual_bwd.express = 1;
+    lltour[cyc[i]].next_express = &(lltour[cyc[0]]);
+    lltour[cyc[i]].prev_express = &(lltour[cyc[i - groupsize]]);
+    lltour[cyc[0]].prev_express = &(lltour[cyc[i]]);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->express)
+        n = n->next;
+
+    if (reversed)
+        return (n != lltour[n->name].bwd);
+    else
+        return (n != lltour[n->name].fwd);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    start = (find_orientation (0) ? lltour[0].bwd : lltour[0].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd->next->name;
+    else
+        return lltour[x].fwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd->next->name;
+    else
+        return lltour[x].bwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp;
+
+    if (x == y)
+        return;
+
+    if (lltour[x].bwd->next->name == xprev)
+        o = lltour[x].fwd;
+    else
+        o = lltour[x].bwd;
+
+    while (!o->express && o->name != y)
+        o = o->next;
+
+    if (o->express) {
+        if (lltour[y].fwd->next->name == ynext)
+            p = lltour[y].bwd;
+        else
+            p = lltour[y].fwd;
+        while (!p->express)
+            p = p->next;
+        express_flip (o->name, p->name);
+    }
+
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd->next->name == y) {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].fwd;
+            }
+        } else {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].fwd;
+            }
+        }
+
+        if (lltour[xprev].fwd->next->name == x) {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            }
+        } else {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    } else if (x != ynext) {
+        if (lltour[xprev].fwd->express) {
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip (int ix, int iy)
+#else
+static void express_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    llnode *x = &(lltour[ix]);
+    llnode *y = &(lltour[iy]);
+    llnode *xprev, *ynext;
+    llnode *n, *next, *prev;
+    oneway *otemp;
+
+    if (x == y) {
+        SWAP (x->fwd, x->bwd, otemp);
+        return;
+    }
+
+    if (reversed) {
+        xprev = x->next_express;
+        if (xprev == y) {
+            reversed = 0;
+            return;
+        }
+        ynext = y->prev_express;
+
+        next = x->prev_express;
+        prev = xprev->next_express;
+
+        while (next != y && prev != ynext) {
+            next = next->prev_express;
+            prev = prev->next_express;
+        }
+
+        if (next == y) {
+            next = x->prev_express;
+            x->prev_express = x->next_express;
+            x->next_express = next;
+            SWAP (x->fwd, x->bwd, otemp);
+
+            do {
+                n = next;
+                next = n->prev_express;
+                n->prev_express = n->next_express;
+                n->next_express = next;
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != y);
+
+            if (xprev != y) {
+                y->next_express = xprev;
+                x->prev_express = ynext;
+                xprev->prev_express = y;
+                ynext->next_express = x;
+            }
+        } else {
+            prev = xprev->next_express;
+            xprev->next_express = xprev->prev_express;
+            xprev->prev_express = prev;
+            SWAP (xprev->fwd, xprev->bwd, otemp);
+
+            do {
+                n = prev;
+                prev = n->next_express;
+                n->next_express = n->prev_express;
+                n->prev_express = prev;
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != ynext);
+
+            if (xprev != y) {
+                y->prev_express = xprev;
+                x->next_express = ynext;
+                xprev->next_express = y;
+                ynext->prev_express = x;
+            }
+            reversed = 0;
+        }
+    } else {
+        xprev = x->prev_express;
+        if (xprev == y) {
+            reversed = 1;
+            return;
+        }
+        ynext = y->next_express;
+
+        next = x->next_express;
+        prev = xprev->prev_express;
+
+        while (next != y && prev != ynext) {
+            next = next->next_express;
+            prev = prev->prev_express;
+        }
+
+        if (next == y) {
+            next = x->next_express;
+            x->next_express = x->prev_express;
+            x->prev_express = next;
+            SWAP (x->fwd, x->bwd, otemp);
+
+            do {
+                n = next;
+                next = n->next_express;
+                n->next_express = n->prev_express;
+                n->prev_express = next;
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != y);
+
+            if (xprev != y) {
+                y->prev_express = xprev;
+                x->next_express = ynext;
+                xprev->next_express = y;
+                ynext->prev_express = x;
+            }
+        } else {
+            prev = xprev->prev_express;
+            xprev->prev_express = xprev->next_express;
+            xprev->next_express = prev;
+            SWAP (xprev->fwd, xprev->bwd, otemp);
+
+            do {
+                n = prev;
+                prev = n->prev_express;
+                n->prev_express = n->next_express;
+                n->next_express = prev;
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != ynext);
+
+            if (xprev != y) {
+                y->next_express = xprev;
+                x->prev_express = ynext;
+                xprev->prev_express = y;
+                ynext->next_express = x;
+            }
+            reversed = 1;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *next, *prev;
+
+    if (x == z || x == y) {
+        return 1;
+    } else {
+        lltour[y].fwd->mark = 1;
+        lltour[y].bwd->mark = 1;
+        lltour[z].fwd->mark = 1;
+        lltour[z].bwd->mark = 1;
+
+        if (find_orientation (x)) {
+            next = lltour[x].bwd;
+            prev = lltour[x].fwd;
+        } else {
+            next = lltour[x].fwd;
+            prev = lltour[x].bwd;
+        }
+
+        while (!next->mark && !prev->mark) {
+            next = next->next;
+            prev = prev->next;
+        }
+
+        if (next->mark) {
+            lltour[y].fwd->mark = 0;
+            lltour[y].bwd->mark = 0;
+            lltour[z].fwd->mark = 0;
+            lltour[z].bwd->mark = 0;
+            return (next->name == y);
+        } else {
+            lltour[y].fwd->mark = 0;
+            lltour[y].bwd->mark = 0;
+            lltour[z].fwd->mark = 0;
+            lltour[z].bwd->mark = 0;
+            return (prev->name == z);
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll8.c b/contrib/blossom/concorde97/LINKERN/flip_ll8.c
new file mode 100644
index 0000000000000000000000000000000000000000..c8a98c0f2bbdde886fa15b9dae9b465775b91f67
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll8.c
@@ -0,0 +1,731 @@
+/***************************************************************************/
+/*                                                                         */
+/*    TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - 3-Level Linked List    */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: June 22, 1995                                                    */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version should be the best of the linked lists so far.       */
+/*   It combines the oneway approach, with three levels for an express     */
+/*   lane and a superexpress lane. Note that all superexpress nodes are    */
+/*   also express nodes.                                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 8  (flip_ll8.c):                                   */
+/*                                                                         */
+/*     1. Uses three levels, the top having n**(1/3) nodes.                */
+/*     2. The top level has explicit next and prevs, the other levels      */
+/*        consist of two "oneway" cycles.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           mark;
+    char           level;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  actual_fwd_express;
+    struct oneway  actual_bwd_express;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct oneway  *fwd_express;
+    struct oneway  *bwd_express;
+    struct llnode  *next_super;
+    struct llnode  *prev_super;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    express_flip (int aprev, int a, int b, int bnext),
+    super_flip (int a, int b);
+static int
+    express_flipper_sequence (int x, int y, int z),
+    find_orientation (int s);
+
+#else
+
+static void
+    express_flip (),
+    super_flip ();
+static int
+    express_flipper_sequence (),
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static int cycle_size = 0;
+static int reversed = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j;
+    int groupsize, supergroupsize;
+
+    cycle_size = ncount;
+    reversed = 0;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.level = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.level = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.level = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.level = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+
+    groupsize = (int) (pow ((double) ncount, 1.0 / 3.0)/ 1.5);
+    supergroupsize = groupsize * groupsize;
+    lltour[cyc[0]].actual_fwd.level = 1;
+    lltour[cyc[0]].actual_bwd.level = 1;
+    lltour[cyc[0]].fwd_express = &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[0]].bwd_express = &(lltour[cyc[0]].actual_bwd_express);
+    lltour[cyc[0]].actual_fwd_express.mark = 0;
+    lltour[cyc[0]].actual_bwd_express.mark = 0;
+    lltour[cyc[0]].actual_fwd_express.level = 1;
+    lltour[cyc[0]].actual_bwd_express.level = 1;
+    lltour[cyc[0]].actual_fwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_bwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_fwd_express.next =
+                          &(lltour[cyc[groupsize]].actual_fwd_express);
+    i = groupsize;
+    j = ncount - groupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 1;
+        lltour[cyc[i]].actual_bwd.level = 1;
+        lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+        lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+        lltour[cyc[i]].actual_fwd_express.mark = 0;
+        lltour[cyc[i]].actual_bwd_express.mark = 0;
+        lltour[cyc[i]].actual_fwd_express.level = 1;
+        lltour[cyc[i]].actual_bwd_express.level = 1;
+        lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[i + groupsize]].actual_fwd_express);
+        lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+        i += groupsize;
+    }
+
+    lltour[cyc[i]].actual_fwd.level = 1;
+    lltour[cyc[i]].actual_bwd.level = 1;
+    lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+    lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+    lltour[cyc[i]].actual_fwd_express.mark = 0;
+    lltour[cyc[i]].actual_bwd_express.mark = 0;
+    lltour[cyc[i]].actual_fwd_express.level = 1;
+    lltour[cyc[i]].actual_bwd_express.level = 1;
+    lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+    lltour[cyc[0]].actual_bwd_express.next =
+                          &(lltour[cyc[i]].actual_bwd_express);
+
+    lltour[cyc[0]].actual_fwd.level = 2;
+    lltour[cyc[0]].actual_bwd.level = 2;
+    lltour[cyc[0]].actual_fwd_express.level = 2;
+    lltour[cyc[0]].actual_bwd_express.level = 2;
+    lltour[cyc[0]].next_super = &(lltour[cyc[supergroupsize]]);
+    i = supergroupsize;
+    j = ncount - supergroupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 2;
+        lltour[cyc[i]].actual_bwd.level = 2;
+        lltour[cyc[i]].actual_fwd_express.level = 2;
+        lltour[cyc[i]].actual_bwd_express.level = 2;
+        lltour[cyc[i]].prev_super = &(lltour[cyc[i - supergroupsize]]);
+        lltour[cyc[i]].next_super = &(lltour[cyc[i + supergroupsize]]);
+        i += supergroupsize;
+    }
+    lltour[cyc[i]].actual_fwd.level = 2;
+    lltour[cyc[i]].actual_bwd.level = 2;
+    lltour[cyc[i]].actual_fwd_express.level = 2;
+    lltour[cyc[i]].actual_bwd_express.level = 2;
+    lltour[cyc[i]].next_super = &(lltour[cyc[0]]);
+    lltour[cyc[i]].prev_super = &(lltour[cyc[i - supergroupsize]]);
+    lltour[cyc[0]].prev_super = &(lltour[cyc[i]]);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->level)
+        n = n->next;
+
+    if (lltour[n->name].fwd == n)
+        n = lltour[n->name].fwd_express;
+    else
+        n = lltour[n->name].bwd_express;
+
+    while (n->level != 2)
+        n = n->next;
+
+    if (reversed)
+        return (n != lltour[n->name].bwd_express);
+    else
+        return (n != lltour[n->name].fwd_express);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    start = (find_orientation (0) ? lltour[0].bwd : lltour[0].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd->next->name;
+    else
+        return lltour[x].fwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd->next->name;
+    else
+        return lltour[x].bwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *oprev, *pnext;
+
+    if (x == y)
+        return;
+
+    if (lltour[x].bwd->next->name == xprev)
+        o = lltour[x].fwd;
+    else
+        o = lltour[x].bwd;
+
+    while (!o->level && o->name != y)
+        o = o->next;
+
+    if (o->level) {
+        if (lltour[o->name].fwd == o)
+            oprev = lltour[o->name].bwd->next;
+        else
+            oprev = lltour[o->name].fwd->next;
+        while (!oprev->level)
+            oprev = oprev->next;
+        if (lltour[y].fwd->next->name == ynext)
+            p = lltour[y].bwd;
+        else
+            p = lltour[y].fwd;
+        while (!p->level)
+            p = p->next;
+        if (lltour[p->name].fwd == p)
+            pnext = lltour[p->name].bwd->next;
+        else
+            pnext = lltour[p->name].fwd->next;
+        while (!pnext->level)
+            pnext = pnext->next;
+        express_flip (oprev->name, o->name, p->name, pnext->name);
+    }
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd->next->name == y) {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].fwd;
+            }
+        } else {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].fwd;
+            }
+        }
+
+        if (lltour[xprev].fwd->next->name == x) {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            }
+        } else {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    } else if (x != ynext) {
+        oneway *otemp;
+        if (lltour[xprev].fwd->level) {
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip (int xprev, int x, int y, int ynext)
+#else
+static void express_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp;
+
+    if (x == y) {
+        SWAP (lltour[x].fwd, lltour[x].bwd, otemp);
+        return;
+    } else if (xprev == ynext) {
+        SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (lltour[x].bwd_express->next->name == xprev) {
+        o = lltour[x].fwd_express;
+    } else {
+        o = lltour[x].bwd_express;
+    }
+
+    while (o->level != 2 && o->name != y)
+        o = o->next;
+
+    if (o->level == 2) {
+        if (lltour[y].fwd_express->next->name == ynext)
+            p = lltour[y].bwd_express;
+        else
+            p = lltour[y].fwd_express;
+        while (p->level != 2)
+            p = p->next;
+        super_flip (o->name, p->name);
+    }
+
+
+    if (x != ynext) {
+        if (lltour[ynext].fwd_express->next->name == y) {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].fwd_express;
+            }
+        } else {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].fwd_express;
+            }
+        }
+
+        if (lltour[xprev].fwd_express->next->name == x) {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].fwd_express;
+            }
+        } else {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].fwd_express;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void super_flip (int ix, int iy)
+#else
+static void super_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    llnode *x = &(lltour[ix]);
+    llnode *y = &(lltour[iy]);
+    llnode *xprev, *ynext;
+    llnode *n, *next, *prev;
+    oneway *otemp;
+
+    if (x == y) {
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+        return;
+    }
+
+    if (reversed) {
+        xprev = x->next_super;
+        ynext = y->prev_super;
+
+        next = x->prev_super;
+        prev = xprev->next_super;
+
+        while (next != y && prev != ynext) {
+            next = next->prev_super;
+            prev = prev->next_super;
+        }
+
+        if (next == y) {
+            next = x->prev_super;
+            x->prev_super = x->next_super;
+            x->next_super = next;
+            SWAP (x->fwd_express, x->bwd_express, otemp);
+            SWAP (x->fwd, x->bwd, otemp);
+
+            do {
+                n = next;
+                next = n->prev_super;
+                n->prev_super = n->next_super;
+                n->next_super = next;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != y);
+
+            if (xprev != y) {
+                y->next_super = xprev;
+                x->prev_super = ynext;
+                xprev->prev_super = y;
+                ynext->next_super = x;
+            }
+        } else {
+            prev = xprev->next_super;
+            xprev->next_super = xprev->prev_super;
+            xprev->prev_super = prev;
+            SWAP (xprev->fwd_express, xprev->bwd_express, otemp);
+            SWAP (xprev->fwd, xprev->bwd, otemp);
+
+            do {
+                n = prev;
+                prev = n->next_super;
+                n->next_super = n->prev_super;
+                n->prev_super = prev;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != ynext);
+
+            if (xprev != y) {
+                y->prev_super = xprev;
+                x->next_super = ynext;
+                xprev->next_super = y;
+                ynext->prev_super = x;
+            }
+            reversed = 0;
+        }
+    } else {
+        xprev = x->prev_super;
+        ynext = y->next_super;
+
+        next = x->next_super;
+        prev = xprev->prev_super;
+
+        while (next != y && prev != ynext) {
+            next = next->next_super;
+            prev = prev->prev_super;
+        }
+
+        if (next == y) {
+            next = x->next_super;
+            x->next_super = x->prev_super;
+            x->prev_super = next;
+            SWAP (x->fwd_express, x->bwd_express, otemp);
+            SWAP (x->fwd, x->bwd, otemp);
+
+            do {
+                n = next;
+                next = n->next_super;
+                n->next_super = n->prev_super;
+                n->prev_super = next;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != y);
+
+            if (xprev != y) {
+                y->prev_super = xprev;
+                x->next_super = ynext;
+                xprev->next_super = y;
+                ynext->prev_super = x;
+            }
+        } else {
+            prev = xprev->prev_super;
+            xprev->prev_super = xprev->next_super;
+            xprev->next_super = prev;
+            SWAP (xprev->fwd_express, xprev->bwd_express, otemp);
+            SWAP (xprev->fwd, xprev->bwd, otemp);
+
+            do {
+                n = prev;
+                prev = n->prev_super;
+                n->prev_super = n->next_super;
+                n->next_super = prev;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != ynext);
+
+            if (xprev != y) {
+                y->next_super = xprev;
+                x->prev_super = ynext;
+                xprev->prev_super = y;
+                ynext->next_super = x;
+            }
+            reversed = 1;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *px, *py, *pz;
+
+    if (x == z || x == y)
+        return 1;
+    if (find_orientation (x))
+        px = lltour[x].bwd;
+    else
+        px = lltour[x].fwd;
+    while (!px->level) {
+        px = px->next;
+        if (px->name == y)
+            return 1;
+        else if (px->name == z)
+            return 0;
+    }
+
+    if (z == y)
+        return 1;
+    if (find_orientation (z))
+        pz = lltour[z].fwd;
+    else
+        pz = lltour[z].bwd;
+    while (!pz->level) {
+        pz = pz->next;
+        if (pz->name == y) {
+            return 1;
+        } else if (pz->name == x) {
+            return 0;
+        } else if (px->name == pz->name) {
+            return 0;
+        }
+    }
+
+    if (find_orientation (y))
+        py = lltour[y].bwd;
+    else
+        py = lltour[y].fwd;
+    while (!py->level) {
+        py = py->next;
+        if (py->name == z) {
+            return 1;
+        } else if (py->name == x) {
+            return 0;
+        } else if (py->name == pz->name) {
+            return 1;
+        } else if (py->name == px->name) {
+            return 0;
+        }
+    }
+    return express_flipper_sequence (px->name, py->name, pz->name);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int express_flipper_sequence (int x, int y, int z)
+#else
+static int express_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *next, *prev;
+
+    lltour[y].fwd_express->mark = 1;
+    lltour[y].bwd_express->mark = 1;
+    lltour[z].fwd_express->mark = 1;
+    lltour[z].bwd_express->mark = 1;
+
+    if (find_orientation (x)) {
+        next = lltour[x].bwd_express;
+        prev = lltour[x].fwd_express;
+    } else {
+        next = lltour[x].fwd_express;
+        prev = lltour[x].bwd_express;
+    }
+
+    while (!next->mark && !prev->mark) {
+        next = next->next;
+        prev = prev->next;
+    }
+
+    if (next->mark) {
+        lltour[y].fwd_express->mark = 0;
+        lltour[y].bwd_express->mark = 0;
+        lltour[z].fwd_express->mark = 0;
+        lltour[z].bwd_express->mark = 0;
+        return (next->name == y);
+    } else {
+        lltour[y].fwd_express->mark = 0;
+        lltour[y].bwd_express->mark = 0;
+        lltour[z].fwd_express->mark = 0;
+        lltour[z].bwd_express->mark = 0;
+        return (prev->name == z);
+    }
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_ll9.c b/contrib/blossom/concorde97/LINKERN/flip_ll9.c
new file mode 100644
index 0000000000000000000000000000000000000000..f9e1011b6368c6001b4bffd02bcf6da02bcbb64b
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_ll9.c
@@ -0,0 +1,299 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Basic Linked List w/ Rev  */
+/*                                             - USES INDEX                */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version uses very little memory, and is reasonably fast      */
+/*   for small problems and for twoopts (but you should have SHORT_SIDE    */
+/*   defined so that the smaller side a flip is carried out.               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 0  (flip_ll0.c):  ADDS INDEX                       */
+/*                                                                         */
+/*     1. Uses linked list with known prev and next.                       */
+/*     2. Tour reversal bit.                                               */
+/*     2. Next and prev given explicitly.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+typedef struct llnode {
+    struct llnode *next;
+    struct llnode *prev;
+    int            name;
+    int            mark;
+    int            index;
+} llnode;
+
+static llnode *lltour = (llnode *) NULL;
+static cycle_size = 0;
+static int reversed = 0;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    flipper_flip_work (int xprev, int x, int y, int ynext);
+#else
+static void
+    flipper_flip_work ();
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    reversed = 0;
+    lltour[cyc[0]].name = cyc[0];
+    lltour[cyc[0]].mark = 0;
+    lltour[cyc[0]].next = &(lltour[cyc[1]]);
+    lltour[cyc[0]].prev = &(lltour[cyc[ncount - 1]]);
+    lltour[cyc[0]].index = 0;
+    lltour[cyc[ncount - 1]].name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].mark = 0;
+    lltour[cyc[ncount - 1]].next = &(lltour[cyc[0]]);
+    lltour[cyc[ncount - 1]].prev = &(lltour[cyc[ncount - 2]]);
+    lltour[cyc[ncount - 1]].index = ncount - 1;
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].name = cyc[i];
+        lltour[cyc[i]].mark = 0;
+        lltour[cyc[i]].next = &(lltour[cyc[i + 1]]);
+        lltour[cyc[i]].prev = &(lltour[cyc[i - 1]]);
+        lltour[cyc[i]].index = i;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    llnode *n, *start;
+    int k = 0;
+
+    n = start = &(lltour[0]);
+
+    if (reversed) {
+        do {
+            x[k++] = n->name;
+            n = n->prev;
+        } while (n != start && k < cycle_size);
+    } else {
+        do {
+            x[k++] = n->name;
+            n = n->next;
+        } while (n != start && k < cycle_size);
+    }
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (reversed)
+        return lltour[x].prev->name;
+    else
+        return lltour[x].next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (reversed)
+        return lltour[x].next->name;
+    else
+        return lltour[x].prev->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    int side;
+
+    if (reversed)
+        side = lltour[x].index - lltour[y].index;
+    else
+        side = lltour[y].index - lltour[x].index;
+    if (side < 0)
+        side += cycle_size;
+
+    if (side < cycle_size / 2)
+         flipper_flip_work (xprev, x, y, ynext);
+    else {
+         flipper_flip_work (y, ynext, xprev, x);
+         reversed ^= 1;
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper_flip_work (int xprev, int x, int y, int ynext)
+#else
+static void flipper_flip_work (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    llnode *nxprev = &(lltour[xprev]);
+    llnode *nynext = &(lltour[ynext]);
+    llnode *nx = &(lltour[x]);
+    llnode *ny = &(lltour[y]);
+    llnode *n, *next;
+    int id = lltour[x].index;
+
+    if (x == y)
+        return;
+
+    if (reversed) {
+        n = ny->next;
+        ny->next = ny->prev;
+        ny->prev = n;
+        ny->index = id--;
+        while (n != nx) {
+            next = n->next;
+            n->next = n->prev;
+            n->prev = next;
+            n->index = id--;
+            n = next;
+        }
+        next = nx->next;
+        nx->next = nx->prev;
+        nx->prev = next;
+        nx->index = id;
+        if (nxprev != ny) {
+            ny->next = nxprev;
+            nx->prev = nynext;
+            nxprev->prev = ny;
+            nynext->next = nx;
+        }
+    } else {
+        n = ny->prev;
+        ny->prev = ny->next;
+        ny->next = n;
+        ny->index = id++;
+        while (n != nx) {
+            next = n->prev;
+            n->prev = n->next;
+            n->next = next;
+            n->index = id++;
+            n = next;
+        }
+        next = nx->prev;
+        nx->prev = nx->next;
+        nx->next = next;
+        nx->index = id;
+        if (nxprev != ny) {
+            ny->prev = nxprev;
+            nx->next = nynext;
+            nxprev->next = ny;
+            nynext->prev = nx;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    int a = lltour[x].index;
+    int b = lltour[y].index;
+    int c = lltour[z].index;
+
+    if (reversed) {
+        if (a >= b)
+            return (b >= c || c >= a);
+        else
+            return (b >= c && c >= a);
+    } else {
+        if (a <= b)
+            return (b <= c || c <= a);
+        else
+            return (b <= c && c <= a);
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_llA.c b/contrib/blossom/concorde97/LINKERN/flip_llA.c
new file mode 100644
index 0000000000000000000000000000000000000000..d319eff2ee8c7b17ccafdf5fa5fde5a04a314295
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_llA.c
@@ -0,0 +1,404 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked Lists (fwd & bwd)  */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version should be slow, since next and prev have to          */
+/*   hunt down an orientation node (since each node knows its neighbors    */
+/*   but not the direction), like flip_ll3, but the two copies of the tour */
+/*   (one in each direction) lets us avoid lost of if tests during the     */
+/*   hunt.                                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 4  (flip_ll4.c):                                   */
+/*                                                                         */
+/*     1. Uses two linked lists (forward and backward)                     */
+/*     2. Need to track down a node of known orientation (the extra info   */
+/*        in the flips provides this).                                     */
+/*     3. The hunt is done by a moving along one of the tours, till we hit */
+/*        an orientation node that will tell us if we are on the forward   */
+/*        or backward tour.                                                */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           dir;
+    char           orient;
+    char           mark;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  fwd;
+    struct oneway  bwd;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    find_orientation (int s);
+
+#else
+
+static int
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static llnode *orientnodes[2];
+static cycle_size = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    cycle_size = ncount;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].fwd.name = cyc[0];
+    lltour[cyc[0]].fwd.mark = 0;
+    lltour[cyc[0]].fwd.dir = FORWARD_TOUR;
+    lltour[cyc[0]].fwd.orient = 0;
+    lltour[cyc[0]].fwd.next = &(lltour[cyc[1]].fwd);
+    lltour[cyc[0]].bwd.name = cyc[0];
+    lltour[cyc[0]].bwd.mark = 0;
+    lltour[cyc[0]].bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[0]].bwd.orient = 0;
+    lltour[cyc[0]].bwd.next = &(lltour[cyc[ncount - 1]].bwd);
+    lltour[cyc[ncount - 1]].fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].fwd.mark = 0;
+    lltour[cyc[ncount - 1]].fwd.dir = FORWARD_TOUR;
+    lltour[cyc[ncount - 1]].fwd.orient = 0;
+    lltour[cyc[ncount - 1]].fwd.next = &(lltour[cyc[0]].fwd);
+    lltour[cyc[ncount - 1]].bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].bwd.mark = 0;
+    lltour[cyc[ncount - 1]].bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[ncount - 1]].bwd.orient = 0;
+    lltour[cyc[ncount - 1]].bwd.next = &(lltour[cyc[ncount - 2]].bwd);
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].fwd.name = cyc[i];
+        lltour[cyc[i]].fwd.mark = 0;
+        lltour[cyc[i]].fwd.dir = FORWARD_TOUR;
+        lltour[cyc[i]].fwd.orient = 0;
+        lltour[cyc[i]].fwd.next = &(lltour[cyc[i + 1]].fwd);
+        lltour[cyc[i]].bwd.name = cyc[i];
+        lltour[cyc[i]].bwd.mark = 0;
+        lltour[cyc[i]].bwd.dir = BACKWARD_TOUR;
+        lltour[cyc[i]].bwd.orient = 0;
+        lltour[cyc[i]].bwd.next = &(lltour[cyc[i - 1]].bwd);
+    }
+    orientnodes[0] = &(lltour[cyc[0]]);
+    orientnodes[1] = &(lltour[cyc[ncount/2]]);
+    lltour[cyc[0]].fwd.orient = 1;
+    lltour[cyc[0]].bwd.orient = 1;
+    lltour[cyc[ncount/2]].fwd.orient = 1;
+    lltour[cyc[ncount/2]].bwd.orient = 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = &(lltour[s].fwd);
+    oneway *p = &(lltour[s].bwd);
+
+    while (!n->orient && !p->orient) {
+        n = n->next;
+        p = p->next;
+    }
+
+    if (n->orient)
+        return (n->dir != FORWARD_TOUR);
+    else
+        return (p->dir != BACKWARD_TOUR);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    n = start = (find_orientation (0) ? &(lltour[0].bwd) : &(lltour[0].fwd));
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd.next->name;
+    else
+        return lltour[x].fwd.next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd.next->name;
+    else
+        return lltour[x].bwd.next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    int xnext, yprev;
+
+    if (x == y)
+        return;
+
+    orientnodes[0]->fwd.orient = 0;
+    orientnodes[0]->bwd.orient = 0;
+    orientnodes[1]->fwd.orient = 0;
+    orientnodes[1]->bwd.orient = 0;
+    orientnodes[0] = &(lltour[x]);
+    orientnodes[1] = &(lltour[y]);
+    orientnodes[0]->fwd.orient = 1;
+    orientnodes[0]->bwd.orient = 1;
+    orientnodes[1]->fwd.orient = 1;
+    orientnodes[1]->bwd.orient = 1;
+
+    if (lltour[x].bwd.next->name == xprev)
+        xnext = lltour[x].fwd.next->name;
+    else
+        xnext = lltour[x].bwd.next->name;
+
+    if (lltour[y].bwd.next->name == ynext)
+        yprev = lltour[y].fwd.next->name;
+    else
+        yprev = lltour[y].bwd.next->name;
+
+    if (xprev == y) {
+        if (lltour[xnext].fwd.next->name == x) {
+            lltour[xnext].fwd.next = &(lltour[x].fwd);
+            lltour[x].bwd.next = &(lltour[xnext].bwd);
+        } else {
+            lltour[xnext].bwd.next = &(lltour[x].fwd);
+            lltour[x].bwd.next = &(lltour[xnext].fwd);
+        }
+
+        if (lltour[yprev].fwd.next->name == y) {
+            lltour[yprev].fwd.next = &(lltour[y].bwd);
+            lltour[y].fwd.next = &(lltour[yprev].bwd);
+        } else {
+            lltour[yprev].bwd.next = &(lltour[y].bwd);
+            lltour[y].fwd.next = &(lltour[yprev].fwd);
+        }
+
+        lltour[x].fwd.next = &(lltour[y].fwd);
+        lltour[y].bwd.next = &(lltour[x].bwd);
+    } else if (xnext == y) {
+        if (lltour[xprev].fwd.next->name == x) {
+            lltour[xprev].fwd.next = &(lltour[y].fwd);
+            lltour[y].bwd.next = &(lltour[xprev].bwd);
+        } else {
+            lltour[xprev].bwd.next = &(lltour[y].fwd);
+            lltour[y].bwd.next = &(lltour[xprev].fwd);
+        }
+
+        if (lltour[ynext].bwd.next->name == y) {
+            lltour[ynext].bwd.next = &(lltour[x].bwd);
+            lltour[x].fwd.next = &(lltour[ynext].fwd);
+        } else {
+            lltour[ynext].fwd.next = &(lltour[x].bwd);
+            lltour[x].fwd.next = &(lltour[ynext].bwd);
+        }
+
+        lltour[x].bwd.next = &(lltour[y].bwd);
+        lltour[y].fwd.next = &(lltour[x].fwd);
+    } else {
+        if (xnext == yprev) {
+            if (lltour[xnext].bwd.next->name == x) {
+                lltour[xnext].bwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].fwd);
+                lltour[xnext].fwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].bwd);
+            } else {
+                lltour[xnext].fwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].bwd);
+                lltour[xnext].bwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].fwd);
+            }
+        } else {
+            if (lltour[xnext].bwd.next->name == x) {
+                lltour[xnext].bwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].fwd);
+            } else {
+                lltour[xnext].fwd.next = &(lltour[x].fwd);
+                lltour[x].bwd.next = &(lltour[xnext].bwd);
+            }
+            if (lltour[yprev].fwd.next->name == y) {
+                lltour[yprev].fwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].bwd);
+            } else {
+                lltour[yprev].bwd.next = &(lltour[y].bwd);
+                lltour[y].fwd.next = &(lltour[yprev].fwd);
+            }
+        }
+
+        if (xprev == ynext) {
+            if (lltour[xprev].fwd.next->name == x) {
+                lltour[xprev].fwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].bwd);
+                lltour[xprev].bwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[xprev].fwd);
+            } else {
+                lltour[xprev].bwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].fwd);
+                lltour[xprev].fwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[xprev].bwd);
+            }
+        } else {
+            if (lltour[ynext].bwd.next->name == y) {
+                lltour[ynext].bwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[ynext].fwd);
+            } else {
+                lltour[ynext].fwd.next = &(lltour[x].bwd);
+                lltour[x].fwd.next = &(lltour[ynext].bwd);
+            }
+            if (lltour[xprev].fwd.next->name == x) {
+                lltour[xprev].fwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].bwd);
+            } else {
+                lltour[xprev].bwd.next = &(lltour[y].fwd);
+                lltour[y].bwd.next = &(lltour[xprev].fwd);
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *n;
+
+    if (x == z || x == y) {
+        return 1;
+    } else {
+        lltour[y].fwd.mark = 1;
+        lltour[y].bwd.mark = 1;
+        lltour[z].fwd.mark = 1;
+        lltour[z].bwd.mark = 1;
+
+        if (find_orientation (x))
+            n = &(lltour[x].bwd);
+        else
+            n = &(lltour[x].fwd);
+
+        while (!n->mark) {
+            n = n->next;
+        }
+        lltour[y].fwd.mark = 0;
+        lltour[y].bwd.mark = 0;
+        lltour[z].fwd.mark = 0;
+        lltour[z].bwd.mark = 0;
+
+        return (n->name == y);
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_llB.c b/contrib/blossom/concorde97/LINKERN/flip_llB.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd5c4954e9da895136c802f34acd880e3ccb5f55
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_llB.c
@@ -0,0 +1,547 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Linked Lists (fwd & bwd)  */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       Like FLIPPER 6, but with reversal bit for the express cycle, and  */
+/*   and smaller groupsize (since flipping should be faster on bigger      */
+/*   cycles, so we can use the smaller groupsize to pick up the speed of   */
+/*   of the orientation finding routines).                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 7  (flip_ll7.c):  (ADDS INDEX)                     */
+/*                                                                         */
+/*     1. Like flip_ll6, but with reversal and smaller groupsize.          */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+#define GROUP_FACTOR 8.0
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           dir;
+    char           mark;
+    char           express;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct llnode  *next_express;
+    struct llnode  *prev_express;
+    int            index;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    express_flip (int a, int b),
+    express_flip_work (llnode *x, llnode *y);
+static int
+    find_orientation (int s);
+
+#else
+
+static void
+    express_flip (),
+    express_flip_work ();
+static int
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static int cycle_size = 0;
+static int express_cycle_size = 0;
+static int reversed = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j, k;
+    int groupsize;
+
+    cycle_size = ncount;
+    reversed = 0;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[0]].actual_fwd.express = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[0]].actual_bwd.express = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.dir = FORWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_fwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.dir = BACKWARD_TOUR;
+    lltour[cyc[ncount - 1]].actual_bwd.express = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.dir = FORWARD_TOUR;
+        lltour[cyc[i]].actual_fwd.express = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.dir = BACKWARD_TOUR;
+        lltour[cyc[i]].actual_bwd.express = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+
+    groupsize = (int) (sqrt ((double) ncount) / GROUP_FACTOR);
+    if (groupsize < 3)
+        groupsize = 3;
+    lltour[cyc[0]].actual_fwd.express = 1;
+    lltour[cyc[0]].actual_bwd.express = 1;
+    lltour[cyc[0]].next_express = &(lltour[cyc[groupsize]]);
+    lltour[cyc[0]].index = 0;
+    i = groupsize;
+    j = ncount - groupsize;
+    k = 1;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.express = 1;
+        lltour[cyc[i]].actual_bwd.express = 1;
+        lltour[cyc[i]].prev_express = &(lltour[cyc[i - groupsize]]);
+        lltour[cyc[i]].next_express = &(lltour[cyc[i + groupsize]]);
+        lltour[cyc[i]].index = k++;
+        i += groupsize;
+    }
+    lltour[cyc[i]].actual_fwd.express = 1;
+    lltour[cyc[i]].actual_bwd.express = 1;
+    lltour[cyc[i]].index = k;
+    lltour[cyc[i]].next_express = &(lltour[cyc[0]]);
+    lltour[cyc[i]].prev_express = &(lltour[cyc[i - groupsize]]);
+    lltour[cyc[0]].prev_express = &(lltour[cyc[i]]);
+    express_cycle_size = k+1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->express)
+        n = n->next;
+
+    if (reversed)
+        return (n != lltour[n->name].bwd);
+    else
+        return (n != lltour[n->name].fwd);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    start = (find_orientation (0) ? lltour[0].bwd : lltour[0].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd->next->name;
+    else
+        return lltour[x].fwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd->next->name;
+    else
+        return lltour[x].bwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp;
+
+    if (x == y)
+        return;
+
+    if (lltour[x].bwd->next->name == xprev)
+        o = lltour[x].fwd;
+    else
+        o = lltour[x].bwd;
+
+    while (!o->express && o->name != y)
+        o = o->next;
+
+    if (o->express) {
+        if (lltour[y].fwd->next->name == ynext)
+            p = lltour[y].bwd;
+        else
+            p = lltour[y].fwd;
+        while (!p->express)
+            p = p->next;
+        express_flip (o->name, p->name);
+    }
+
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd->next->name == y) {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].fwd;
+            }
+        } else {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].fwd;
+            }
+        }
+
+        if (lltour[xprev].fwd->next->name == x) {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            }
+        } else {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    } else if (x != ynext) {
+        if (lltour[xprev].fwd->express) {
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip (int ix, int iy)
+#else
+static void express_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    int side;
+    llnode *x = &(lltour[ix]);
+    llnode *y = &(lltour[iy]);
+    llnode *xprev, *ynext;
+    oneway *otemp;
+
+    if (x == y) {
+        SWAP (x->fwd, x->bwd, otemp);
+        return;
+    }
+
+    if (reversed) {
+        xprev = lltour[ix].next_express;
+        ynext = lltour[iy].prev_express;
+    } else {
+        xprev = lltour[ix].prev_express;
+        ynext = lltour[iy].next_express;
+    }
+
+    if (xprev == ynext) {
+        SWAP (xprev->fwd, xprev->bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (xprev == y) {
+        reversed ^= 1;
+        return;
+    }
+
+    if (reversed)
+        side = x->index - y->index;
+    else
+        side = y->index - x->index;
+    if (side < 0)
+        side += express_cycle_size;
+
+    if (side < express_cycle_size / 2)
+        express_flip_work (x, y);
+    else {
+        express_flip_work (ynext, xprev);
+        reversed ^= 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip_work (llnode *x, llnode *y)
+#else
+static void express_flip_work (x, y)
+llnode *x, *y;
+#endif
+{
+    llnode *xprev, *ynext;
+    llnode *n, *next;
+    oneway *otemp;
+    int id = x->index;
+
+    if (reversed) {
+        xprev = x->next_express;
+        ynext = y->prev_express;
+
+        n = y->next_express;
+        y->next_express = y->prev_express;
+        y->prev_express = n;
+        y->index = id--;
+        SWAP (y->fwd, y->bwd, otemp);
+        while (n != x) {
+            next = n->next_express;
+            n->next_express = n->prev_express;
+            n->prev_express = next;
+            n->index = id--;
+            SWAP (n->fwd, n->bwd, otemp);
+            n = next;
+        }
+        next = x->next_express;
+        x->next_express = x->prev_express;
+        x->prev_express = next;
+        x->index = id;
+        SWAP (x->fwd, x->bwd, otemp);
+
+        y->next_express = xprev;
+        x->prev_express = ynext;
+        xprev->prev_express = y;
+        ynext->next_express = x;
+    } else {
+        xprev = x->prev_express;
+        ynext = y->next_express;
+
+        n = y->prev_express;
+        y->prev_express = y->next_express;
+        y->next_express = n;
+        y->index = id++;
+        SWAP (y->fwd, y->bwd, otemp);
+        while (n != x) {
+            next = n->prev_express;
+            n->prev_express = n->next_express;
+            n->next_express = next;
+            n->index = id++;
+            SWAP (n->fwd, n->bwd, otemp);
+            n = next;
+        }
+        next = x->prev_express;
+        x->prev_express = x->next_express;
+        x->next_express = next;
+        x->index = id;
+        SWAP (x->fwd, x->bwd, otemp);
+        y->prev_express = xprev;
+        x->next_express = ynext;
+        xprev->next_express = y;
+        ynext->prev_express = x;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *px, *py, *pz;
+    int a, b, c;
+
+    if (x == z || x == y) {
+        return 1;
+    }
+
+    if (find_orientation (x))
+        px = lltour[x].bwd;
+    else
+        px = lltour[x].fwd;
+
+    while (!px->express) {
+        px = px->next;
+        if (px->name == y) {
+            return 1;
+        } else if (px->name == z) {
+            return 0;
+        }
+    }
+
+    if (z == y)
+        return 1;
+    if (find_orientation (z))
+        pz = lltour[z].fwd;
+    else
+        pz = lltour[z].bwd;
+    while (!pz->express) {
+        pz = pz->next;
+        if (pz->name == y) {
+            return 1;
+        } else if (pz->name == x) {
+            return 0;
+        } else if (px->name == pz->name) {
+            return 0;
+        }
+    }
+
+    if (find_orientation (y))
+        py = lltour[y].bwd;
+    else
+        py = lltour[y].fwd;
+    while (!py->express) {
+        py = py->next;
+        if (py->name == z) {
+            return 1;
+        } else if (py->name == x) {
+            return 0;
+        } else if (py->name == pz->name) {
+            return 1;
+        } else if (py->name == px->name) {
+            return 0;
+        }
+    }
+
+    a = lltour[px->name].index;
+    b = lltour[py->name].index;
+    c = lltour[pz->name].index;
+
+    if (reversed) {
+        if (a >= b)
+            return (b >= c || c >= a);
+        else
+            return (b >= c && c >= a);
+    } else {
+        if (a <= b)
+            return (b <= c || c <= a);
+        else
+            return (b <= c && c <= a);
+    }
+
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_llC.c b/contrib/blossom/concorde97/LINKERN/flip_llC.c
new file mode 100644
index 0000000000000000000000000000000000000000..b273ea02c032318e8f0518b17248e39a4af0762d
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_llC.c
@@ -0,0 +1,812 @@
+/***************************************************************************/
+/*                                                                         */
+/*    TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - 3-Level Linked List    */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: June 22, 1995                                                    */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version should be the best of the linked lists so far.       */
+/*   It combines the oneway approach, with three levels for an express     */
+/*   lane and a superexpress lane. Note that all superexpress nodes are    */
+/*   also express nodes.                                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 8  (flip_ll8.c):                                   */
+/*                                                                         */
+/*     1. Uses three levels, the top having n**(1/3) nodes.                */
+/*     2. The top level has explicit next and prevs, the other levels      */
+/*        consist of two "oneway" cycles.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+#define GROUP_FACTOR 5.0
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           mark;
+    char           level;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  actual_fwd_express;
+    struct oneway  actual_bwd_express;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct oneway  *fwd_express;
+    struct oneway  *bwd_express;
+    struct llnode  *next_super;
+    struct llnode  *prev_super;
+    int            index;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    express_flip (int aprev, int a, int b, int bnext),
+    super_flip (int a, int b),
+    super_flip_work (llnode *a, llnode *b);
+static int
+    express_flipper_sequence (int x, int y, int z),
+    find_orientation (int s);
+
+#else
+
+static void
+    express_flip (),
+    super_flip (),
+    super_flip_work ();
+static int
+    express_flipper_sequence (),
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static int cycle_size = 0;
+static int super_cycle_size = 0;
+static int reversed = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j, k;
+    int groupsize, supergroupsize;
+
+    cycle_size = ncount;
+    reversed = 0;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.level = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.level = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.level = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.level = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+
+    groupsize = (int) (pow ((double) ncount, 1.0 / 3.0)/ GROUP_FACTOR);
+    supergroupsize = groupsize * groupsize;
+    lltour[cyc[0]].actual_fwd.level = 1;
+    lltour[cyc[0]].actual_bwd.level = 1;
+    lltour[cyc[0]].fwd_express = &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[0]].bwd_express = &(lltour[cyc[0]].actual_bwd_express);
+    lltour[cyc[0]].actual_fwd_express.mark = 0;
+    lltour[cyc[0]].actual_bwd_express.mark = 0;
+    lltour[cyc[0]].actual_fwd_express.level = 1;
+    lltour[cyc[0]].actual_bwd_express.level = 1;
+    lltour[cyc[0]].actual_fwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_bwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_fwd_express.next =
+                          &(lltour[cyc[groupsize]].actual_fwd_express);
+    i = groupsize;
+    j = ncount - groupsize;
+    k = 1;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 1;
+        lltour[cyc[i]].actual_bwd.level = 1;
+        lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+        lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+        lltour[cyc[i]].actual_fwd_express.mark = 0;
+        lltour[cyc[i]].actual_bwd_express.mark = 0;
+        lltour[cyc[i]].actual_fwd_express.level = 1;
+        lltour[cyc[i]].actual_bwd_express.level = 1;
+        lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[i + groupsize]].actual_fwd_express);
+        lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+        i += groupsize;
+    }
+
+    lltour[cyc[i]].actual_fwd.level = 1;
+    lltour[cyc[i]].actual_bwd.level = 1;
+    lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+    lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+    lltour[cyc[i]].actual_fwd_express.mark = 0;
+    lltour[cyc[i]].actual_bwd_express.mark = 0;
+    lltour[cyc[i]].actual_fwd_express.level = 1;
+    lltour[cyc[i]].actual_bwd_express.level = 1;
+    lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+    lltour[cyc[0]].actual_bwd_express.next =
+                          &(lltour[cyc[i]].actual_bwd_express);
+
+    lltour[cyc[0]].actual_fwd.level = 2;
+    lltour[cyc[0]].actual_bwd.level = 2;
+    lltour[cyc[0]].actual_fwd_express.level = 2;
+    lltour[cyc[0]].actual_bwd_express.level = 2;
+    lltour[cyc[0]].next_super = &(lltour[cyc[supergroupsize]]);
+    lltour[cyc[0]].index = 0;
+    i = supergroupsize;
+    j = ncount - supergroupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 2;
+        lltour[cyc[i]].actual_bwd.level = 2;
+        lltour[cyc[i]].actual_fwd_express.level = 2;
+        lltour[cyc[i]].actual_bwd_express.level = 2;
+        lltour[cyc[i]].prev_super = &(lltour[cyc[i - supergroupsize]]);
+        lltour[cyc[i]].next_super = &(lltour[cyc[i + supergroupsize]]);
+        lltour[cyc[i]].index = k++;
+        i += supergroupsize;
+    }
+    lltour[cyc[i]].actual_fwd.level = 2;
+    lltour[cyc[i]].actual_bwd.level = 2;
+    lltour[cyc[i]].actual_fwd_express.level = 2;
+    lltour[cyc[i]].actual_bwd_express.level = 2;
+    lltour[cyc[i]].next_super = &(lltour[cyc[0]]);
+    lltour[cyc[i]].prev_super = &(lltour[cyc[i - supergroupsize]]);
+    lltour[cyc[0]].prev_super = &(lltour[cyc[i]]);
+    lltour[cyc[i]].index = k;
+    super_cycle_size = k + 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->level)
+        n = n->next;
+
+    if (lltour[n->name].fwd == n)
+        n = lltour[n->name].fwd_express;
+    else
+        n = lltour[n->name].bwd_express;
+
+    while (n->level != 2)
+        n = n->next;
+
+    if (reversed)
+        return (n != lltour[n->name].bwd_express);
+    else
+        return (n != lltour[n->name].fwd_express);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    start = (find_orientation (0) ? lltour[0].bwd : lltour[0].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd->next->name;
+    else
+        return lltour[x].fwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd->next->name;
+    else
+        return lltour[x].bwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *oprev, *pnext;
+
+    if (x == y)
+        return;
+
+    if (lltour[x].bwd->next->name == xprev)
+        o = lltour[x].fwd;
+    else
+        o = lltour[x].bwd;
+
+    while (!o->level && o->name != y)
+        o = o->next;
+
+    if (o->level) {
+        if (lltour[o->name].fwd == o)
+            oprev = lltour[o->name].bwd->next;
+        else
+            oprev = lltour[o->name].fwd->next;
+        while (!oprev->level)
+            oprev = oprev->next;
+        if (lltour[y].fwd->next->name == ynext)
+            p = lltour[y].bwd;
+        else
+            p = lltour[y].fwd;
+        while (!p->level)
+            p = p->next;
+        if (lltour[p->name].fwd == p)
+            pnext = lltour[p->name].bwd->next;
+        else
+            pnext = lltour[p->name].fwd->next;
+        while (!pnext->level)
+            pnext = pnext->next;
+        express_flip (oprev->name, o->name, p->name, pnext->name);
+    }
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd->next->name == y) {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].fwd;
+            }
+        } else {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].fwd;
+            }
+        }
+
+        if (lltour[xprev].fwd->next->name == x) {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            }
+        } else {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    } else if (x != ynext) {
+        oneway *otemp;
+        if (lltour[xprev].fwd->level) {
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip (int xprev, int x, int y, int ynext)
+#else
+static void express_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp;
+
+    if (x == y) {
+        SWAP (lltour[x].fwd, lltour[x].bwd, otemp);
+        return;
+    } else if (xprev == ynext) {
+        SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (lltour[x].bwd_express->next->name == xprev) {
+        o = lltour[x].fwd_express;
+    } else {
+        o = lltour[x].bwd_express;
+    }
+
+    while (o->level != 2 && o->name != y)
+        o = o->next;
+
+    if (o->level == 2) {
+        if (lltour[y].fwd_express->next->name == ynext)
+            p = lltour[y].bwd_express;
+        else
+            p = lltour[y].fwd_express;
+        while (p->level != 2)
+            p = p->next;
+        super_flip (o->name, p->name);
+    }
+
+
+    if (x != ynext) {
+        if (lltour[ynext].fwd_express->next->name == y) {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].fwd_express;
+            }
+        } else {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].fwd_express;
+            }
+        }
+
+        if (lltour[xprev].fwd_express->next->name == x) {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].fwd_express;
+            }
+        } else {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].fwd_express;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void super_flip (int ix, int iy)
+#else
+static void super_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    int side;
+    llnode *x = &(lltour[ix]);
+    llnode *y = &(lltour[iy]);
+    llnode *xprev, *ynext;
+    oneway *otemp;
+
+    if (x == y) {
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+        return;
+    }
+
+    if (reversed) {
+        xprev = x->next_super;
+        ynext = y->prev_super;
+    } else {
+        xprev = x->prev_super;
+        ynext = y->next_super;
+    }
+
+    if (xprev == ynext) {
+        SWAP (xprev->fwd_express, xprev->bwd_express, otemp);
+        SWAP (xprev->fwd, xprev->bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (xprev == y) {
+        reversed ^= 1;
+        return;
+    }
+
+    if (reversed)
+        side = x->index - y->index;
+    else
+        side = y->index - x->index;
+    if (side < 0)
+        side += super_cycle_size;
+
+    if (side < super_cycle_size / 2)
+        super_flip_work (x, y);
+    else {
+        super_flip_work (ynext, xprev);
+        reversed ^= 1;
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void super_flip_work (llnode *x, llnode *y)
+#else
+static void super_flip_work (x, y)
+llnode *x, *y;
+#endif
+{
+    llnode *xprev, *ynext;
+    llnode *n, *next;
+    oneway *otemp;
+    int id = x->index;
+
+
+    if (reversed) {
+        xprev = x->next_super;
+        ynext = y->prev_super;
+
+        n = y->next_super;
+        y->next_super = y->prev_super;
+        y->prev_super = n;
+        y->index = id--;
+        SWAP (y->fwd_express, y->bwd_express, otemp);
+        SWAP (y->fwd, y->bwd, otemp);
+        while (n != x) {
+            next = n->next_super;
+            n->next_super = n->prev_super;
+            n->prev_super = next;
+            n->index = id--;
+            SWAP (n->fwd_express, n->bwd_express, otemp);
+            SWAP (n->fwd, n->bwd, otemp);
+            n = next;
+        }
+        next = x->next_super;
+        x->next_super = x->prev_super;
+        x->prev_super = next;
+        x->index = id;
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+
+        if (xprev != y) {
+            y->next_super = xprev;
+            x->prev_super = ynext;
+            xprev->prev_super = y;
+            ynext->next_super = x;
+        }
+    } else {
+        xprev = x->prev_super;
+        ynext = y->next_super;
+
+        n = y->prev_super;
+        y->prev_super = y->next_super;
+        y->next_super = n;
+        y->index = id++;
+        SWAP (y->fwd_express, y->bwd_express, otemp);
+        SWAP (y->fwd, y->bwd, otemp);
+        while (n != x) {
+            next = n->prev_super;
+            n->prev_super = n->next_super;
+            n->next_super = next;
+            n->index = id++;
+            SWAP (n->fwd_express, n->bwd_express, otemp);
+            SWAP (n->fwd, n->bwd, otemp);
+            n = next;
+        }
+        next = x->prev_super;
+        x->prev_super = x->next_super;
+        x->next_super = next;
+        x->index = id;
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+
+        if (xprev != y) {
+            y->prev_super = xprev;
+            x->next_super = ynext;
+            xprev->next_super = y;
+            ynext->prev_super = x;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *px, *py, *pz;
+
+    if (x == z || x == y)
+        return 1;
+    if (find_orientation (x))
+        px = lltour[x].bwd;
+    else
+        px = lltour[x].fwd;
+    while (!px->level) {
+        px = px->next;
+        if (px->name == y)
+            return 1;
+        else if (px->name == z)
+            return 0;
+    }
+
+    if (z == y)
+        return 1;
+    if (find_orientation (z))
+        pz = lltour[z].fwd;
+    else
+        pz = lltour[z].bwd;
+    while (!pz->level) {
+        pz = pz->next;
+        if (pz->name == y) {
+            return 1;
+        } else if (pz->name == x) {
+            return 0;
+        } else if (px->name == pz->name) {
+            return 0;
+        }
+    }
+
+    if (find_orientation (y))
+        py = lltour[y].bwd;
+    else
+        py = lltour[y].fwd;
+    while (!py->level) {
+        py = py->next;
+        if (py->name == z) {
+            return 1;
+        } else if (py->name == x) {
+            return 0;
+        } else if (py->name == pz->name) {
+            return 1;
+        } else if (py->name == px->name) {
+            return 0;
+        }
+    }
+    return express_flipper_sequence (px->name, py->name, pz->name);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int express_flipper_sequence (int x, int y, int z)
+#else
+static int express_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *px, *py, *pz;
+    int a, b, c;
+
+    if (x == z || x == y) {
+        return 1;
+    }
+
+    if (find_orientation (x))
+        px = lltour[x].bwd_express;
+    else
+        px = lltour[x].fwd_express;
+
+    while (px->level != 2) {
+        px = px->next;
+        if (px->name == y) {
+            return 1;
+        } else if (px->name == z) {
+            return 0;
+        }
+    }
+
+    if (z == y)
+        return 1;
+    if (find_orientation (z))
+        pz = lltour[z].fwd_express;
+    else
+        pz = lltour[z].bwd_express;
+    while (pz->level != 2) {
+        pz = pz->next;
+        if (pz->name == y) {
+            return 1;
+        } else if (pz->name == x) {
+            return 0;
+        } else if (px->name == pz->name) {
+            return 0;
+        }
+    }
+
+    if (find_orientation (y))
+        py = lltour[y].bwd_express;
+    else
+        py = lltour[y].fwd_express;
+    while (py->level != 2) {
+        py = py->next;
+        if (py->name == z) {
+            return 1;
+        } else if (py->name == x) {
+            return 0;
+        } else if (py->name == pz->name) {
+            return 1;
+        } else if (py->name == px->name) {
+            return 0;
+        }
+    }
+
+    a = lltour[px->name].index;
+    b = lltour[py->name].index;
+    c = lltour[pz->name].index;
+
+    if (reversed) {
+        if (a >= b)
+            return (b >= c || c >= a);
+        else
+            return (b >= c && c >= a);
+    } else {
+        if (a <= b)
+            return (b <= c || c <= a);
+        else
+            return (b <= c && c <= a);
+    }
+
+
+/*
+    oneway *next, *prev;
+
+    lltour[y].fwd_express->mark = 1;
+    lltour[y].bwd_express->mark = 1;
+    lltour[z].fwd_express->mark = 1;
+    lltour[z].bwd_express->mark = 1;
+
+    if (find_orientation (x)) {
+        next = lltour[x].bwd_express;
+        prev = lltour[x].fwd_express;
+    } else {
+        next = lltour[x].fwd_express;
+        prev = lltour[x].bwd_express;
+    }
+
+    while (!next->mark && !prev->mark) {
+        next = next->next;
+        prev = prev->next;
+    }
+
+    if (next->mark) {
+        lltour[y].fwd_express->mark = 0;
+        lltour[y].bwd_express->mark = 0;
+        lltour[z].fwd_express->mark = 0;
+        lltour[z].bwd_express->mark = 0;
+        return (next->name == y);
+    } else {
+        lltour[y].fwd_express->mark = 0;
+        lltour[y].bwd_express->mark = 0;
+        lltour[z].fwd_express->mark = 0;
+        lltour[z].bwd_express->mark = 0;
+        return (prev->name == z);
+    }
+*/
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_llD.c b/contrib/blossom/concorde97/LINKERN/flip_llD.c
new file mode 100644
index 0000000000000000000000000000000000000000..40bd709b8bef5082e3d2d2e5ee2adeafdab8e076
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_llD.c
@@ -0,0 +1,1017 @@
+/***************************************************************************/
+/*                                                                         */
+/*    TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - 4-Level Linked List    */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: June 22, 1995                                                    */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version should be the best of the linked lists so far.       */
+/*   It combines the oneway approach, with four levels for an express      */
+/*   lane and a superexpress lane and an autobahn. Note that all           */
+/*   superexpress nodes are also express nodes, and all autobahn nodes     */
+/*   are also superexpress nodes.                                          */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER D  (flip_llD.c):                                   */
+/*                                                                         */
+/*     1. Uses four levels, the top having n**(1/4) nodes.                 */
+/*     2. The top level has explicit next and prevs, the other levels      */
+/*        consist of two "oneway" cycles.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+#define GROUP_FACTOR 3.0
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           mark;
+    char           level;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  actual_fwd_express;
+    struct oneway  actual_bwd_express;
+    struct oneway  actual_fwd_super;
+    struct oneway  actual_bwd_super;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct oneway  *fwd_express;
+    struct oneway  *bwd_express;
+    struct oneway  *fwd_super;
+    struct oneway  *bwd_super;
+    struct llnode  *next_auto;
+    struct llnode  *prev_auto;
+    int            index;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    express_flip (int aprev, int a, int b, int bnext),
+    super_flip (int aprev, int a, int b, int bnext),
+    auto_flip (int a, int b),
+    auto_flip_work (llnode *a, llnode *b);
+static int
+    express_flipper_sequence (int x, int y, int z),
+    super_flipper_sequence (int x, int y, int z),
+    find_orientation (int s);
+
+#else
+
+static void
+    express_flip (),
+    super_flip (),
+    auto_flip (),
+    auto_flip_work ();
+static int
+    express_flipper_sequence (),
+    super_flipper_sequence (),
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static int cycle_size = 0;
+static int auto_cycle_size = 0;
+static int reversed = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j, k;
+    int groupsize, supergroupsize, autogroupsize;
+
+    cycle_size = ncount;
+    reversed = 0;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.level = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.level = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.level = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.level = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+
+    groupsize = (int) (pow ((double) ncount, 1.0 / 4.0)/ GROUP_FACTOR);
+    supergroupsize = groupsize * groupsize;
+    autogroupsize = supergroupsize * groupsize;
+
+
+    lltour[cyc[0]].actual_fwd.level = 1;
+    lltour[cyc[0]].actual_bwd.level = 1;
+    lltour[cyc[0]].fwd_express = &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[0]].bwd_express = &(lltour[cyc[0]].actual_bwd_express);
+    lltour[cyc[0]].actual_fwd_express.mark = 0;
+    lltour[cyc[0]].actual_bwd_express.mark = 0;
+    lltour[cyc[0]].actual_fwd_express.level = 1;
+    lltour[cyc[0]].actual_bwd_express.level = 1;
+    lltour[cyc[0]].actual_fwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_bwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_fwd_express.next =
+                          &(lltour[cyc[groupsize]].actual_fwd_express);
+    i = groupsize;
+    j = ncount - groupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 1;
+        lltour[cyc[i]].actual_bwd.level = 1;
+        lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+        lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+        lltour[cyc[i]].actual_fwd_express.mark = 0;
+        lltour[cyc[i]].actual_bwd_express.mark = 0;
+        lltour[cyc[i]].actual_fwd_express.level = 1;
+        lltour[cyc[i]].actual_bwd_express.level = 1;
+        lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[i + groupsize]].actual_fwd_express);
+        lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+        i += groupsize;
+    }
+    lltour[cyc[i]].actual_fwd.level = 1;
+    lltour[cyc[i]].actual_bwd.level = 1;
+    lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+    lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+    lltour[cyc[i]].actual_fwd_express.mark = 0;
+    lltour[cyc[i]].actual_bwd_express.mark = 0;
+    lltour[cyc[i]].actual_fwd_express.level = 1;
+    lltour[cyc[i]].actual_bwd_express.level = 1;
+    lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+    lltour[cyc[0]].actual_bwd_express.next =
+                          &(lltour[cyc[i]].actual_bwd_express);
+
+
+
+    lltour[cyc[0]].actual_fwd.level = 2;
+    lltour[cyc[0]].actual_bwd.level = 2;
+    lltour[cyc[0]].actual_fwd_express.level = 2;
+    lltour[cyc[0]].actual_bwd_express.level = 2;
+    lltour[cyc[0]].fwd_super = &(lltour[cyc[0]].actual_fwd_super);
+    lltour[cyc[0]].bwd_super = &(lltour[cyc[0]].actual_bwd_super);
+    lltour[cyc[0]].actual_fwd_super.level = 2;
+    lltour[cyc[0]].actual_bwd_super.level = 2;
+    lltour[cyc[0]].actual_fwd_super.mark = 0;
+    lltour[cyc[0]].actual_bwd_super.mark = 0;
+    lltour[cyc[0]].actual_fwd_super.name = cyc[0];
+    lltour[cyc[0]].actual_bwd_super.name = cyc[0];
+    lltour[cyc[0]].actual_fwd_super.next =
+                    &(lltour[cyc[supergroupsize]].actual_fwd_super);
+    i = supergroupsize;
+    j = ncount - supergroupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 2;
+        lltour[cyc[i]].actual_bwd.level = 2;
+        lltour[cyc[i]].actual_fwd_express.level = 2;
+        lltour[cyc[i]].actual_bwd_express.level = 2;
+        lltour[cyc[i]].fwd_super = &(lltour[cyc[i]].actual_fwd_super);
+        lltour[cyc[i]].bwd_super = &(lltour[cyc[i]].actual_bwd_super);
+        lltour[cyc[i]].actual_fwd_super.level = 2;
+        lltour[cyc[i]].actual_bwd_super.level = 2;
+        lltour[cyc[i]].actual_fwd_super.mark = 0;
+        lltour[cyc[i]].actual_bwd_super.mark = 0;
+        lltour[cyc[i]].actual_fwd_super.name = cyc[i];
+        lltour[cyc[i]].actual_bwd_super.name = cyc[i];
+        lltour[cyc[i]].actual_fwd_super.next =
+                    &(lltour[cyc[i + supergroupsize]].actual_fwd_super);
+        lltour[cyc[i]].actual_bwd_super.next =
+                    &(lltour[cyc[i - supergroupsize]].actual_bwd_super);
+        i += supergroupsize;
+    }
+    lltour[cyc[i]].actual_fwd.level = 2;
+    lltour[cyc[i]].actual_bwd.level = 2;
+    lltour[cyc[i]].actual_fwd_express.level = 2;
+    lltour[cyc[i]].actual_bwd_express.level = 2;
+    lltour[cyc[i]].fwd_super = &(lltour[cyc[i]].actual_fwd_super);
+    lltour[cyc[i]].bwd_super = &(lltour[cyc[i]].actual_bwd_super);
+    lltour[cyc[i]].actual_fwd_super.level = 2;
+    lltour[cyc[i]].actual_bwd_super.level = 2;
+    lltour[cyc[i]].actual_fwd_super.mark = 0;
+    lltour[cyc[i]].actual_bwd_super.mark = 0;
+    lltour[cyc[i]].actual_fwd_super.name = cyc[i];
+    lltour[cyc[i]].actual_bwd_super.name = cyc[i];
+    lltour[cyc[i]].actual_fwd_super.next =
+                    &(lltour[cyc[0]].actual_fwd_super);
+    lltour[cyc[i]].actual_bwd_super.next =
+                    &(lltour[cyc[i - supergroupsize]].actual_bwd_super);
+    lltour[cyc[0]].actual_bwd_super.next =
+                          &(lltour[cyc[i]].actual_bwd_super);
+
+
+    lltour[cyc[0]].actual_fwd.level = 3;
+    lltour[cyc[0]].actual_bwd.level = 3;
+    lltour[cyc[0]].actual_fwd_express.level = 3;
+    lltour[cyc[0]].actual_bwd_express.level = 3;
+    lltour[cyc[0]].actual_fwd_super.level = 3;
+    lltour[cyc[0]].actual_bwd_super.level = 3;
+    lltour[cyc[0]].next_auto = &(lltour[cyc[autogroupsize]]);
+    lltour[cyc[0]].index = 0;
+    i = autogroupsize;
+    j = ncount - autogroupsize;
+    k = 1;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 3;
+        lltour[cyc[i]].actual_bwd.level = 3;
+        lltour[cyc[i]].actual_fwd_express.level = 3;
+        lltour[cyc[i]].actual_bwd_express.level = 3;
+        lltour[cyc[i]].actual_fwd_super.level = 3;
+        lltour[cyc[i]].actual_bwd_super.level = 3;
+        lltour[cyc[i]].prev_auto = &(lltour[cyc[i - autogroupsize]]);
+        lltour[cyc[i]].next_auto = &(lltour[cyc[i + autogroupsize]]);
+        lltour[cyc[i]].index = k++;
+        i += autogroupsize;
+    }
+    lltour[cyc[i]].actual_fwd.level = 2;
+    lltour[cyc[i]].actual_bwd.level = 2;
+    lltour[cyc[i]].actual_fwd_express.level = 2;
+    lltour[cyc[i]].actual_bwd_express.level = 2;
+    lltour[cyc[i]].actual_fwd_super.level = 2;
+    lltour[cyc[i]].actual_bwd_super.level = 2;
+    lltour[cyc[i]].next_auto = &(lltour[cyc[0]]);
+    lltour[cyc[i]].prev_auto = &(lltour[cyc[i - autogroupsize]]);
+    lltour[cyc[0]].prev_auto = &(lltour[cyc[i]]);
+    lltour[cyc[i]].index = k;
+    auto_cycle_size = k + 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->level)
+        n = n->next;
+
+    if (lltour[n->name].fwd == n)
+        n = lltour[n->name].fwd_express;
+    else
+        n = lltour[n->name].bwd_express;
+
+    while (n->level < 2)
+        n = n->next;
+
+    if (lltour[n->name].fwd_express == n)
+        n = lltour[n->name].fwd_super;
+    else
+        n = lltour[n->name].bwd_super;
+
+    while (n->level < 3)
+        n = n->next;
+
+    if (reversed)
+        return (n != lltour[n->name].bwd_super);
+    else
+        return (n != lltour[n->name].fwd_super);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    oneway *start, *n;
+    int k = 0;
+
+    start = (find_orientation (0) ? lltour[0].bwd : lltour[0].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].bwd->next->name;
+    else
+        return lltour[x].fwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    if (find_orientation (x))
+        return lltour[x].fwd->next->name;
+    else
+        return lltour[x].bwd->next->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *oprev, *pnext;
+
+    if (x == y)
+        return;
+
+    if (lltour[x].bwd->next->name == xprev)
+        o = lltour[x].fwd;
+    else
+        o = lltour[x].bwd;
+
+    while (!o->level && o->name != y)
+        o = o->next;
+
+    if (o->level) {
+        if (lltour[o->name].fwd == o)
+            oprev = lltour[o->name].bwd->next;
+        else
+            oprev = lltour[o->name].fwd->next;
+        while (!oprev->level)
+            oprev = oprev->next;
+        if (lltour[y].fwd->next->name == ynext)
+            p = lltour[y].bwd;
+        else
+            p = lltour[y].fwd;
+        while (!p->level)
+            p = p->next;
+        if (lltour[p->name].fwd == p)
+            pnext = lltour[p->name].bwd->next;
+        else
+            pnext = lltour[p->name].fwd->next;
+        while (!pnext->level)
+            pnext = pnext->next;
+        express_flip (oprev->name, o->name, p->name, pnext->name);
+    }
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd->next->name == y) {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].fwd;
+            }
+        } else {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].fwd;
+            }
+        }
+
+        if (lltour[xprev].fwd->next->name == x) {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            }
+        } else {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    } else if (x != ynext) {
+        oneway *otemp;
+        if (lltour[xprev].fwd->level) {
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip (int xprev, int x, int y, int ynext)
+#else
+static void express_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp, *oprev, *pnext;
+
+    if (x == y) {
+        SWAP (lltour[x].fwd, lltour[x].bwd, otemp);
+        return;
+    } else if (xprev == ynext) {
+        SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (lltour[x].bwd_express->next->name == xprev) {
+        o = lltour[x].fwd_express;
+    } else {
+        o = lltour[x].bwd_express;
+    }
+
+    while (o->level < 2 && o->name != y)
+        o = o->next;
+
+    if (o->level >= 2) {
+        if (lltour[o->name].fwd_express == o)
+            oprev = lltour[o->name].bwd_express->next;
+        else
+            oprev = lltour[o->name].fwd_express->next;
+        while (oprev->level < 2)
+            oprev = oprev->next;
+        if (lltour[y].fwd_express->next->name == ynext)
+            p = lltour[y].bwd_express;
+        else
+            p = lltour[y].fwd_express;
+        while (p->level < 2)
+            p = p->next;
+        if (lltour[p->name].fwd_express == p)
+            pnext = lltour[p->name].bwd_express->next;
+        else
+            pnext = lltour[p->name].fwd_express->next;
+        while (pnext->level < 2)
+            pnext = pnext->next;
+        super_flip (oprev->name, o->name, p->name, pnext->name);
+    }
+
+    if (x != ynext) {
+        if (lltour[ynext].fwd_express->next->name == y) {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].fwd_express;
+            }
+        } else {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].fwd_express;
+            }
+        }
+
+        if (lltour[xprev].fwd_express->next->name == x) {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].fwd_express;
+            }
+        } else {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].fwd_express;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void super_flip (int xprev, int x, int y, int ynext)
+#else
+static void super_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp;
+
+    if (x == y) {
+        SWAP (lltour[x].fwd_express, lltour[x].bwd_express, otemp);
+        SWAP (lltour[x].fwd, lltour[x].bwd, otemp);
+        return;
+    } else if (xprev == ynext) {
+        SWAP (lltour[xprev].fwd_express, lltour[xprev].bwd_express, otemp);
+        SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (lltour[x].bwd_super->next->name == xprev) {
+        o = lltour[x].fwd_super;
+    } else {
+        o = lltour[x].bwd_super;
+    }
+
+    while (o->level < 3 && o->name != y)
+        o = o->next;
+
+    if (o->level >= 3) {
+        if (lltour[y].fwd_super->next->name == ynext)
+            p = lltour[y].bwd_super;
+        else
+            p = lltour[y].fwd_super;
+        while (p->level < 3)
+            p = p->next;
+        auto_flip (o->name, p->name);
+    }
+
+    if (x != ynext) {
+        if (lltour[ynext].fwd_super->next->name == y) {
+            if (lltour[x].fwd_super->next->name == xprev) {
+                lltour[x].fwd_super->next = lltour[ynext].bwd_super;
+                lltour[ynext].fwd_super->next = lltour[x].bwd_super;
+            } else {
+                lltour[x].bwd_super->next = lltour[ynext].bwd_super;
+                lltour[ynext].fwd_super->next = lltour[x].fwd_super;
+            }
+        } else {
+            if (lltour[x].fwd_super->next->name == xprev) {
+                lltour[x].fwd_super->next = lltour[ynext].fwd_super;
+                lltour[ynext].bwd_super->next = lltour[x].bwd_super;
+            } else {
+                lltour[x].bwd_super->next = lltour[ynext].fwd_super;
+                lltour[ynext].bwd_super->next = lltour[x].fwd_super;
+            }
+        }
+
+        if (lltour[xprev].fwd_super->next->name == x) {
+            if (lltour[y].fwd_super->next->name == ynext) {
+                lltour[y].fwd_super->next = lltour[xprev].bwd_super;
+                lltour[xprev].fwd_super->next = lltour[y].bwd_super;
+            } else {
+                lltour[y].bwd_super->next = lltour[xprev].bwd_super;
+                lltour[xprev].fwd_super->next = lltour[y].fwd_super;
+            }
+        } else {
+            if (lltour[y].fwd_super->next->name == ynext) {
+                lltour[y].fwd_super->next = lltour[xprev].fwd_super;
+                lltour[xprev].bwd_super->next = lltour[y].bwd_super;
+            } else {
+                lltour[y].bwd_super->next = lltour[xprev].fwd_super;
+                lltour[xprev].bwd_super->next = lltour[y].fwd_super;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void auto_flip (int ix, int iy)
+#else
+static void auto_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    int side;
+    llnode *x = &(lltour[ix]);
+    llnode *y = &(lltour[iy]);
+    llnode *xprev, *ynext;
+    oneway *otemp;
+
+    if (x == y) {
+        SWAP (x->fwd_super, x->bwd_super, otemp);
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+        return;
+    }
+
+    if (reversed) {
+        xprev = x->next_auto;
+        ynext = y->prev_auto;
+    } else {
+        xprev = x->prev_auto;
+        ynext = y->next_auto;
+    }
+
+    if (xprev == ynext) {
+        SWAP (xprev->fwd_super, xprev->bwd_super, otemp);
+        SWAP (xprev->fwd_express, xprev->bwd_express, otemp);
+        SWAP (xprev->fwd, xprev->bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (xprev == y) {
+        reversed ^= 1;
+        return;
+    }
+
+    if (reversed)
+        side = x->index - y->index;
+    else
+        side = y->index - x->index;
+    if (side < 0)
+        side += auto_cycle_size;
+
+    if (side < auto_cycle_size / 2)
+        auto_flip_work (x, y);
+    else {
+        auto_flip_work (ynext, xprev);
+        reversed ^= 1;
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void auto_flip_work (llnode *x, llnode *y)
+#else
+static void auto_flip_work (x, y)
+llnode *x, *y;
+#endif
+{
+    llnode *xprev, *ynext;
+    llnode *n, *next;
+    oneway *otemp;
+    int id = x->index;
+
+    if (reversed) {
+        xprev = x->next_auto;
+        ynext = y->prev_auto;
+
+        n = y->next_auto;
+        y->next_auto = y->prev_auto;
+        y->prev_auto = n;
+        y->index = id--;
+        SWAP (y->fwd_super, y->bwd_super, otemp);
+        SWAP (y->fwd_express, y->bwd_express, otemp);
+        SWAP (y->fwd, y->bwd, otemp);
+        while (n != x) {
+            next = n->next_auto;
+            n->next_auto = n->prev_auto;
+            n->prev_auto = next;
+            n->index = id--;
+            SWAP (n->fwd_super, n->bwd_super, otemp);
+            SWAP (n->fwd_express, n->bwd_express, otemp);
+            SWAP (n->fwd, n->bwd, otemp);
+            n = next;
+        }
+        next = x->next_auto;
+        x->next_auto = x->prev_auto;
+        x->prev_auto = next;
+        x->index = id;
+        SWAP (x->fwd_super, x->bwd_super, otemp);
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+
+        if (xprev != y) {
+            y->next_auto = xprev;
+            x->prev_auto = ynext;
+            xprev->prev_auto = y;
+            ynext->next_auto = x;
+        }
+    } else {
+        xprev = x->prev_auto;
+        ynext = y->next_auto;
+
+        n = y->prev_auto;
+        y->prev_auto = y->next_auto;
+        y->next_auto = n;
+        y->index = id++;
+        SWAP (y->fwd_super, y->bwd_super, otemp);
+        SWAP (y->fwd_express, y->bwd_express, otemp);
+        SWAP (y->fwd, y->bwd, otemp);
+        while (n != x) {
+            next = n->prev_auto;
+            n->prev_auto = n->next_auto;
+            n->next_auto = next;
+            n->index = id++;
+            SWAP (n->fwd_super, n->bwd_super, otemp);
+            SWAP (n->fwd_express, n->bwd_express, otemp);
+            SWAP (n->fwd, n->bwd, otemp);
+            n = next;
+        }
+        next = x->prev_auto;
+        x->prev_auto = x->next_auto;
+        x->next_auto = next;
+        x->index = id;
+        SWAP (x->fwd_super, x->bwd_super, otemp);
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+
+        if (xprev != y) {
+            y->prev_auto = xprev;
+            x->next_auto = ynext;
+            xprev->next_auto = y;
+            ynext->prev_auto = x;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *px, *py, *pz;
+
+    if (x == z || x == y)
+        return 1;
+    if (find_orientation (x))
+        px = lltour[x].bwd;
+    else
+        px = lltour[x].fwd;
+    while (!px->level) {
+        px = px->next;
+        if (px->name == y)
+            return 1;
+        else if (px->name == z)
+            return 0;
+    }
+
+    if (z == y)
+        return 1;
+    if (find_orientation (z))
+        pz = lltour[z].fwd;
+    else
+        pz = lltour[z].bwd;
+    while (!pz->level) {
+        pz = pz->next;
+        if (pz->name == y) {
+            return 1;
+        } else if (pz->name == x) {
+            return 0;
+        } else if (px->name == pz->name) {
+            return 0;
+        }
+    }
+
+    if (find_orientation (y))
+        py = lltour[y].bwd;
+    else
+        py = lltour[y].fwd;
+    while (!py->level) {
+        py = py->next;
+        if (py->name == z) {
+            return 1;
+        } else if (py->name == x) {
+            return 0;
+        } else if (py->name == pz->name) {
+            return 1;
+        } else if (py->name == px->name) {
+            return 0;
+        }
+    }
+    return express_flipper_sequence (px->name, py->name, pz->name);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int express_flipper_sequence (int x, int y, int z)
+#else
+static int express_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *px, *py, *pz;
+
+    if (x == z || x == y) {
+        return 1;
+    }
+
+    if (find_orientation (x))
+        px = lltour[x].bwd_express;
+    else
+        px = lltour[x].fwd_express;
+
+    while (px->level < 2) {
+        px = px->next;
+        if (px->name == y) {
+            return 1;
+        } else if (px->name == z) {
+            return 0;
+        }
+    }
+
+    if (z == y)
+        return 1;
+    if (find_orientation (z))
+        pz = lltour[z].fwd_express;
+    else
+        pz = lltour[z].bwd_express;
+    while (pz->level < 2) {
+        pz = pz->next;
+        if (pz->name == y) {
+            return 1;
+        } else if (pz->name == x) {
+            return 0;
+        } else if (px->name == pz->name) {
+            return 0;
+        }
+    }
+
+    if (find_orientation (y))
+        py = lltour[y].bwd_express;
+    else
+        py = lltour[y].fwd_express;
+    while (py->level < 2) {
+        py = py->next;
+        if (py->name == z) {
+            return 1;
+        } else if (py->name == x) {
+            return 0;
+        } else if (py->name == pz->name) {
+            return 1;
+        } else if (py->name == px->name) {
+            return 0;
+        }
+    }
+
+    return super_flipper_sequence (px->name, py->name, pz->name);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int super_flipper_sequence (int x, int y, int z)
+#else
+static int super_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *px, *py, *pz;
+    int a, b, c;
+
+    if (x == z || x == y) {
+        return 1;
+    }
+
+    if (find_orientation (x))
+        px = lltour[x].bwd_super;
+    else
+        px = lltour[x].fwd_super;
+
+    while (px->level < 3) {
+        px = px->next;
+        if (px->name == y) {
+            return 1;
+        } else if (px->name == z) {
+            return 0;
+        }
+    }
+
+    if (z == y)
+        return 1;
+    if (find_orientation (z))
+        pz = lltour[z].fwd_super;
+    else
+        pz = lltour[z].bwd_super;
+    while (pz->level < 3) {
+        pz = pz->next;
+        if (pz->name == y) {
+            return 1;
+        } else if (pz->name == x) {
+            return 0;
+        } else if (px->name == pz->name) {
+            return 0;
+        }
+    }
+
+    if (find_orientation (y))
+        py = lltour[y].bwd_super;
+    else
+        py = lltour[y].fwd_super;
+    while (py->level < 3) {
+        py = py->next;
+        if (py->name == z) {
+            return 1;
+        } else if (py->name == x) {
+            return 0;
+        } else if (py->name == pz->name) {
+            return 1;
+        } else if (py->name == px->name) {
+            return 0;
+        }
+    }
+
+    a = lltour[px->name].index;
+    b = lltour[py->name].index;
+    c = lltour[pz->name].index;
+
+    if (reversed) {
+        if (a >= b)
+            return (b >= c || c >= a);
+        else
+            return (b >= c && c >= a);
+    } else {
+        if (a <= b)
+            return (b <= c || c <= a);
+        else
+            return (b <= c && c <= a);
+    }
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_sg1.c b/contrib/blossom/concorde97/LINKERN/flip_sg1.c
new file mode 100644
index 0000000000000000000000000000000000000000..40bf9802b5dcb7f5ce5e946a8e796789744ebe0e
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_sg1.c
@@ -0,0 +1,896 @@
+/***************************************************************************/
+/*                                                                         */
+/*     TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Segments with UNDO    */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: April 24, 1995 (but mainly from March, 1990)                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_reset_temp (int ncount)                         */
+/*     reinitializes the cycle to the current cycle - use this to keep the */
+/*     number of segments small.                                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int x, int y)                            */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version is closest to our orignal segment code. It undos the */
+/* flips that do not lead to an improvement.                               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define USE_TIMESTAMP */
+
+/***************************************************************************/
+/*                                                                         */
+/* SEGMENT FLIPPER (flipper1):                                             */
+/*                                                                         */
+/*     1. flipper_cycle and flipper_cycle_inverse return the current       */
+/*        number of segments.                                              */
+/*                                                                         */
+/*     2. The cycle should be renumbered, freed, and initialized now and   */
+/*        and again to reduce the number of segments.                      */
+/*                                                                         */
+/*     3. This is the first pass - uses a straight cycle of segments, and  */
+/*        a tree to find segment. No balance condition is maintained for   */
+/*        the tree.                                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+typedef struct flipper1 {
+    struct {
+        struct flipper1 *parent;
+        struct flipper1 *lower;
+        struct flipper1 *higher;
+    } locate;
+    struct {
+        struct flipper1 *left;
+        struct flipper1 *right;
+    } order;
+    int low;
+    int high;
+    int reverse;
+    struct flipper1 *next;
+} flipper1;
+
+#ifdef  USE_TIMESTAMP
+typedef struct cacheobj {
+    struct flipper1 *segment;
+    int              stamp;
+} cacheobj;
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    flipper1_tree_delete (flipper1 *),
+    flipper1_merge (flipper1 *),
+    flipper1_checkmerge (flipper1 *),
+    flipper1free (flipper1 *p),
+    flipper1_tree_free (flipper1 *, flipper1 *);
+
+static flipper1
+   *flipper1_locate (int x),
+   *flipper1_split (flipper1 *, int);
+
+#else
+
+static void
+    flipper1_tree_delete (),
+    flipper1_merge (),
+    flipper1_checkmerge (),
+    flipper1free (),
+    flipper1_tree_free ();
+
+static flipper1
+   *flipper1_locate (),
+   *flipper1_split ();
+
+#endif
+
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+
+#define LOCATE_CHILD(p, c) (*((p) ? ((p)->locate.lower == (c) ?              \
+                              &(p)->locate.lower : &(p)->locate.higher) :    \
+                              &locate_root))
+
+#define PARENT_HOOKUP(q, p, c) (((q)->locate.parent = (p)),                  \
+                                (LOCATE_CHILD((p),(c)) = (q)))
+
+#define HIGHER_HOOKUP(p, c) (((p)->locate.higher = (c)),                     \
+                       ((c) ? (c)->locate.parent = (p) : (flipper1 *) NULL))
+
+#define LOWER_HOOKUP(p, c)  (((p)->locate.lower = (c)),                      \
+                       ((c) ? (c)->locate.parent = (p) : (flipper1 *) NULL))
+
+static flipper1 *locate_root = (flipper1 *) NULL;
+static flipper1 *order_root = (flipper1 *) NULL;
+#ifdef USE_TIMESTAMP
+static cacheobj *locate_cache = (cacheobj *) NULL;
+static int       locate_cache_magic = 0;
+#else
+static flipper1 **locate_cache = (flipper1 **) NULL;
+#endif
+
+static int *flip1_cyc = (int *) NULL;
+static int *flip1_inv = (int *) NULL;
+static int segment_count = 1;
+
+/*
+static int seghit = 0;
+static int segtotal = 0;
+*/
+
+CC_PTR_ALLOC_ROUTINE (flipper1, flipper1alloc, flipper1chunklist,
+                  flipper1freelist)
+CC_PTR_FREE_WORLD_ROUTINE( flipper1, flipper1free_world, flipper1chunklist,
+                  flipper1freelist)
+CC_PTR_LEAKS_ROUTINE (flipper1, flipper1_check_leaks, flipper1chunklist,
+                  flipper1freelist, reverse, int)
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1free (flipper1 *p)
+#else
+static void flipper1free (p)
+flipper1 *p;
+#endif
+{
+    p->next = flipper1freelist;
+    flipper1freelist = p;
+    p->low = p->high = -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_tree_free (flipper1 *p, flipper1 *bigp)
+#else
+static void flipper1_tree_free (p, bigp)
+flipper1 *p, *bigp;
+#endif
+{
+    if (p) {
+        flipper1_tree_free (p->locate.lower, bigp);
+        flipper1_tree_free (p->locate.higher, bigp);
+        if (p != bigp)
+           flipper1free (p);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset_temp (int ncount)
+#else
+int CClinkern_flipper_reset_temp (ncount)
+int ncount;
+#endif
+{
+    int i, n, *cyc = (int *) NULL;
+    int nseg = 0, big = 0, bigreverse = 0;
+    flipper1 *p, *bigp = (flipper1 *) NULL;
+
+    p = order_root;
+    do {
+        if (p->high - p->low > big) {
+            big = p->high - p->low;
+            bigp = p;
+        }
+        nseg++;
+        p = p->order.right;
+    } while (p != order_root);
+
+    if (nseg == 1)
+        return 0;
+
+    cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!cyc) {
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+        return 1;
+    }
+    if (bigp->reverse) {
+        bigreverse = 1;
+        p = bigp->order.left;
+        n = bigp->high + 1;
+        do {
+            if (!p->reverse) {
+                for (i = p->high; i >= p->low; i--) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            } else {
+                for (i = p->low; i <= p->high; i++) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            }
+            p = p->order.left;
+        } while (p != bigp);
+    } else {
+        bigreverse = 0;
+        p = bigp->order.right;
+        n = bigp->high + 1;
+        do {
+            if (p->reverse) {
+                for (i = p->high; i >= p->low; i--) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            } else {
+                for (i = p->low; i <= p->high; i++) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            }
+            p = p->order.right;
+        } while (p != bigp);
+    }
+
+    for (i = bigp->high + 1; i < ncount; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+#ifndef USE_TIMESTAMP
+        locate_cache[i] = bigp;
+#endif
+    }
+    for (i = 0; i < bigp->low; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+#ifndef USE_TIMESTAMP
+        locate_cache[i] = bigp;
+#endif
+    }
+    if (cyc)
+        CC_FREE (cyc, int);
+
+
+#ifdef USE_TIMESTAMP
+    flipper1_tree_free (locate_root, (flipper1 *) NULL);
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+#else
+    flipper1_tree_free (locate_root, bigp);
+    locate_root = bigp;
+#endif
+
+    order_root = locate_root;
+    locate_root->locate.parent = (flipper1 *) NULL;
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = ncount - 1;
+    locate_root->reverse = bigreverse;
+    segment_count = 1;
+
+#ifdef USE_TIMESTAMP
+    locate_cache_magic++;
+#endif
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+    order_root = locate_root;
+
+#ifdef USE_TIMESTAMP
+    if (!locate_cache) {
+        locate_cache = CC_SAFE_MALLOC (ncount, cacheobj);
+        if (!locate_cache) {
+            flipper1free (locate_root);
+            return 1;
+        }
+        for (i = 0; i < ncount; i++) {
+            locate_cache[i].segment = locate_root;
+            locate_cache[i].stamp = 0;
+        }
+        locate_cache_magic = 0;
+    } else {
+        locate_cache_magic++;
+    }
+#else
+    if (!locate_cache) {
+        locate_cache = CC_SAFE_MALLOC (ncount, flipper1 *);
+        if (!locate_cache) {
+            flipper1free (locate_root);
+            return 1;
+        }
+    }
+#endif
+
+    locate_root->locate.parent = (flipper1 *) NULL;
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = ncount - 1;
+    locate_root->reverse = 0;
+    segment_count = 1;
+
+#ifndef USE_TIMESTAMP
+    for (i = 0; i < ncount; i++) {
+        locate_cache[i] = locate_root;
+    }
+#endif
+
+    flip1_cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!flip1_cyc) {
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+        return 1;
+    }
+    flip1_inv = CC_SAFE_MALLOC (ncount, int);
+    if (!flip1_inv) {
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+        CC_FREE (flip1_cyc, int);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    flipper1 *p;
+    int i;
+    int n = 0;
+    int nseg = 0;
+
+    p = order_root;
+    do {
+        nseg++;
+        if (p->reverse) {
+            for (i = p->high; i >= p->low; i--)
+                x[n++] = flip1_cyc[i];
+        } else {
+            for (i = p->low; i <= p->high; i++)
+                x[n++] = flip1_cyc[i];
+        }
+        p = p->order.right;
+    } while (p != order_root);
+
+    assert (nseg == segment_count);
+/*
+    printf ("Segment Hits: %d  (Total %d) (%.2f)\n", seghit, segtotal,
+                (double) seghit / (double) segtotal);
+    fflush (stdout);
+*/
+    return nseg;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    flipper1_tree_free (locate_root, (flipper1 *) NULL);
+    locate_root = (flipper1 *) NULL;
+    order_root = (flipper1 *) NULL;
+
+    if (flip1_cyc)
+        CC_FREE (flip1_cyc, int);
+    if (flip1_inv)
+        CC_FREE (flip1_inv, int);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    int total, onlist;
+
+    if (locate_cache)
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+
+    if (flipper1_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding flippers\n", total - onlist);
+    }
+    flipper1free_world ();
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static flipper1 *flipper1_locate (int x)
+#else
+static flipper1 *flipper1_locate (x)
+int x;
+#endif
+{
+    flipper1 *p;
+
+#ifdef USE_TIMESTAMP
+    if (locate_cache[x].stamp == locate_cache_magic) {
+        p = locate_cache[x].segment;
+    } else {
+        p = locate_root;
+    }
+#else
+    p = locate_cache[x];
+#endif
+
+    if (p->high < x) {
+        if (p->high != -1) {
+            if (p->locate.higher && p->locate.higher->high >= x) {
+                p = p->locate.higher;
+            } else if (p->locate.parent && p->locate.parent->high >= x) {
+                p = p->locate.parent;
+            } else {
+                p = locate_root;
+            }
+        } else {
+            p = locate_root;
+        }
+    } else if (p->low > x) {
+        if (p->locate.lower && p->locate.lower->low <= x) {
+            p = p->locate.lower;
+        } else if (p->locate.parent && p->locate.parent->low <= x) {
+            p = p->locate.parent;
+        } else {
+            p = locate_root;
+        }
+    } else {
+        return p;
+    }
+
+/*
+    while (p) {       For some reason this is faster under linux
+*/
+    while (1) {
+        if (x < p->low)
+            p = p->locate.lower;
+        else if (x > p->high)
+            p = p->locate.higher;
+        else
+            break;
+    }
+#ifdef USE_TIMESTAMP
+    locate_cache[x].segment = p;
+    locate_cache[x].stamp = locate_cache_magic;
+#else
+    locate_cache[x] = p;
+#endif
+
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int ix)
+#else
+int CClinkern_flipper_next (ix)
+int ix;
+#endif
+{
+    int x = flip1_inv[ix];
+    flipper1 *p;
+
+    p = flipper1_locate (x);
+
+    if (p->reverse) {
+        return x == p->low ? (p->order.right->reverse
+                              ? flip1_cyc[p->order.right->high]
+                              : flip1_cyc[p->order.right->low])
+            : flip1_cyc[x - 1];
+    } else {
+        return x == p->high ? (p->order.right->reverse
+                               ? flip1_cyc[p->order.right->high]
+                               : flip1_cyc[p->order.right->low])
+            : flip1_cyc[x + 1];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int ix)
+#else
+int CClinkern_flipper_prev (ix)
+int ix;
+#endif
+{
+    int x = flip1_inv[ix];
+    flipper1 *p;
+
+    p = flipper1_locate (x);
+
+    if (p->reverse) {
+        return x == p->high ? (p->order.left->reverse
+                               ? flip1_cyc[p->order.left->low]
+                               : flip1_cyc[p->order.left->high])
+            : flip1_cyc[x + 1];
+    } else {
+        return x == p->low ? (p->order.left->reverse
+                              ? flip1_cyc[p->order.left->low]
+                              : flip1_cyc[p->order.left->high])
+            : flip1_cyc[x - 1];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_tree_delete (flipper1 *p)
+#else
+static void flipper1_tree_delete (p)
+flipper1 *p;
+#endif
+{
+    flipper1 *q;
+
+    if (p->locate.lower == (flipper1 *) NULL) {
+        if (p->locate.higher) {
+            PARENT_HOOKUP (p->locate.higher, p->locate.parent, p);
+        } else {
+            LOCATE_CHILD (p->locate.parent, p) = (flipper1 *) NULL;
+        }
+    } else if (p->locate.higher == (flipper1 *) NULL) {
+        PARENT_HOOKUP (p->locate.lower, p->locate.parent, p);
+    } else {
+        q = p->locate.lower;
+        while (q->locate.higher)
+            q = q->locate.higher;
+        if (q->locate.parent == p) {
+            PARENT_HOOKUP (q, p->locate.parent, p);
+            HIGHER_HOOKUP (q, p->locate.higher);
+        } else {
+            HIGHER_HOOKUP (q->locate.parent, q->locate.lower);
+            PARENT_HOOKUP (q, p->locate.parent, p);
+            LOWER_HOOKUP (q, p->locate.lower);
+            HIGHER_HOOKUP (q, p->locate.higher);
+        }
+    }
+}
+
+/*
+   flipper1_split breaks p between x-1 and x.
+*/
+
+#ifdef CC_PROTOTYPE_ANSI
+static flipper1 *flipper1_split (flipper1 *p, int x)
+#else
+static flipper1 *flipper1_split (p, x)
+flipper1 *p;
+int x;
+#endif
+{
+    flipper1 *q = flipper1alloc ();  /* This will not fail - initial supply */
+    static int side = 0;
+
+    segment_count++;
+    if (side) {
+        HIGHER_HOOKUP (q, p->locate.higher);
+        HIGHER_HOOKUP (p, q);
+        q->locate.lower = (flipper1 *) NULL;
+        q->low = x;
+        q->high = p->high;
+        p->high = x - 1;
+        q->reverse = p->reverse;
+        if (p->reverse) {
+            p->order.left->order.right = q;
+            q->order.left = p->order.left;
+            q->order.right = p;
+            p->order.left = q;
+        } else {
+            p->order.right->order.left = q;
+            q->order.right = p->order.right;
+            q->order.left = p;
+            p->order.right = q;
+        }
+        side = 0;
+        return q;
+    } else {
+        LOWER_HOOKUP (q, p->locate.lower);
+        LOWER_HOOKUP (p, q);
+        q->locate.higher =  (flipper1 *) NULL;
+        q->low = p->low;
+        q->high = x - 1;
+        p->low = x;
+        q->reverse = p->reverse;
+        if (p->reverse) {
+            p->order.right->order.left = q;
+            q->order.right = p->order.right;
+            q->order.left = p;
+            p->order.right = q;
+        } else {
+            p->order.left->order.right = q;
+            q->order.left = p->order.left;
+            q->order.right = p;
+            p->order.left = q;
+        }
+        side = 1;
+        return p;
+    }
+}
+
+/* flipper1_merge merges p->right into p.  */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_merge (flipper1 *p)
+#else
+static void flipper1_merge (p)
+flipper1 *p;
+#endif
+{
+    flipper1 *pr = p->order.right;
+
+    if (pr->high > p->high)
+        p->high = pr->high;
+    if (pr->low < p->low)
+        p->low = pr->low;
+    p->order.right = pr->order.right;
+    p->order.right->order.left = p;
+    flipper1_tree_delete (pr);
+    if (order_root == pr)
+        order_root = p;
+    flipper1free (pr);
+    segment_count--;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_checkmerge (flipper1 *x)
+#else
+static void flipper1_checkmerge (x)
+flipper1 *x;
+#endif
+{
+    flipper1 *xr = x->order.right;
+
+    if (x->reverse || x->low == x->high) {
+        if ((xr->reverse || xr->low == xr->high) && xr->high + 1 == x->low) {
+            x->reverse = 1;
+            flipper1_merge (x);
+        }
+    }
+    if (!x->reverse || x->low == x->high) {
+        if ((!xr->reverse || xr->low == xr->high) && x->high + 1 == xr->low) {
+            x->reverse = 0;
+            flipper1_merge (x);
+        }
+    }
+}
+
+#define HITSIZE 100
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int ix, int iy)
+#else
+void CClinkern_flipper_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    flipper1 *xp, *yp, *p, *ptemp, *rp, *lp;
+    int x, y;
+
+    x = flip1_inv[ix];
+    y = flip1_inv[iy];
+
+    xp = flipper1_locate (x);
+
+    if (y >= xp->low && y <= xp->high) {
+        if (xp->reverse) {
+            if (x > y && x - y <= HITSIZE) {
+                int gap = x - y;
+                gap++;
+                gap /= 2;
+                for (; gap; gap--) {
+                   ix = flip1_cyc[x];
+                   iy = flip1_cyc[y];
+                   flip1_cyc[x] = iy;
+                   flip1_cyc[y] = ix;
+                   flip1_inv[ix] = y++;
+                   flip1_inv[iy] = x--;
+                }
+                return;
+            }
+        } else {
+            if (x < y && y - x <= HITSIZE) {
+                int gap = y - x;
+                gap++;
+                gap /= 2;
+                for (; gap; gap--) {
+                   ix = flip1_cyc[x];
+                   iy = flip1_cyc[y];
+                   flip1_cyc[x] = iy;
+                   flip1_cyc[y] = ix;
+                   flip1_inv[ix] = y--;
+                   flip1_inv[iy] = x++;
+                }
+                return;
+            }
+        }
+    }
+
+
+    /* split segments if necessary */
+    if (xp->reverse) {
+        if (x != xp->high) {
+            xp = flipper1_split (xp, x + 1);
+            xp = xp->order.right;
+        }
+    } else {
+        if (x != xp->low) {
+            xp = flipper1_split (xp, x);
+        }
+    }
+
+    yp = flipper1_locate (y);
+    if (yp->reverse) {
+        if (y != yp->low) {
+            yp = flipper1_split (yp, y);
+        }
+    } else {
+        if (y != yp->high) {
+            yp = flipper1_split (yp, y + 1);
+            yp = yp->order.left;
+        }
+    }
+    xp = flipper1_locate (x);
+
+    /* reverse */
+    p = xp;
+    for (;;) {
+        SWAP (p->order.right, p->order.left, ptemp);
+        p->reverse ^= 1;
+        if (p == yp)
+            break;
+        p = p->order.left;
+    }
+
+    if (xp->order.right != yp) {
+        lp = xp->order.right;
+        rp = yp->order.left;
+
+        lp->order.right = yp;
+        rp->order.left = xp;
+        xp->order.right = rp;
+        yp->order.left = lp;
+    }
+    /* merge segments if necessary */
+    rp = xp->order.right;
+    if (yp != xp->order.right) {
+        flipper1_checkmerge (xp);
+        flipper1_checkmerge (yp->order.left);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int ix, int iy, int iz)
+#else
+int CClinkern_flipper_sequence (ix, iy, iz)
+int ix, iy, iz;
+#endif
+{
+    flipper1 *xp, *yp, *zp;
+    int x, y, z;
+
+    x = flip1_inv[ix];
+    y = flip1_inv[iy];
+    z = flip1_inv[iz];
+
+    if (segment_count == 1) {
+        if (locate_root->reverse) {
+            if (x >= y)
+                return y >= z || z >= x;
+            else
+                return y >= z && z >= x;
+        } else {
+            if (x <= y)
+                return y <= z || z <= x;
+            else
+                return y <= z && z <= x;
+        }
+    }
+
+    xp = flipper1_locate (x);
+    yp = flipper1_locate (y);
+    zp = flipper1_locate (z);
+
+    if (xp == yp) {
+        if (xp == zp) {
+            if (xp->reverse) {
+                if (x >= y) {
+                    return y >= z || z >= x;
+                } else {
+                    return y >= z && z >= x;
+                }
+            } else {
+                if (x <= y) {
+                    return y <= z || z <= x;
+                } else {
+                    return y <= z && z <= x;
+                }
+            }
+        } else {
+            if (xp->reverse) {
+                return x >= y;
+            } else {
+                return x <= y;
+            }
+        }
+    } else if (xp == zp) {
+        if (xp->reverse) {
+            return z >= x;
+        } else {
+            return z <= x;
+        }
+    } else if (yp == zp) {
+        if (yp->reverse) {
+            return y >= z;
+        } else {
+            return y <= z;
+        }
+    } else {
+        while (xp != yp) {
+            if (xp == zp) {
+                return 0;
+            }
+            xp = xp->order.right;
+        }
+        return 1;
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_sg2.c b/contrib/blossom/concorde97/LINKERN/flip_sg2.c
new file mode 100644
index 0000000000000000000000000000000000000000..432cc8e6d60ec9d1e29e7f2cea06513e7f6ad468
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_sg2.c
@@ -0,0 +1,872 @@
+/***************************************************************************/
+/*                                                                         */
+/*  TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Segments with no UNDO    */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 13, 1995 (but mainly from March, 1990)                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_reset_perm (int ncount)                         */
+/*     reinitializes the cycle to the one current in the perm array.       */
+/*   int CClinkern_flipper_reset_temp (int ncount)                         */
+/*     reinitializes the cycle to the current cycle - use this to keep the */
+/*     number of segments small.                                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int x, int y)                            */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   void CClinkern_flipper_flip_perm (int x, int y)                       */
+/*     performs the flip on the reference (perm) cycle - use this to avoid */
+/*     a reinitialization when there have not been too many flips.         */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*     This is similar to the version of segments proposed by FJMO. It is  */
+/* faster on smaller problems, but is not as flexible since it makes it    */
+/* expensive to backtrack deep in the search.                              */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* SEGMENT FLIPPER (flipper1):                                             */
+/*                                                                         */
+/*     1. CClinkern_flipper_cycle and CClinkern_flipper_cycle_inverse      */
+/*        return the current number of segments.                           */
+/*                                                                         */
+/*     2. This is the first pass - uses a straight cycle of segments, and  */
+/*        a tree to find segment.                                          */
+/*                                                                         */
+/***************************************************************************/
+
+/* #define CC_USE_QUICK_FLIPS  */
+
+typedef struct flipper1 {
+    struct {
+        struct flipper1 *lower;
+        struct flipper1 *higher;
+    } locate;
+    struct {
+        struct flipper1 *left;
+        struct flipper1 *right;
+    } order;
+    int low;
+    int high;
+    int reverse;
+    struct flipper1 *next;
+} flipper1;
+
+typedef struct cacheobj {
+    struct flipper1 *segment;
+    int              stamp;
+} cacheobj;
+
+#ifdef CC_USE_QUICK_FLIPS
+typedef struct quickpair {
+    int first;
+    int last;
+    int dir;
+    int reversed;
+} quickpair;
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+#ifdef CC_USE_QUICK_FLIPS
+    undo_quick_flips (void),
+#endif
+    flipper1free (flipper1 *p),
+    flipper1_tree_free (flipper1 *);
+
+static flipper1
+   *flipper1_locate (int x),
+   *flipper1_split (flipper1 *, int);
+
+#else
+
+static void
+#ifdef CC_USE_QUICK_FLIPS
+    undo_quick_flips (),
+#endif
+    flipper1free (),
+    flipper1_tree_free ();
+
+static flipper1
+   *flipper1_locate (),
+   *flipper1_split ();
+
+#endif
+
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+
+static flipper1 *locate_root = (flipper1 *) NULL;
+static flipper1 *order_root = (flipper1 *) NULL;
+static cacheobj *locate_cache = (cacheobj *) NULL;
+static int       locate_cache_magic = 0;
+
+#ifdef CC_USE_QUICK_FLIPS
+static quickpair quickstack[1000];
+static top_quickstack = 0;
+#endif
+
+static int *flip1_cyc = (int *) NULL;
+static int *flip1_inv = (int *) NULL;
+static int reversed = 0;
+static int short_size = 0;
+static int cycle_size = 0;
+static int segment_count = 1;
+
+CC_PTR_ALLOC_ROUTINE (flipper1, flipper1alloc, flipper1chunklist,
+                  flipper1freelist)
+CC_PTR_FREE_WORLD_ROUTINE( flipper1, flipper1free_world, flipper1chunklist,
+                  flipper1freelist)
+CC_PTR_LEAKS_ROUTINE (flipper1, flipper1_check_leaks, flipper1chunklist,
+                  flipper1freelist, reverse, int)
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1free (flipper1 *p)
+#else
+static void flipper1free (p)
+flipper1 *p;
+#endif
+{
+    p->next = flipper1freelist;
+    flipper1freelist = p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_tree_free (flipper1 *h)
+#else
+static void flipper1_tree_free (h)
+flipper1 *h;
+#endif
+{
+    flipper1 *p = order_root, *q = order_root;
+
+    if (!p)
+        return;
+
+    do {
+        p->next = flipper1freelist;   /* this does flipper1free (p) */
+        flipper1freelist = p;
+        p = p->order.right;
+    } while (p != q);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset_perm (int keeper)
+#else
+int CClinkern_flipper_reset_perm (keeper)
+int keeper;
+#endif
+{
+/*
+    printf ("CClinkern_flipper_reset_perm (%d)\n", keeper);
+    fflush (stdout);
+*/
+
+#ifdef CC_USE_QUICK_FLIPS
+    if (!keeper) {
+        undo_quick_flips ();
+    } else {
+        top_quickstack = 0;
+    }
+#endif
+
+    flipper1_tree_free (locate_root);
+
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+
+    order_root = locate_root;
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = cycle_size - 1;
+    locate_root->reverse = reversed;
+    segment_count = 1;
+    locate_cache_magic++;
+
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset_temp (int ncount)
+#else
+int CClinkern_flipper_reset_temp (ncount)
+int ncount;
+#endif
+{
+    int i, n, *cyc = (int *) NULL;
+    int nseg = 0, big = 0, bigreverse = 0;
+    flipper1 *p, *bigp = (flipper1 *) NULL;
+
+    printf ("CClinkern_flipper_reset_temp ...\n");
+    fflush (stdout);
+
+    p = order_root;
+    do {
+        if (p->high - p->low > big) {
+            big = p->high - p->low;
+            bigp = p;
+        }
+        nseg++;
+        p = p->order.right;
+    } while (p != order_root);
+
+    if (nseg == 1)
+        return 0;
+
+    cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!cyc) {
+        CC_FREE (locate_cache, cacheobj);
+        return 1;
+    }
+    if (bigp->reverse) {
+        bigreverse = 1;
+        p = bigp->order.left;
+        n = bigp->high + 1;
+        do {
+            if (!p->reverse) {
+                for (i = p->high; i >= p->low; i--) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            } else {
+                for (i = p->low; i <= p->high; i++) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            }
+            p = p->order.left;
+        } while (p != bigp);
+    } else {
+        bigreverse = 0;
+        p = bigp->order.right;
+        n = bigp->high + 1;
+        do {
+            if (p->reverse) {
+                for (i = p->high; i >= p->low; i--) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            } else {
+                for (i = p->low; i <= p->high; i++) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            }
+            p = p->order.right;
+        } while (p != bigp);
+    }
+
+    for (i = bigp->high + 1; i < ncount; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+    }
+    for (i = 0; i < bigp->low; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+    }
+    if (cyc)
+        CC_FREE (cyc, int);
+
+
+    flipper1_tree_free (locate_root);
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+
+    order_root = locate_root;
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = ncount - 1;
+    locate_root->reverse = bigreverse;
+    segment_count = 1;
+    reversed = bigreverse;
+    locate_cache_magic++;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+    order_root = locate_root;
+
+    if (!locate_cache) {
+        locate_cache = CC_SAFE_MALLOC (ncount, cacheobj);
+        if (!locate_cache) {
+            flipper1free (locate_root);
+            return 1;
+        }
+        for (i = 0; i < ncount; i++) {
+            locate_cache[i].segment = locate_root;
+            locate_cache[i].stamp = 0;
+        }
+        locate_cache_magic = 0;
+    } else {
+        locate_cache_magic++;
+    }
+
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = ncount - 1;
+    locate_root->reverse = 0;
+    segment_count = 1;
+
+    flip1_cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!flip1_cyc) {
+        CC_FREE (locate_cache, cacheobj);
+        return 1;
+    }
+    flip1_inv = CC_SAFE_MALLOC (ncount, int);
+    if (!flip1_inv) {
+        CC_FREE (locate_cache, cacheobj);
+        CC_FREE (flip1_cyc, int);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+    }
+    cycle_size = ncount;
+    short_size = ncount/2;
+    reversed = 0;
+
+#ifdef CC_USE_QUICK_FLIPS
+    top_quickstack = 0;
+#endif
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    int *p;
+
+/*
+    printf ("CClinkern_flipper_cycle ...\n");
+    fflush (stdout);
+*/
+
+#ifdef CC_USE_QUICK_FLIPS
+    while (top_quickstack) {
+        undo_quick_flips ();
+    }
+#endif
+
+    if (reversed) {
+        p = flip1_cyc + cycle_size;
+        while (p > flip1_cyc) {
+            *x++ = *--p;
+        }
+    } else {
+        p = flip1_cyc + cycle_size;
+        x += cycle_size;
+        while (p > flip1_cyc) {
+            *--x = *--p;
+        }
+    }
+
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    flipper1_tree_free (locate_root);
+    locate_root = (flipper1 *) NULL;
+    order_root = (flipper1 *) NULL;
+
+    if (flip1_cyc)
+        CC_FREE (flip1_cyc, int);
+    if (flip1_inv)
+        CC_FREE (flip1_inv, int);
+    cycle_size = 0;
+    short_size = 0;
+    reversed = 0;
+#ifdef CC_USE_QUICK_FLIPS
+    top_quickstack = 0;
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    int total, onlist;
+
+    if (locate_cache)
+        CC_FREE (locate_cache, cacheobj);
+
+    if (flipper1_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding flippers\n", total - onlist);
+    }
+    flipper1free_world ();
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static flipper1 *flipper1_locate (int x)
+#else
+static flipper1 *flipper1_locate (x)
+int x;
+#endif
+{
+    flipper1 *p;
+
+    if (locate_cache[x].stamp == locate_cache_magic) {
+        p = locate_cache[x].segment;
+    } else {
+        p = locate_root;
+    }
+
+/*
+    while (p) {       For some reason this is faster under linux
+*/
+    while (1) {
+        if (x < p->low)
+            p = p->locate.lower;
+        else if (x > p->high)
+            p = p->locate.higher;
+        else
+            break;
+    }
+
+    locate_cache[x].segment = p;
+    locate_cache[x].stamp = locate_cache_magic;
+
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int ix)
+#else
+int CClinkern_flipper_next (ix)
+int ix;
+#endif
+{
+    int x = flip1_inv[ix];
+    flipper1 *p;
+
+    if (segment_count == 1) {
+        int y;
+        if (locate_root->reverse) {
+            y = x - 1;
+            return (y >= 0) ? flip1_cyc[y] : flip1_cyc[cycle_size-1];
+        } else {
+            y = x + 1;
+            return (y < cycle_size) ? flip1_cyc[y] : flip1_cyc[0];
+        }
+    }
+
+    p = flipper1_locate (x);
+
+    if (p->reverse) {
+        return x == p->low ? (p->order.right->reverse
+                              ? flip1_cyc[p->order.right->high]
+                              : flip1_cyc[p->order.right->low])
+            : flip1_cyc[x - 1];
+    } else {
+        return x == p->high ? (p->order.right->reverse
+                               ? flip1_cyc[p->order.right->high]
+                               : flip1_cyc[p->order.right->low])
+            : flip1_cyc[x + 1];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int ix)
+#else
+int CClinkern_flipper_prev (ix)
+int ix;
+#endif
+{
+    int x = flip1_inv[ix];
+    flipper1 *p;
+
+    if (segment_count == 1) {
+        int y;
+        if (locate_root->reverse) {
+            y = x + 1;
+            return (y < cycle_size) ? flip1_cyc[y] : flip1_cyc[0];
+        } else {
+            y = x - 1;
+            return (y >= 0) ? flip1_cyc[y] : flip1_cyc[cycle_size-1];
+        }
+    }
+
+    p = flipper1_locate (x);
+
+    if (p->reverse) {
+        return x == p->high ? (p->order.left->reverse
+                               ? flip1_cyc[p->order.left->low]
+                               : flip1_cyc[p->order.left->high])
+            : flip1_cyc[x + 1];
+    } else {
+        return x == p->low ? (p->order.left->reverse
+                              ? flip1_cyc[p->order.left->low]
+                              : flip1_cyc[p->order.left->high])
+            : flip1_cyc[x - 1];
+    }
+}
+
+/*
+   flipper1_split breaks p between x-1 and x.  returns segment containing x.
+*/
+
+#ifdef CC_PROTOTYPE_ANSI
+static flipper1 *flipper1_split (flipper1 *p, int x)
+#else
+static flipper1 *flipper1_split (p, x)
+flipper1 *p;
+int x;
+#endif
+{
+    flipper1 *q = flipper1alloc ();  /* This will not fail - initial supply */
+    static int side = 0;
+
+    segment_count++;
+    if (side) {
+        q->locate.higher = p->locate.higher;
+        p->locate.higher = q;
+        q->locate.lower = (flipper1 *) NULL;;
+        q->low = x;
+        q->high = p->high;
+        p->high = x - 1;
+        q->reverse = p->reverse;
+        if (p->reverse) {
+            p->order.left->order.right = q;
+            q->order.left = p->order.left;
+            q->order.right = p;
+            p->order.left = q;
+        } else {
+            p->order.right->order.left = q;
+            q->order.right = p->order.right;
+            q->order.left = p;
+            p->order.right = q;
+        }
+        side = 1;
+        return q;
+    } else {
+        q->locate.lower = p->locate.lower;
+        p->locate.lower = q;
+        q->locate.higher =  (flipper1 *) NULL;
+        q->low = p->low;
+        q->high = x - 1;
+        p->low = x;
+        q->reverse = p->reverse;
+        if (p->reverse) {
+            p->order.right->order.left = q;
+            q->order.right = p->order.right;
+            q->order.left = p;
+            p->order.right = q;
+        } else {
+            p->order.left->order.right = q;
+            q->order.left = p->order.left;
+            q->order.right = p;
+            p->order.left = q;
+        }
+        side = 0;
+        return p;
+    }
+}
+
+#ifdef CC_USE_QUICK_FLIPS
+#define HITSIZE 10   /* Cannot run problems of size < 2 * HITSIZE */
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int ix, int iy)
+#else
+void CClinkern_flipper_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    flipper1 *xp, *yp, *p, *ptemp, *rp, *lp;
+    int x, y;
+
+    x = flip1_inv[ix];
+    y = flip1_inv[iy];
+
+    xp = flipper1_locate (x);
+
+#ifdef CC_USE_QUICK_FLIPS
+    if (y >= xp->low && y <= xp->high) {
+        if (xp->reverse) {
+            if (x > y && x - y <= HITSIZE) {
+                int gap = x - y;
+                quickstack[top_quickstack].first = ix;
+                quickstack[top_quickstack].last = iy;
+                quickstack[top_quickstack].reversed = reversed;
+                quickstack[top_quickstack++].dir = 1;
+                gap++;
+                gap /= 2;
+                for (; gap; gap--) {
+                   ix = flip1_cyc[x];
+                   iy = flip1_cyc[y];
+                   flip1_cyc[x] = iy;
+                   flip1_cyc[y] = ix;
+                   flip1_inv[ix] = y++;
+                   flip1_inv[iy] = x--;
+                }
+                return;
+            }
+        } else {
+            if (x < y && y - x <= HITSIZE) {
+                int gap = y - x;
+                quickstack[top_quickstack].first = ix;
+                quickstack[top_quickstack].last = iy;
+                quickstack[top_quickstack].reversed = reversed;
+                quickstack[top_quickstack++].dir = 0;
+                gap++;
+                gap /= 2;
+                for (; gap; gap--) {
+                   ix = flip1_cyc[x];
+                   iy = flip1_cyc[y];
+                   flip1_cyc[x] = iy;
+                   flip1_cyc[y] = ix;
+                   flip1_inv[ix] = y--;
+                   flip1_inv[iy] = x++;
+                }
+                return;
+            }
+        }
+    }
+#endif
+
+
+    /* split segments if necessary */
+    if (xp->reverse) {
+        if (x != xp->high) {
+            xp = flipper1_split (xp, x + 1);
+            xp = xp->order.right;
+        }
+    } else {
+        if (x != xp->low) {
+            xp = flipper1_split (xp, x);
+        }
+    }
+
+    yp = flipper1_locate (y);
+    if (yp->reverse) {
+        if (y != yp->low) {
+            yp = flipper1_split (yp, y);
+        }
+    } else {
+        if (y != yp->high) {
+            yp = flipper1_split (yp, y + 1);
+            yp = yp->order.left;
+        }
+    }
+    xp = flipper1_locate (x);
+
+    /* reverse */
+    p = xp;
+    for (;;) {
+        SWAP (p->order.right, p->order.left, ptemp);
+        p->reverse ^= 1;
+        if (p == yp)
+            break;
+        p = p->order.left;
+    }
+
+    if (xp->order.right != yp) {
+        lp = xp->order.right;
+        rp = yp->order.left;
+
+        lp->order.right = yp;
+        rp->order.left = xp;
+        xp->order.right = rp;
+        yp->order.left = lp;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    int xloc = flip1_inv[x];
+    int yloc = flip1_inv[y];
+    int zloc = flip1_inv[z];
+
+    if (reversed) {
+        if (xloc >= yloc)
+            return yloc >= zloc || zloc >= xloc;
+        else
+            return yloc >= zloc && zloc >= xloc;
+    } else {
+        if (xloc <= yloc)
+            return yloc <= zloc || zloc <= xloc;
+        else
+            return yloc <= zloc && zloc <= xloc;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip_perm (int x, int y)
+#else
+void CClinkern_flipper_flip_perm (x, y)
+int x,y;
+#endif
+{
+    int xloc = flip1_inv[x];
+    int yloc = flip1_inv[y];
+    int temp;
+    int gap;
+
+/*
+    printf ("CClinkern_flipper_flip_perm (%d, %d)\n", x, y); fflush (stdout);
+*/
+
+    if (reversed) {
+        SWAP (xloc, yloc, temp);
+    }
+    gap = yloc - xloc;
+    if (gap < 0) gap += cycle_size;
+
+    if (gap > short_size) {
+        SWAP (xloc, yloc, temp);
+        reversed ^= 1;
+        xloc++;
+        if (xloc >= cycle_size)
+            xloc = 0;
+        yloc--;
+        if (yloc < 0)
+            yloc = cycle_size - 1;
+        gap = cycle_size - gap - 2;
+    }
+
+    if (xloc > yloc) {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip1_cyc[xloc];
+            y = flip1_cyc[yloc];
+            flip1_cyc[xloc] = y;
+            flip1_cyc[yloc] = x;
+            flip1_inv[x] = yloc--;
+            flip1_inv[y] = xloc++;
+            if (xloc >= cycle_size)
+                xloc = 0;
+            if (yloc < 0)
+                yloc = cycle_size - 1;
+        }
+    } else {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip1_cyc[xloc];
+            y = flip1_cyc[yloc];
+            flip1_cyc[xloc] = y;
+            flip1_cyc[yloc] = x;
+            flip1_inv[x] = yloc--;
+            flip1_inv[y] = xloc++;
+        }
+    }
+}
+
+#ifdef CC_USE_QUICK_FLIPS
+#ifdef CC_PROTOTYPE_ANSI
+static void undo_quick_flips (void)
+#else
+static void undo_quick_flips ()
+#endif
+{
+    int x, y, ix, iy, gap;
+
+/*
+    printf ("undo_quick_flips (%d)\n", top_quickstack);
+    fflush (stdout);
+*/
+
+    while (top_quickstack) {
+        top_quickstack--;
+
+        assert (reversed == quickstack[top_quickstack].reversed);
+
+        x = flip1_inv[quickstack[top_quickstack].first];
+        y = flip1_inv[quickstack[top_quickstack].last];
+        if (quickstack[top_quickstack].dir) {
+            SWAP (x, y , ix);
+        }
+        gap = x - y + 1;
+        if (gap < 0) {
+            printf ("AARG: %d\n", gap); fflush (stdout);
+        }
+        gap /= 2;
+        for (; gap; gap--) {
+           ix = flip1_cyc[x];
+           iy = flip1_cyc[y];
+           flip1_cyc[x] = iy;
+           flip1_cyc[y] = ix;
+           flip1_inv[ix] = y++;
+           flip1_inv[iy] = x--;
+        }
+    }
+}
+#endif
diff --git a/contrib/blossom/concorde97/LINKERN/flip_sg3.c b/contrib/blossom/concorde97/LINKERN/flip_sg3.c
new file mode 100644
index 0000000000000000000000000000000000000000..8433b8ebea7d485e593194cfcc53d79f317dc1cc
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_sg3.c
@@ -0,0 +1,982 @@
+/***************************************************************************/
+/*                                                                         */
+/*     TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Segments with UNDO    */
+/*                                                 - No perm mucks         */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: April 24, 1995 (but mainly from March, 1990)                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_reset_temp (int ncount)                         */
+/*     reinitializes the cycle to the current cycle - use this to keep the */
+/*     number of segments small.                                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int x, int y)                            */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version is closest to our orignal segment code. It undos the */
+/* flips that do not lead to an improvement.                               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#define USE_TIMESTAMP
+
+/***************************************************************************/
+/*                                                                         */
+/* FULL SEGMENT FLIPPER (flipper1):                                        */
+/*                                                                         */
+/*     1. CClinkern_flipper_cycle and CClinkern_flipper_cycle_inverse      */
+/*        return the current number of segments.                           */
+/*                                                                         */
+/*     2. this version wants to keep the segment tree around until a       */
+/*        Lin-Kern round is complete.  If its an improving round, then     */
+/*        the perm tour is updated. If its not a winner, then the segment  */
+/*        tree is discarded. Sounds like it would be okay late in a run    */
+/*        not many winners are found (do not use ACCEPT_TIES), but the big */
+/*        trees lead to long searches for the segment containing a node.   */
+/*                                                                         */
+/***************************************************************************/
+
+
+typedef struct flipper1 {
+    struct {
+        struct flipper1 *parent;
+        struct flipper1 *lower;
+        struct flipper1 *higher;
+    } locate;
+    struct {
+        struct flipper1 *left;
+        struct flipper1 *right;
+    } order;
+    int low;
+    int high;
+    int reverse;
+    struct flipper1 *next;
+} flipper1;
+
+#ifdef  USE_TIMESTAMP
+typedef struct cacheobj {
+    struct flipper1 *segment;
+    int              stamp;
+} cacheobj;
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    flipper1_tree_delete (flipper1 *),
+    flipper1_merge (flipper1 *),
+    flipper1_checkmerge (flipper1 *),
+    flipper1free (flipper1 *p),
+    flipper1_tree_free (flipper1 *, flipper1 *);
+
+static flipper1
+   *flipper1_locate (int x),
+   *flipper1_split (flipper1 *, int);
+
+#else
+
+static void
+    flipper1_tree_delete (),
+    flipper1_merge (),
+    flipper1_checkmerge (),
+    flipper1free (),
+    flipper1_tree_free ();
+
+static flipper1
+   *flipper1_locate (),
+   *flipper1_split ();
+
+#endif
+
+#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
+
+#define LOCATE_CHILD(p, c) (*((p) ? ((p)->locate.lower == (c) ?              \
+                              &(p)->locate.lower : &(p)->locate.higher) :    \
+                              &locate_root))
+
+#define PARENT_HOOKUP(q, p, c) (((q)->locate.parent = (p)),                  \
+                                (LOCATE_CHILD((p),(c)) = (q)))
+
+#define HIGHER_HOOKUP(p, c) (((p)->locate.higher = (c)),                     \
+                       ((c) ? (c)->locate.parent = (p) : (flipper1 *) NULL))
+
+#define LOWER_HOOKUP(p, c)  (((p)->locate.lower = (c)),                      \
+                       ((c) ? (c)->locate.parent = (p) : (flipper1 *) NULL))
+
+static flipper1 *locate_root = (flipper1 *) NULL;
+static flipper1 *order_root = (flipper1 *) NULL;
+#ifdef USE_TIMESTAMP
+static cacheobj *locate_cache = (cacheobj *) NULL;
+static int       locate_cache_magic = 0;
+#else
+static flipper1 **locate_cache = (flipper1 **) NULL;
+#endif
+
+static int *flip1_cyc = (int *) NULL;
+static int *flip1_inv = (int *) NULL;
+static int reversed = 0;
+static int short_size = 0;
+static int cycle_size = 0;
+static int segment_count = 1;
+
+/*
+static double totalsize = 1.0;
+static double totaldepth = 1.0;
+static int depthcalls = 1;
+*/
+
+CC_PTR_ALLOC_ROUTINE (flipper1, flipper1alloc, flipper1chunklist,
+                  flipper1freelist)
+CC_PTR_FREE_WORLD_ROUTINE (flipper1, flipper1free_world, flipper1chunklist,
+                  flipper1freelist)
+CC_PTR_LEAKS_ROUTINE (flipper1, flipper1_check_leaks, flipper1chunklist,
+                  flipper1freelist, reverse, int)
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1free (flipper1 *p)
+#else
+static void flipper1free (p)
+flipper1 *p;
+#endif
+{
+    p->next = flipper1freelist;
+    flipper1freelist = p;
+    p->low = p->high = -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_tree_free (flipper1 *p, flipper1 *bigp)
+#else
+static void flipper1_tree_free (p, bigp)
+flipper1 *p, *bigp;
+#endif
+{
+    if (p) {
+        flipper1_tree_free (p->locate.lower, bigp);
+        flipper1_tree_free (p->locate.higher, bigp);
+        if (p != bigp)
+           flipper1free (p);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset_perm (int ncount)
+#else
+int CClinkern_flipper_reset_perm (ncount)
+int ncount;
+#endif
+{
+    flipper1_tree_free (locate_root, (flipper1 *) NULL);
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+
+    order_root = locate_root;
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = cycle_size - 1;
+    locate_root->reverse = reversed;
+    segment_count = 1;
+    locate_cache_magic++;
+
+/*
+    printf ("Locate Calls: %d   Depth: %.0f   Size: %.0f\n",
+               depthcalls, totaldepth/depthcalls, totalsize/depthcalls);
+    fflush (stdout);
+*/
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset_temp (int ncount)
+#else
+int CClinkern_flipper_reset_temp (ncount)
+int ncount;
+#endif
+{
+    int i, n, *cyc = (int *) NULL;
+    int nseg = 0, big = 0, bigreverse = 0;
+    flipper1 *p, *bigp = (flipper1 *) NULL;
+
+/*
+    printf ("CClinkern_flipper_reset_temp ....\n"); fflush (stdout);
+    printf ("Locate Calls: %d   Depth: %.0f   Size: %.0f\n",
+               depthcalls, totaldepth/depthcalls, totalsize/depthcalls);
+    fflush (stdout);
+*/
+
+    p = order_root;
+    do {
+        if (p->high - p->low > big) {
+            big = p->high - p->low;
+            bigp = p;
+        }
+        nseg++;
+        p = p->order.right;
+    } while (p != order_root);
+
+    if (nseg == 1)
+        return 0;
+
+    cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!cyc) {
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+        return 1;
+    }
+    if (bigp->reverse) {
+        bigreverse = 1;
+        p = bigp->order.left;
+        n = bigp->high + 1;
+        do {
+            if (!p->reverse) {
+                for (i = p->high; i >= p->low; i--) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            } else {
+                for (i = p->low; i <= p->high; i++) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            }
+            p = p->order.left;
+        } while (p != bigp);
+    } else {
+        bigreverse = 0;
+        p = bigp->order.right;
+        n = bigp->high + 1;
+        do {
+            if (p->reverse) {
+                for (i = p->high; i >= p->low; i--) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            } else {
+                for (i = p->low; i <= p->high; i++) {
+                    if (n == ncount)
+                        n = 0;
+                    cyc[n++] = flip1_cyc[i];
+                }
+            }
+            p = p->order.right;
+        } while (p != bigp);
+    }
+
+    for (i = bigp->high + 1; i < ncount; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+#ifndef USE_TIMESTAMP
+        locate_cache[i] = bigp;
+#endif
+    }
+    for (i = 0; i < bigp->low; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+#ifndef USE_TIMESTAMP
+        locate_cache[i] = bigp;
+#endif
+    }
+    if (cyc)
+        CC_FREE (cyc, int);
+
+
+#ifdef USE_TIMESTAMP
+    flipper1_tree_free (locate_root, (flipper1 *) NULL);
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+#else
+    flipper1_tree_free (locate_root, bigp);
+    locate_root = bigp;
+#endif
+
+    order_root = locate_root;
+    locate_root->locate.parent = (flipper1 *) NULL;
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = ncount - 1;
+    locate_root->reverse = bigreverse;
+    segment_count = 1;
+    reversed = bigreverse;
+
+#ifdef USE_TIMESTAMP
+    locate_cache_magic++;
+#endif
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    locate_root = flipper1alloc ();
+    if (!locate_root)
+        return 1;
+    order_root = locate_root;
+
+#ifdef USE_TIMESTAMP
+    if (!locate_cache) {
+        locate_cache = CC_SAFE_MALLOC (ncount, cacheobj);
+        if (!locate_cache) {
+            flipper1free (locate_root);
+            return 1;
+        }
+        for (i = 0; i < ncount; i++) {
+            locate_cache[i].segment = locate_root;
+            locate_cache[i].stamp = 0;
+        }
+        locate_cache_magic = 0;
+    } else {
+        locate_cache_magic++;
+    }
+#else
+    if (!locate_cache) {
+        locate_cache = CC_SAFE_MALLOC (ncount, flipper1 *);
+        if (!locate_cache) {
+            flipper1free (locate_root);
+            return 1;
+        }
+    }
+#endif
+
+    locate_root->locate.parent = (flipper1 *) NULL;
+    locate_root->locate.lower = (flipper1 *) NULL;
+    locate_root->locate.higher = (flipper1 *) NULL;
+    locate_root->order.left = locate_root;
+    locate_root->order.right = locate_root;
+    locate_root->low = 0;
+    locate_root->high = ncount - 1;
+    locate_root->reverse = 0;
+    segment_count = 1;
+
+#ifndef USE_TIMESTAMP
+    for (i = 0; i < ncount; i++) {
+        locate_cache[i] = locate_root;
+    }
+#endif
+
+    flip1_cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!flip1_cyc) {
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+        return 1;
+    }
+    flip1_inv = CC_SAFE_MALLOC (ncount, int);
+    if (!flip1_inv) {
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+        CC_FREE (flip1_cyc, int);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        flip1_cyc[i] = cyc[i];
+        flip1_inv[cyc[i]] = i;
+    }
+    cycle_size = ncount;
+    short_size = ncount/2;
+    reversed = 0;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    flipper1 *p;
+    int i;
+    int n = 0;
+    int nseg = 0;
+
+    p = order_root;
+
+    do {
+        nseg++;
+        if (p->reverse) {
+            for (i = p->high; i >= p->low; i--)
+                x[n++] = flip1_cyc[i];
+        } else {
+            for (i = p->low; i <= p->high; i++)
+                x[n++] = flip1_cyc[i];
+        }
+        p = p->order.right;
+    } while (p != order_root);
+
+    assert (nseg == segment_count);
+/*
+    printf ("Segment Hits: %d  (Total %d) (%.2f)\n", seghit, segtotal,
+                (double) seghit / (double) segtotal);
+    fflush (stdout);
+*/
+    return nseg;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    flipper1_tree_free (locate_root, (flipper1 *) NULL);
+    locate_root = (flipper1 *) NULL;
+    order_root = (flipper1 *) NULL;
+
+    if (flip1_cyc)
+        CC_FREE (flip1_cyc, int);
+    if (flip1_inv)
+        CC_FREE (flip1_inv, int);
+    cycle_size = 0;
+    short_size = 0;
+    reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    int total, onlist;
+
+    if (locate_cache)
+#ifdef USE_TIMESTAMP
+        CC_FREE (locate_cache, cacheobj);
+#else
+        CC_FREE (locate_cache, flipper1 *);
+#endif
+
+    if (flipper1_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding flippers\n", total - onlist);
+    }
+    flipper1free_world ();
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static flipper1 *flipper1_locate (int x)
+#else
+static flipper1 *flipper1_locate (x)
+int x;
+#endif
+{
+    flipper1 *p;
+
+#ifdef USE_TIMESTAMP
+    if (locate_cache[x].stamp == locate_cache_magic) {
+        p = locate_cache[x].segment;
+    } else {
+        p = locate_root;
+    }
+#else
+    p = locate_cache[x];
+#endif
+
+    if (x <= p->high && x >= p->low)
+        return p;
+    else
+        p = locate_root;
+
+    if (p->high < x) {
+        if (p->high != -1) {
+            if (p->locate.higher && p->locate.higher->high >= x) {
+                p = p->locate.higher;
+            } else if (p->locate.parent && p->locate.parent->high >= x) {
+                p = p->locate.parent;
+            } else {
+                p = locate_root;
+            }
+        } else {
+            p = locate_root;
+        }
+    } else if (p->low > x) {
+        if (p->locate.lower && p->locate.lower->low <= x) {
+            p = p->locate.lower;
+        } else if (p->locate.parent && p->locate.parent->low <= x) {
+            p = p->locate.parent;
+        } else {
+            p = locate_root;
+        }
+    } else {
+        return p;
+    }
+
+/*
+    while (p) {       For some reason this is faster under linux
+*/
+    while (1) {
+/*
+        totaldepth += 1.0;
+*/
+        if (x < p->low)
+            p = p->locate.lower;
+        else if (x > p->high)
+            p = p->locate.higher;
+        else
+            break;
+    }
+/*
+    totalsize += segment_count;
+    depthcalls++;
+*/
+
+#ifdef USE_TIMESTAMP
+    locate_cache[x].segment = p;
+    locate_cache[x].stamp = locate_cache_magic;
+#else
+    locate_cache[x] = p;
+#endif
+
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int ix)
+#else
+int CClinkern_flipper_next (ix)
+int ix;
+#endif
+{
+    int x = flip1_inv[ix];
+    flipper1 *p;
+
+    p = flipper1_locate (x);
+
+    if (p->reverse) {
+        return x == p->low ? (p->order.right->reverse
+                              ? flip1_cyc[p->order.right->high]
+                              : flip1_cyc[p->order.right->low])
+            : flip1_cyc[x - 1];
+    } else {
+        return x == p->high ? (p->order.right->reverse
+                               ? flip1_cyc[p->order.right->high]
+                               : flip1_cyc[p->order.right->low])
+            : flip1_cyc[x + 1];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int ix)
+#else
+int CClinkern_flipper_prev (ix)
+int ix;
+#endif
+{
+    int x = flip1_inv[ix];
+    flipper1 *p;
+
+    p = flipper1_locate (x);
+
+    if (p->reverse) {
+        return x == p->high ? (p->order.left->reverse
+                               ? flip1_cyc[p->order.left->low]
+                               : flip1_cyc[p->order.left->high])
+            : flip1_cyc[x + 1];
+    } else {
+        return x == p->low ? (p->order.left->reverse
+                              ? flip1_cyc[p->order.left->low]
+                              : flip1_cyc[p->order.left->high])
+            : flip1_cyc[x - 1];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_tree_delete (flipper1 *p)
+#else
+static void flipper1_tree_delete (p)
+flipper1 *p;
+#endif
+{
+    flipper1 *q;
+
+    if (p->locate.lower == (flipper1 *) NULL) {
+        if (p->locate.higher) {
+            PARENT_HOOKUP (p->locate.higher, p->locate.parent, p);
+        } else {
+            LOCATE_CHILD (p->locate.parent, p) = (flipper1 *) NULL;
+        }
+    } else if (p->locate.higher == (flipper1 *) NULL) {
+        PARENT_HOOKUP (p->locate.lower, p->locate.parent, p);
+    } else {
+        q = p->locate.lower;
+        while (q->locate.higher)
+            q = q->locate.higher;
+        if (q->locate.parent == p) {
+            PARENT_HOOKUP (q, p->locate.parent, p);
+            HIGHER_HOOKUP (q, p->locate.higher);
+        } else {
+            HIGHER_HOOKUP (q->locate.parent, q->locate.lower);
+            PARENT_HOOKUP (q, p->locate.parent, p);
+            LOWER_HOOKUP (q, p->locate.lower);
+            HIGHER_HOOKUP (q, p->locate.higher);
+        }
+    }
+}
+
+/*
+   flipper1_split breaks p between x-1 and x.
+*/
+
+#ifdef CC_PROTOTYPE_ANSI
+static flipper1 *flipper1_split (flipper1 *p, int x)
+#else
+static flipper1 *flipper1_split (p, x)
+flipper1 *p;
+int x;
+#endif
+{
+    flipper1 *q = flipper1alloc ();  /* This will not fail - initial supply */
+    static int side = 0;
+
+    segment_count++;
+    if (side) {
+        HIGHER_HOOKUP (q, p->locate.higher);
+        HIGHER_HOOKUP (p, q);
+        q->locate.lower = (flipper1 *) NULL;
+        q->low = x;
+        q->high = p->high;
+        p->high = x - 1;
+        q->reverse = p->reverse;
+        if (p->reverse) {
+            p->order.left->order.right = q;
+            q->order.left = p->order.left;
+            q->order.right = p;
+            p->order.left = q;
+        } else {
+            p->order.right->order.left = q;
+            q->order.right = p->order.right;
+            q->order.left = p;
+            p->order.right = q;
+        }
+        side = 0;
+        return q;
+    } else {
+        LOWER_HOOKUP (q, p->locate.lower);
+        LOWER_HOOKUP (p, q);
+        q->locate.higher =  (flipper1 *) NULL;
+        q->low = p->low;
+        q->high = x - 1;
+        p->low = x;
+        q->reverse = p->reverse;
+        if (p->reverse) {
+            p->order.right->order.left = q;
+            q->order.right = p->order.right;
+            q->order.left = p;
+            p->order.right = q;
+        } else {
+            p->order.left->order.right = q;
+            q->order.left = p->order.left;
+            q->order.right = p;
+            p->order.left = q;
+        }
+        side = 1;
+        return p;
+    }
+}
+
+/* flipper1_merge merges p->right into p.  */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_merge (flipper1 *p)
+#else
+static void flipper1_merge (p)
+flipper1 *p;
+#endif
+{
+    flipper1 *pr = p->order.right;
+
+    if (pr->high > p->high)
+        p->high = pr->high;
+    if (pr->low < p->low)
+        p->low = pr->low;
+    p->order.right = pr->order.right;
+    p->order.right->order.left = p;
+    flipper1_tree_delete (pr);
+    if (order_root == pr)
+        order_root = p;
+    flipper1free (pr);
+    segment_count--;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper1_checkmerge (flipper1 *x)
+#else
+static void flipper1_checkmerge (x)
+flipper1 *x;
+#endif
+{
+    flipper1 *xr = x->order.right;
+
+    if (x->reverse || x->low == x->high) {
+        if ((xr->reverse || xr->low == xr->high) && xr->high + 1 == x->low) {
+            x->reverse = 1;
+            flipper1_merge (x);
+        }
+    }
+    if (!x->reverse || x->low == x->high) {
+        if ((!xr->reverse || xr->low == xr->high) && x->high + 1 == xr->low) {
+            x->reverse = 0;
+            flipper1_merge (x);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int ix, int iy)
+#else
+void CClinkern_flipper_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    flipper1 *xp, *yp, *p, *ptemp, *rp, *lp;
+    int x, y;
+
+    x = flip1_inv[ix];
+    y = flip1_inv[iy];
+
+    xp = flipper1_locate (x);
+
+    /* split segments if necessary */
+    if (xp->reverse) {
+        if (x != xp->high) {
+            xp = flipper1_split (xp, x + 1);
+            xp = xp->order.right;
+        }
+    } else {
+        if (x != xp->low) {
+            xp = flipper1_split (xp, x);
+        }
+    }
+
+    yp = flipper1_locate (y);
+    if (yp->reverse) {
+        if (y != yp->low) {
+            yp = flipper1_split (yp, y);
+        }
+    } else {
+        if (y != yp->high) {
+            yp = flipper1_split (yp, y + 1);
+            yp = yp->order.left;
+        }
+    }
+    xp = flipper1_locate (x);
+
+    /* reverse */
+    p = xp;
+    for (;;) {
+        SWAP (p->order.right, p->order.left, ptemp);
+        p->reverse ^= 1;
+        if (p == yp)
+            break;
+        p = p->order.left;
+    }
+
+    if (xp->order.right != yp) {
+        lp = xp->order.right;
+        rp = yp->order.left;
+
+        lp->order.right = yp;
+        rp->order.left = xp;
+        xp->order.right = rp;
+        yp->order.left = lp;
+    }
+    /* merge segments if necessary */
+    rp = xp->order.right;
+    if (yp != xp->order.right) {
+        flipper1_checkmerge (xp);
+        flipper1_checkmerge (yp->order.left);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int ix, int iy, int iz)
+#else
+int CClinkern_flipper_sequence (ix, iy, iz)
+int ix, iy, iz;
+#endif
+{
+    flipper1 *xp, *yp, *zp;
+    int x, y, z;
+
+    x = flip1_inv[ix];
+    y = flip1_inv[iy];
+    z = flip1_inv[iz];
+
+    if (segment_count == 1) {
+        if (locate_root->reverse) {
+            if (x >= y)
+                return y >= z || z >= x;
+            else
+                return y >= z && z >= x;
+        } else {
+            if (x <= y)
+                return y <= z || z <= x;
+            else
+                return y <= z && z <= x;
+        }
+    }
+
+    xp = flipper1_locate (x);
+    yp = flipper1_locate (y);
+    zp = flipper1_locate (z);
+
+    if (xp == yp) {
+        if (xp == zp) {
+            if (xp->reverse) {
+                if (x >= y) {
+                    return y >= z || z >= x;
+                } else {
+                    return y >= z && z >= x;
+                }
+            } else {
+                if (x <= y) {
+                    return y <= z || z <= x;
+                } else {
+                    return y <= z && z <= x;
+                }
+            }
+        } else {
+            if (xp->reverse) {
+                return x >= y;
+            } else {
+                return x <= y;
+            }
+        }
+    } else if (xp == zp) {
+        if (xp->reverse) {
+            return z >= x;
+        } else {
+            return z <= x;
+        }
+    } else if (yp == zp) {
+        if (yp->reverse) {
+            return y >= z;
+        } else {
+            return y <= z;
+        }
+    } else {
+        while (xp != yp) {
+            if (xp == zp) {
+                return 0;
+            }
+            xp = xp->order.right;
+        }
+        return 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip_perm (int x, int y)
+#else
+void CClinkern_flipper_flip_perm (x, y)
+int x,y;
+#endif
+{
+    int xloc = flip1_inv[x];
+    int yloc = flip1_inv[y];
+    int temp;
+    int gap;
+
+    if (reversed) {
+        SWAP (xloc, yloc, temp);
+    }
+    gap = yloc - xloc;
+    if (gap < 0) gap += cycle_size;
+    if (gap > short_size) {
+        SWAP (xloc, yloc, temp);
+        reversed ^= 1;
+        xloc++;
+        if (xloc >= cycle_size)
+            xloc = 0;
+        yloc--;
+        if (yloc < 0)
+                        yloc = cycle_size - 1;
+        gap = cycle_size - gap - 2;
+    }
+    if (xloc > yloc) {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip1_cyc[xloc];
+            y = flip1_cyc[yloc];
+            flip1_cyc[xloc] = y;
+            flip1_cyc[yloc] = x;
+            flip1_inv[x] = yloc--;
+            flip1_inv[y] = xloc++;
+            if (xloc >= cycle_size)
+                xloc = 0;
+            if (yloc < 0)
+                yloc = cycle_size - 1;
+        }
+    } else {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = flip1_cyc[xloc];
+            y = flip1_cyc[yloc];
+            flip1_cyc[xloc] = y;
+            flip1_cyc[yloc] = x;
+            flip1_inv[x] = yloc--;
+            flip1_inv[y] = xloc++;
+        }
+    }
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_sp1.c b/contrib/blossom/concorde97/LINKERN/flip_sp1.c
new file mode 100644
index 0000000000000000000000000000000000000000..c0a085371bc5c27e5205f5338d6babbcc291cdd1
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_sp1.c
@@ -0,0 +1,1017 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Splay Trees  (no dummy)  */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 28, 1995 (but mainly from March, 1990)                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*   void CClinkern_flipper_sequence_burst_init (int x, int z)             */
+/*     initilizes the tree for a sequence of (x, y, z) sequence queries.   */
+/*   int CClinkern_flipper_sequence_burst (int x, int y, int z)            */
+/*     can be called instead of CClinkern_flipper_sequence, after a call to*/
+/*     CClinkern_flipper_sequence_burst_init (x, y), and before any flips  */
+/*     (but it requires that NEXT_PREV_NOSPLAY be defined). Does not seem  */
+/*     to improve the running time.                                        */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       Should work well on very large problems.                          */
+/*       One of NEXT_PREV_SPLAY, NEXT_PREV_NOSPLAY, NEXT_PREV_NOSPLAY1,    */
+/*   or NEXT_PREV_NOSPLAY2 must be defined. (NEXT_PREV_NOSPLAY looks like  */
+/*   the fastest.) One of SEQUENCE_SPLAY or SEQUENCE_NOSPLAY must be       */
+/*   defined. (SEQUENCE_NOSPLAY looks like the fastest - it does not splay */
+/*   the middle node in the query.)                                        */
+/*                                                                         */
+/*   If USE_UGLY_SPLAY is defined, an uglier (but perhaps faster) splay    */
+/*   step is used.                                                         */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*   In this case, the neighbor is never splayed, so NEXT_PREV_SPLAY       */
+/*   and NEXT_PREV_NOSPLAY2 become equivalent, as do NEXT_PREV_NOSPLAY     */
+/*   NEXT_PREV_NOSPLAY1.                                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/*#define NEXT_PREV_SPLAY */     /* 1xxxx */
+#define NEXT_PREV_NOSPLAY        /* 2xxxx */
+/*#define NEXT_PREV_NOSPLAY1 */  /* 3xxxx */
+/*#define NEXT_PREV_NOSPLAY2 */  /* 4xxxx */
+/*#define SEQUENCE_SPLAY */      /* x1xxx */
+#define SEQUENCE_NOSPLAY         /* x2xxx */
+#define USE_UGLY_SPLAY           /* xx2xx */
+#define SAVE_NEIGHBORS           /* xxx2x */
+
+/***************************************************************************/
+/*                                                                         */
+/* SPLAY TREE FLIPPER (flipper4):                                          */
+/*                                                                         */
+/*     1. CClinkern_flipper_cycle and CClinkern_flipper_cycle_inverse return the number of     */
+/*        nodes.                                                           */
+/*                                                                         */
+/*     2. The basic splay implementation - uses a splay tree with one node */
+/*        per element.                                                     */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct splay {
+    struct splay *parent;
+    struct splay *child[2];
+#ifdef SAVE_NEIGHBORS
+    struct splay *neigh[2];
+#endif
+    int reversed;
+    int mark;
+    int value;
+} splay;
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    flipper4_cycle_fillin(int *x, int i, splay *p, int r);
+static void
+    flipper4_reverse (splay *p),
+    flipper4_rotate (splay *x, splay *px),
+    flipper4_splay (splay *x);
+static splay
+    *flipper4_make_tree (int a, int b, int *cyc);
+
+#else
+
+static int
+    flipper4_cycle_fillin();
+static void
+    flipper4_reverse (),
+    flipper4_rotate (),
+    flipper4_splay ();
+static splay
+    *flipper4_make_tree ();
+
+#endif
+
+static splay *splay_space = (splay *) NULL;
+static splay root;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static splay *flipper4_make_tree (int a, int b, int *cyc)
+#else
+static splay *flipper4_make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    splay *p;
+    int center;
+
+    if (b < a)
+        return (splay *) NULL;
+
+    center = (a + b)/2;
+    p = splay_space + cyc[center];
+    if ((p->child[0] = flipper4_make_tree (a, center-1, cyc)) != (splay *) NULL)
+        p->child[0]->parent = p;
+    if ((p->child[1] = flipper4_make_tree (center+1, b, cyc)) != (splay *) NULL)
+        p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+/*
+    printf ("Flipper flags:");
+#ifdef NEXT_PREV_SPLAY
+    printf (" NEXT_PREV_SPLAY");
+#endif
+#ifdef NEXT_PREV_NOSPLAY
+    printf (" NEXT_PREV_NOSPLAY");
+#endif
+#ifdef NEXT_PREV_NOSPLAY1
+    printf (" NEXT_PREV_NOSPLAY1");
+#endif
+#ifdef NEXT_PREV_NOSPLAY2
+    printf (" NEXT_PREV_NOSPLAY2");
+#endif
+#ifdef SEQUENCE_SPLAY
+    printf (" SEQUENCE_SPLAY");
+#endif
+#ifdef SEQUENCE_NOSPLAY
+    printf (" SEQUENCE_NOSPLAY");
+#endif
+#ifdef USE_UGLY_SPLAY
+    printf (" USE_UGLY_SPLAY");
+#else
+    printf (" !USE_UGLY_SPLAY");
+#endif
+#ifdef SAVE_NEIGHBORS
+    printf (" SAVE_NEIGHBORS");
+#else
+    printf (" !SAVE_NEIGHBORS");
+#endif
+    printf (" !DUMMY_LEAF\n");
+*/
+
+    root.reversed = 0;
+    root.parent = (splay *) NULL;
+    root.child[1] = (splay *) NULL;
+    root.value = ncount;
+
+    splay_space = CC_SAFE_MALLOC (ncount, splay);
+    if (!splay_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        splay_space[i].reversed = 0;
+        splay_space[i].value = i;
+        splay_space[i].mark = 0;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            splay_space[cyc[0]].neigh[0] = &splay_space[cyc[ncount-1]];
+            splay_space[cyc[ncount-1]].neigh[1] = &splay_space[cyc[0]];
+        } else {
+            splay_space[cyc[i]].neigh[0] = &splay_space[cyc[i-1]];
+            splay_space[cyc[i-1]].neigh[1] = &splay_space[cyc[i]];
+        }
+#endif
+    }
+
+    root.child[0] = flipper4_make_tree (0, ncount - 1, cyc);
+    root.child[0]->parent = &root;
+    root.mark = 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int flipper4_cycle_fillin(int *x, int i, splay *p, int r)
+#else
+static int flipper4_cycle_fillin(x, i, p, r)
+int *x;
+int i;
+splay *p;
+int r;
+#endif
+{
+    if (!p)
+        return i;
+
+    r ^= p->reversed;
+    i = flipper4_cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = flipper4_cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    return flipper4_cycle_fillin (x, 0, root.child[0], 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (splay_space)
+        CC_FREE (splay_space, splay);
+
+    root.child[0] = (splay *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_reverse (splay *p)
+#else
+static void flipper4_reverse (p)
+splay *p;
+#endif
+{
+    splay *temp;
+
+    SWAP (p->child[0], p->child[1], temp);
+    if (p->child[0])
+        p->child[0]->reversed ^= 1;
+    if (p->child[1])
+        p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], temp);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_rotate (splay *x, splay *px)
+#else
+static void flipper4_rotate (x, px)
+splay *x, *px;
+#endif
+{
+    splay *b;
+
+    if (px->child[0] == x) {
+        b = x->child[1];
+        if (b) b->parent = px;
+        x->child[1] = px;
+        x->parent = px->parent;
+        if (x->parent->child[0] == px) {
+            x->parent->child[0] = x;
+        } else {
+            x->parent->child[1] = x;
+        }
+        px->child[0] = b;
+        px->parent = x;
+    } else {
+        b = x->child[0];
+        if (b) b->parent = px;
+        x->child[0] = px;
+        x->parent = px->parent;
+        if (x->parent->child[0] == px) {
+            x->parent->child[0] = x;
+        } else {
+            x->parent->child[1] = x;
+        }
+        px->child[1] = b;
+        px->parent = x;
+    }
+}
+
+#ifdef USE_UGLY_SPLAY
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_splay (splay *x)
+#else
+static void flipper4_splay (x)
+splay *x;
+#endif
+{
+    splay *px;
+    splay *ppx;
+    splay *b, *c;
+
+    for (;;) {
+        px = x->parent;
+        if (px->mark)
+            return;
+        ppx = px->parent;
+        if (ppx->mark) {
+            if (px->reversed)
+                flipper4_reverse (px);
+            if (x->reversed)
+                flipper4_reverse (x);
+            flipper4_rotate (x, px);
+            return;
+        }
+        if (ppx->reversed)
+            flipper4_reverse (ppx);
+        if (px->reversed)
+            flipper4_reverse (px);
+        if (x->reversed)
+            flipper4_reverse (x);
+
+        x->parent = ppx->parent;
+        if (x->parent->child[0] == ppx) {
+            x->parent->child[0] = x;
+        } else {
+            x->parent->child[1] = x;
+        }
+
+        if (ppx->child[0] == px) {
+            if (px->child[0] == x) {
+                b = x->child[1];
+                c = px->child[1];
+                if (b) b->parent = px;
+                if (c) c->parent = ppx;
+                x->child[1] = px;
+                px->child[0] = b;
+                px->child[1] = ppx;
+                ppx->child[0] = c;
+                px->parent = x;
+                ppx->parent = px;
+            } else {
+                b = x->child[0];
+                c = x->child[1];
+                if (b) b->parent = px;
+                if (c) c->parent = ppx;
+                x->child[0] = px;
+                x->child[1] = ppx;
+                px->child[1] = b;
+                ppx->child[0] = c;
+                px->parent = x;
+                ppx->parent = x;
+            }
+        } else {
+            if (px->child[1] == x) {
+                b = px->child[0];
+                c = x->child[0];
+                if (b) b->parent = ppx;
+                if (c) c->parent = px;
+                x->child[0] = px;
+                px->child[0] = ppx;
+                px->child[1] = c;
+                ppx->child[1] = b;
+                px->parent = x;
+                ppx->parent = px;
+            } else {
+                b = x->child[0];
+                c = x->child[1];
+                if (b) b->parent = ppx;
+                if (c) c->parent = px;
+                x->child[0] = ppx;
+                x->child[1] = px;
+                ppx->child[1] = b;
+                px->child[0] = c;
+                px->parent = x;
+                ppx->parent = x;
+            }
+        }
+    }
+}
+
+#else /* USE_UGLY_SPLAY */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_splay (splay *x)
+#else
+static void flipper4_splay (x)
+splay *x;
+#endif
+{
+    splay *px;
+    splay *ppx;
+
+    for (;;) {
+        px = x->parent;
+        if (px->mark)
+            return;
+        ppx = px->parent;
+        if (ppx->mark) {
+            if (px->reversed)
+                flipper4_reverse (px);
+            if (x->reversed)
+                flipper4_reverse (x);
+            flipper4_rotate (x, px);
+            return;
+        }
+        if (ppx->reversed)
+            flipper4_reverse (ppx);
+        if (px->reversed)
+            flipper4_reverse (px);
+        if (x->reversed)
+            flipper4_reverse (x);
+        if (ppx->child[0] == px) {
+            if (px->child[0] == x) {
+                flipper4_rotate (px, ppx);
+                flipper4_rotate (x, px);
+            } else {
+                flipper4_rotate (x, px);
+                flipper4_rotate (x, ppx);
+            }
+        } else {
+            if (px->child[1] == x) {
+                flipper4_rotate (px, ppx);
+                flipper4_rotate (x, px);
+            } else {
+                flipper4_rotate (x, px);
+                flipper4_rotate (x, ppx);
+            }
+        }
+    }
+}
+
+#endif /* USE_UGLY_SPLAY */
+
+#ifdef NEXT_PREV_SPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[1])
+        p = p->child[1];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[r];
+        if (!pnext) break;
+        p = pnext;
+    }
+    flipper4_splay (p);
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[0]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[0])
+        p = p->child[0];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[1 - r];
+        if (!pnext) break;
+        p = pnext;
+    }
+    flipper4_splay (p);
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_SPLAY */
+
+
+#ifdef NEXT_PREV_NOSPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)      /* CClinkern_flipper_next_nspl */
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space + x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space + x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_NOSPLAY */
+
+
+#ifdef NEXT_PREV_NOSPLAY1
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)      /* CClinkern_flipper_next_nspl1 */
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[r] == p) {
+                flipper4_splay (pnext);
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (!pnext) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl1 */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[1 - r] == p) {
+                flipper4_splay (pnext);
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (!pnext) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_NOSPLAY1 */
+
+
+#ifdef NEXT_PREV_NOSPLAY2
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)      /* CClinkern_flipper_next_nospl2 */
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[1])
+        p = p->child[1];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[r];
+        if (!pnext) break;
+        p = pnext;
+    }
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nospl2 */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[0]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[0])
+        p = p->child[0];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[1 - r];
+        if (!pnext) break;
+        p = pnext;
+    }
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_NOSPLAY2 */
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *temp, *temp2;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root.child[0]->reversed ^= 1;
+        return;
+    }
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (py);
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (py->reversed)
+        flipper4_reverse (py);
+    if (px->child[1] == py) {
+#ifdef SAVE_NEIGHBORS
+        temp = px->neigh[0];
+        temp2 = py->neigh[1];
+        px->neigh[0] = px->neigh[1];
+        py->neigh[1] = py->neigh[0];
+        py->neigh[0] = temp;
+        px->neigh[1] = temp2;
+        if (temp->neigh[0] == px) temp->neigh[0] = py;
+        else temp->neigh[1] = py;
+        if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+        else temp2->neigh[1] = px;
+#endif
+        if (py->child[0])
+            py->child[0]->reversed ^= 1;
+        SWAP (px->child[0], py->child[0], temp);
+        if (px->child[0])
+            px->child[0]->parent = px;
+        if (py->child[0])
+            py->child[0]->parent = py;
+        px->child[1] = py->child[1];
+        if (px->child[1])
+            px->child[1]->parent = px;
+        py->child[1] = px;
+        px->parent = py;
+        py->parent = &root;
+        root.child[0] = py;
+    } else {
+#ifdef SAVE_NEIGHBORS
+        temp = px->neigh[0];
+        temp2 = py->neigh[1];
+        py->neigh[1] = temp;
+        px->neigh[0] = temp2;
+        if (temp->neigh[0] == px) temp->neigh[0] = py;
+        else temp->neigh[1] = py;
+        if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+        else temp2->neigh[1] = px;
+#endif
+        px->reversed ^= 1;
+        if (py->child[1])
+            py->child[1]->reversed ^= 1;
+    }
+}
+
+#ifdef SEQUENCE_SPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *pz = splay_space + z;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (py);
+    py->mark = 1;
+    flipper4_splay (pz);
+    py->mark = 0;
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (py->reversed)
+        flipper4_reverse (py);
+
+    if (pz->parent == px)
+        return px->child[0] == pz;
+    else
+        return py->child[1] == pz;
+}
+#endif /* SEQUENCE_SPLAY */
+
+#ifdef SEQUENCE_NOSPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)   /* CClinkern_flipper_sequence_nospl */
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *pz = splay_space + z;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (pz);
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (pz->reversed)
+        flipper4_reverse (pz);
+
+    for (;;) {
+        if (py->parent == px) {
+            return px->child[1] == py;
+        } else if (py->parent == pz) {
+            return pz->child[0] == py;
+        } else {
+            py = py->parent;
+        }
+    }
+}
+#endif /* SEQUENCE_NOSPLAY */
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_sequence_burst_init (int x, int z)
+#else
+void CClinkern_flipper_sequence_burst_init (x, z)
+int x, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *pz = splay_space + z;
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (pz);
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (pz->reversed)
+        flipper4_reverse (pz);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence_burst (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence_burst (x, y, z)
+int x, y, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *pz = splay_space + z;
+
+    if (y == z || y == x)
+        return 1;
+
+    for (;;) {
+        if (py->parent == px) {
+            return px->child[1] == py;
+        } else if (py->parent == pz) {
+            return pz->child[0] == py;
+        } else {
+            py = py->parent;
+        }
+    }
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_sp2.c b/contrib/blossom/concorde97/LINKERN/flip_sp2.c
new file mode 100644
index 0000000000000000000000000000000000000000..859f0d3456082645232f2de544256c8c7d095837
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_sp2.c
@@ -0,0 +1,979 @@
+/***************************************************************************/
+/*                                                                         */
+/* TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN  - Splay Trees (with dummy) */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: April 21, 1995                                                   */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   int CClinkern_flipper_sequence (int x, int y, int z)                  */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*   void CClinkern_flipper_sequence_burst_init (int x, int z)             */
+/*     initilizes the tree for a sequence of (x, y, z) sequence queries.   */
+/*   int CClinkern_flipper_sequence_burst (int x, int y, int z)            */
+/*     can be called instead of CClinkern_flipper_sequence, after a call to*/
+/*     CClinkern_flipper_sequence_burst_init (x, y), and before any flips  */
+/*     (but it requires that NEXT_PREV_NOSPLAY be defined). Does not seem  */
+/*     to improve the running time.                                        */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       Should work well on very large problems.                          */
+/*       One of NEXT_PREV_SPLAY, NEXT_PREV_NOSPLAY, NEXT_PREV_NOSPLAY1,    */
+/*   or NEXT_PREV_NOSPLAY2 must be defined. (NEXT_PREV_NOSPLAY looks like  */
+/*   the fastest.) One of SEQUENCE_SPLAY or SEQUENCE_NOSPLAY must be       */
+/*   defined. (SEQUENCE_NOSPLAY looks like the fastest - it does not splay */
+/*   the middle node in the query.)                                        */
+/*                                                                         */
+/*   If USE_UGLY_SPLAY is defined, an uglier (but perhaps faster) splay    */
+/*   step is used.                                                         */
+/*                                                                         */
+/*   If SAVE_NEIGHBORS is defined, the neighbors of each node are          */
+/*   remembered, saving some tree traversals for next and prev.            */
+/*   In this case, the neighbor is never splayed, so NEXT_PREV_SPLAY       */
+/*   and NEXT_PREV_NOSPLAY2 become equivalent, as do NEXT_PREV_NOSPLAY     */
+/*   NEXT_PREV_NOSPLAY1.                                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/* #define NEXT_PREV_SPLAY    */   /* 1xxxx */
+#define NEXT_PREV_NOSPLAY          /* 2xxxx */
+/* #define NEXT_PREV_NOSPLAY1 */   /* 3xxxx */
+/* #define NEXT_PREV_NOSPLAY2 */   /* 4xxxx */
+/* #define SEQUENCE_SPLAY     */   /* x1xxx */
+#define SEQUENCE_NOSPLAY           /* x2xxx */
+#define USE_UGLY_SPLAY             /* xx2xx */
+#define SAVE_NEIGHBORS             /* xxx2x */
+
+/***************************************************************************/
+/*                                                                         */
+/* SPLAY TREE FLIPPER (flipper4):                                          */
+/*                                                                         */
+/*     1. CClinkern_flipper_cycle and CClinkern_flipper_cycle_inverse return the number of     */
+/*        nodes.                                                           */
+/*                                                                         */
+/*     2. The basic splay implementation - uses a splay tree with one node */
+/*        per element.                                                     */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct splay {
+    struct splay *parent;
+    struct splay *child[2];
+#ifdef SAVE_NEIGHBORS
+    struct splay *neigh[2];
+#endif
+    int reversed;
+    int mark;
+    int value;
+} splay;
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    flipper4_cycle_fillin(int *x, int i, splay *p, int r);
+static void
+    flipper4_reverse (splay *p),
+    flipper4_rotate (splay *x, splay *px),
+    flipper4_splay (splay *x);
+static splay
+    *flipper4_make_tree (int a, int b, int *cyc);
+
+#else
+
+static int
+    flipper4_cycle_fillin();
+static void
+    flipper4_reverse (),
+    flipper4_rotate (),
+    flipper4_splay ();
+static splay
+    *flipper4_make_tree ();
+
+#endif
+
+static splay *splay_space = (splay *) NULL;
+static splay root;
+static splay dummy_leaf;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_reset (int ncount)
+#else
+int CClinkern_flipper_reset (ncount)
+int ncount;
+#endif
+{
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static splay *flipper4_make_tree (int a, int b, int *cyc)
+#else
+static splay *flipper4_make_tree (a, b, cyc)
+int a;
+int b;
+int *cyc;
+#endif
+{
+    splay *p;
+    int center;
+
+    if (b < a)
+        return &dummy_leaf;
+
+    center = (a + b)/2;
+    p = splay_space + cyc[center];
+    p->child[0] = flipper4_make_tree (a, center-1, cyc);
+    p->child[0]->parent = p;
+    p->child[1] = flipper4_make_tree (center+1, b, cyc);
+    p->child[1]->parent = p;
+    return p;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    root.reversed = 0;
+    root.parent = (splay *) NULL;
+    root.child[1] = &dummy_leaf;
+    root.value = ncount;
+
+    splay_space = CC_SAFE_MALLOC (ncount, splay);
+    if (!splay_space)
+        return 1;
+
+    for (i = 0; i < ncount; i++) {
+        splay_space[i].reversed = 0;
+        splay_space[i].value = i;
+        splay_space[i].mark = 0;
+#ifdef SAVE_NEIGHBORS
+        if (i==0) {
+            splay_space[cyc[0]].neigh[0] = &splay_space[cyc[ncount-1]];
+            splay_space[cyc[ncount-1]].neigh[1] = &splay_space[cyc[0]];
+        } else {
+            splay_space[cyc[i]].neigh[0] = &splay_space[cyc[i-1]];
+            splay_space[cyc[i-1]].neigh[1] = &splay_space[cyc[i]];
+        }
+#endif
+    }
+
+    root.child[0] = flipper4_make_tree (0, ncount - 1, cyc);
+    root.child[0]->parent = &root;
+    root.mark = 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int flipper4_cycle_fillin(int *x, int i, splay *p, int r)
+#else
+static int flipper4_cycle_fillin(x, i, p, r)
+int *x;
+int i;
+splay *p;
+int r;
+#endif
+{
+    if (p == &dummy_leaf)
+        return i;
+
+    r ^= p->reversed;
+    i = flipper4_cycle_fillin (x, i, p->child[r], r);
+    x[i++] = p->value;
+    i = flipper4_cycle_fillin (x, i, p->child[1 - r], r);
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    return flipper4_cycle_fillin (x, 0, root.child[0], 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (splay_space)
+        CC_FREE (splay_space, splay);
+
+    root.child[0] = (splay *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_reverse (splay *p)
+#else
+static void flipper4_reverse (p)
+splay *p;
+#endif
+{
+    splay *temp;
+
+    SWAP (p->child[0], p->child[1], temp);
+    p->child[0]->reversed ^= 1;
+    p->child[1]->reversed ^= 1;
+    p->reversed ^= 1;
+#ifdef SAVE_NEIGHBORS
+    SWAP (p->neigh[0], p->neigh[1], temp);
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_rotate (splay *x, splay *px)
+#else
+static void flipper4_rotate (x, px)
+splay *x, *px;
+#endif
+{
+    splay *b;
+
+    if (px->child[0] == x) {
+        b = x->child[1];
+        b->parent = px;
+        x->child[1] = px;
+        x->parent = px->parent;
+        if (x->parent->child[0] == px) {
+            x->parent->child[0] = x;
+        } else {
+            x->parent->child[1] = x;
+        }
+        px->child[0] = b;
+        px->parent = x;
+    } else {
+        b = x->child[0];
+        b->parent = px;
+        x->child[0] = px;
+        x->parent = px->parent;
+        if (x->parent->child[0] == px) {
+            x->parent->child[0] = x;
+        } else {
+            x->parent->child[1] = x;
+        }
+        px->child[1] = b;
+        px->parent = x;
+    }
+}
+
+#ifdef USE_UGLY_SPLAY
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_splay (splay *x)
+#else
+static void flipper4_splay (x)
+splay *x;
+#endif
+{
+    splay *px;
+    splay *ppx;
+    splay *b, *c;
+
+    for (;;) {
+        px = x->parent;
+        if (px->mark)
+            return;
+        ppx = px->parent;
+        if (ppx->mark) {
+            if (px->reversed)
+                flipper4_reverse (px);
+            if (x->reversed)
+                flipper4_reverse (x);
+            flipper4_rotate (x, px);
+            return;
+        }
+        if (ppx->reversed)
+            flipper4_reverse (ppx);
+        if (px->reversed)
+            flipper4_reverse (px);
+        if (x->reversed)
+            flipper4_reverse (x);
+
+        x->parent = ppx->parent;
+        if (x->parent->child[0] == ppx) {
+            x->parent->child[0] = x;
+        } else {
+            x->parent->child[1] = x;
+        }
+
+        if (ppx->child[0] == px) {
+            if (px->child[0] == x) {
+                b = x->child[1];
+                c = px->child[1];
+                b->parent = px;
+                c->parent = ppx;
+                x->child[1] = px;
+                px->child[0] = b;
+                px->child[1] = ppx;
+                ppx->child[0] = c;
+                px->parent = x;
+                ppx->parent = px;
+            } else {
+                b = x->child[0];
+                c = x->child[1];
+                b->parent = px;
+                c->parent = ppx;
+                x->child[0] = px;
+                x->child[1] = ppx;
+                px->child[1] = b;
+                ppx->child[0] = c;
+                px->parent = x;
+                ppx->parent = x;
+            }
+        } else {
+            if (px->child[1] == x) {
+                b = px->child[0];
+                c = x->child[0];
+                b->parent = ppx;
+                c->parent = px;
+                x->child[0] = px;
+                px->child[0] = ppx;
+                px->child[1] = c;
+                ppx->child[1] = b;
+                px->parent = x;
+                ppx->parent = px;
+            } else {
+                b = x->child[0];
+                c = x->child[1];
+                b->parent = ppx;
+                c->parent = px;
+                x->child[0] = ppx;
+                x->child[1] = px;
+                ppx->child[1] = b;
+                px->child[0] = c;
+                px->parent = x;
+                ppx->parent = x;
+            }
+        }
+    }
+}
+
+#else /* USE_UGLY_SPLAY */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void flipper4_splay (splay *x)
+#else
+static void flipper4_splay (x)
+splay *x;
+#endif
+{
+    splay *px;
+    splay *ppx;
+
+    for (;;) {
+        px = x->parent;
+        if (px->mark)
+            return;
+        ppx = px->parent;
+        if (ppx->mark) {
+            if (px->reversed)
+                flipper4_reverse (px);
+            if (x->reversed)
+                flipper4_reverse (x);
+            flipper4_rotate (x, px);
+            return;
+        }
+        if (ppx->reversed)
+            flipper4_reverse (ppx);
+        if (px->reversed)
+            flipper4_reverse (px);
+        if (x->reversed)
+            flipper4_reverse (x);
+        if (ppx->child[0] == px) {
+            if (px->child[0] == x) {
+                flipper4_rotate (px, ppx);
+                flipper4_rotate (x, px);
+            } else {
+                flipper4_rotate (x, px);
+                flipper4_rotate (x, ppx);
+            }
+        } else {
+            if (px->child[1] == x) {
+                flipper4_rotate (px, ppx);
+                flipper4_rotate (x, px);
+            } else {
+                flipper4_rotate (x, px);
+                flipper4_rotate (x, ppx);
+            }
+        }
+    }
+}
+
+#endif /* USE_UGLY_SPLAY */
+
+#ifdef NEXT_PREV_SPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[1] != &dummy_leaf)
+        p = p->child[1];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[r];
+        if (pnext == &dummy_leaf) break;
+        p = pnext;
+    }
+    flipper4_splay (p);
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[0]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[0] != &dummy_leaf)
+        p = p->child[0];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[1 - r];
+        if (pnext == &dummy_leaf) break;
+        p = pnext;
+    }
+    flipper4_splay (p);
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_SPLAY */
+
+
+#ifdef NEXT_PREV_NOSPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)      /* CClinkern_flipper_next_nspl */
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space + x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext != &dummy_leaf) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space + x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext != &dummy_leaf) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[1 - r] == p) {
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (pnext == &dummy_leaf) {
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_NOSPLAY */
+
+
+#ifdef NEXT_PREV_NOSPLAY1
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)      /* CClinkern_flipper_next_nspl1 */
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1-r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[1 - r];
+    if (pnext != &dummy_leaf) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (pnext == &dummy_leaf) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[r] == p) {
+                flipper4_splay (pnext);
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[r];
+            if (pnext == &dummy_leaf) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nspl1 */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    r = 0;
+    for (pnext = p, r = 0; !pnext->mark; pnext = pnext->parent)
+        r ^= pnext->reversed;
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[r]->value;
+#else /* SAVE_NEIGHBORS */
+    pnext = p->child[r];
+    if (pnext != &dummy_leaf) {
+        p = pnext;
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (pnext == &dummy_leaf) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    } else {
+        r ^= p->reversed; /* change */
+        pnext = p->parent;
+        while (!pnext->mark) {
+            if (pnext->child[1 - r] == p) {
+                flipper4_splay (pnext);
+                return pnext->value;
+            }
+            r ^= pnext->reversed;
+            p = pnext;
+            pnext = p->parent;
+        }
+        for (;;) {
+            r ^= p->reversed;
+            pnext = p->child[1 - r];
+            if (pnext == &dummy_leaf) {
+                flipper4_splay (p);
+                return p->value;
+            }
+            p = pnext;
+        }
+    }
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_NOSPLAY1 */
+
+
+#ifdef NEXT_PREV_NOSPLAY2
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)      /* CClinkern_flipper_next_nospl2 */
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[1]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[1] != &dummy_leaf)
+        p = p->child[1];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[r];
+        if (pnext == &dummy_leaf) break;
+        p = pnext;
+    }
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)      /* CClinkern_flipper_prev_nospl2 */
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    splay *p = splay_space+x;
+    splay *pnext;
+    int r;
+
+    flipper4_splay (p);
+    if (p->reversed)
+        flipper4_reverse (p);
+#ifdef SAVE_NEIGHBORS
+    return p->neigh[0]->value;
+#else /* SAVE_NEIGHBORS */
+    if (p->child[0] != &dummy_leaf)
+        p = p->child[0];
+    r = 0;
+    for (;;) {
+        r ^= p->reversed;
+        pnext = p->child[1 - r];
+        if (pnext == &dummy_leaf) break;
+        p = pnext;
+    }
+    return p->value;
+#endif /* SAVE_NEIGHBORS */
+}
+#endif /* NEXT_PREV_NOSPLAY2 */
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *temp, *temp2;
+
+    if (x == y) return;
+    if (xprev == ynext) {
+        root.child[0]->reversed ^= 1;
+        return;
+    }
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (py);
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (py->reversed)
+        flipper4_reverse (py);
+    if (px->child[1] == py) {
+#ifdef SAVE_NEIGHBORS
+        temp = px->neigh[0];
+        temp2 = py->neigh[1];
+        px->neigh[0] = px->neigh[1];
+        py->neigh[1] = py->neigh[0];
+        py->neigh[0] = temp;
+        px->neigh[1] = temp2;
+        if (temp->neigh[0] == px) temp->neigh[0] = py;
+        else temp->neigh[1] = py;
+        if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+        else temp2->neigh[1] = px;
+#endif
+        py->child[0]->reversed ^= 1;
+        SWAP (px->child[0], py->child[0], temp);
+        px->child[0]->parent = px;
+        py->child[0]->parent = py;
+        px->child[1] = py->child[1];
+        px->child[1]->parent = px;
+        py->child[1] = px;
+        px->parent = py;
+        py->parent = &root;
+        root.child[0] = py;
+    } else {
+#ifdef SAVE_NEIGHBORS
+        temp = px->neigh[0];
+        temp2 = py->neigh[1];
+        py->neigh[1] = temp;
+        px->neigh[0] = temp2;
+        if (temp->neigh[0] == px) temp->neigh[0] = py;
+        else temp->neigh[1] = py;
+        if (temp2->neigh[0] == py) temp2->neigh[0] = px;
+        else temp2->neigh[1] = px;
+#endif
+        px->reversed ^= 1;
+        py->child[1]->reversed ^= 1;
+    }
+}
+
+#ifdef SEQUENCE_SPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *pz = splay_space + z;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (py);
+    py->mark = 1;
+    flipper4_splay (pz);
+    py->mark = 0;
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (py->reversed)
+        flipper4_reverse (py);
+
+    if (pz->parent == px)
+        return px->child[0] == pz;
+    else
+        return py->child[1] == pz;
+}
+#endif /* SEQUENCE_SPLAY */
+
+#ifdef SEQUENCE_NOSPLAY
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)   /* CClinkern_flipper_sequence_nospl */
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *pz = splay_space + z;
+
+    if (y == z || x == z || x == y)
+        return 1;
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (pz);
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (pz->reversed)
+        flipper4_reverse (pz);
+
+    for (;;) {
+        if (py->parent == px) {
+            return px->child[1] == py;
+        } else if (py->parent == pz) {
+            return pz->child[0] == py;
+        } else {
+            py = py->parent;
+        }
+    }
+}
+#endif /* SEQUENCE_NOSPLAY */
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_sequence_burst_init (int x, int z)
+#else
+void CClinkern_flipper_sequence_burst_init (x, z)
+int x, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *pz = splay_space + z;
+
+    flipper4_splay (px);
+    px->mark = 1;
+    flipper4_splay (pz);
+    px->mark = 0;
+
+    if (px->reversed)
+        flipper4_reverse (px);
+    if (pz->reversed)
+        flipper4_reverse (pz);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence_burst (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence_burst (x, y, z)
+int x, y, z;
+#endif
+{
+    splay *px = splay_space + x;
+    splay *py = splay_space + y;
+    splay *pz = splay_space + z;
+
+    if (y == z || y == x)
+        return 1;
+
+    for (;;) {
+        if (py->parent == px) {
+            return px->child[1] == py;
+        } else if (py->parent == pz) {
+            return pz->child[0] == py;
+        } else {
+            py = py->parent;
+        }
+    }
+}
+
diff --git a/contrib/blossom/concorde97/LINKERN/flip_try.c b/contrib/blossom/concorde97/LINKERN/flip_try.c
new file mode 100644
index 0000000000000000000000000000000000000000..54c66deb4ccd53cdd220e29597a1c8355c467efc
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_try.c
@@ -0,0 +1,1241 @@
+/***************************************************************************/
+/*                                                                         */
+/*    TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - 3-Level Linked List    */
+/*                (Contains debugging information)                         */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1995                                                     */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)      */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This version should be the best of the linked lists so far.       */
+/*   It combines the oneway approach, with three levels for an express     */
+/*   lane and a superexpress lane. Note that all superexpress nodes are    */
+/*   also express nodes.                                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* LINKDED LIST FLIPPER 8  (flip_ll8.c):                                   */
+/*                                                                         */
+/*     1. Uses three levels, the top having n**(1/3) nodes.                */
+/*     2. The top level has explicit next and prevs, the other levels      */
+/*        consist of two "oneway" cycles.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define FORWARD_TOUR  0
+#define BACKWARD_TOUR 1
+
+static int test_cycle_size = 0;
+static int test_reversed = 0;
+static int test_short_size = 0;
+static int *test_flip_cyc = (int *) NULL;
+static int *test_flip_cyc_inv = (int *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    test_flipper_init (int ncount, int *cyc),
+    test_flipper_next (int x),
+    test_flipper_prev (int x),
+    test_flipper_cycle (int *x),
+    test_flipper_sequence (int x, int y, int z);
+static void
+    test_flipper_flip (int x, int y),
+    test_flipper_finish (void),
+    test_flipper_free_world (void);
+
+#else
+
+static int
+    test_flipper_init (),
+    test_flipper_next (),
+    test_flipper_prev (),
+    test_flipper_cycle (),
+    test_flipper_sequence ();
+static void
+    test_flipper_flip (),
+    test_flipper_finish (),
+    test_flipper_free_world ();
+
+#endif
+
+typedef struct oneway {
+    struct oneway *next;
+    int            name;
+    char           mark;
+    char           level;
+} oneway;
+
+typedef struct llnode {
+    struct oneway  actual_fwd;
+    struct oneway  actual_bwd;
+    struct oneway  actual_fwd_express;
+    struct oneway  actual_bwd_express;
+    struct oneway  *fwd;
+    struct oneway  *bwd;
+    struct oneway  *fwd_express;
+    struct oneway  *bwd_express;
+    struct llnode  *next_super;
+    struct llnode  *prev_super;
+} llnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    express_flip (int aprev, int a, int b, int bnext),
+    super_flip (int a, int b),
+    dump_raw_cycle (void),
+    dump_cycle (void);
+static int
+    express_flipper_sequence (int x, int y, int z),
+    find_orientation (int s);
+
+#else
+
+static void
+    express_flip (),
+    super_flip (),
+    dump_raw_cycle (),
+    dump_cycle ();
+static int
+    express_flipper_sequence (),
+    find_orientation ();
+
+#endif
+
+static llnode *lltour = (llnode *) NULL;
+static int cycle_size = 0;
+static int reversed = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j;
+    int groupsize, supergroupsize;
+
+    if (test_flipper_init (ncount, cyc)) {
+        printf ("the test code failed\n");
+        fflush (stdout);
+        return 1;
+    }
+
+    cycle_size = ncount;
+    reversed = 0;
+
+    lltour = CC_SAFE_MALLOC (ncount, llnode);
+    if (!lltour)
+        return 1;
+
+    lltour[cyc[0]].actual_fwd.name = cyc[0];
+    lltour[cyc[0]].actual_fwd.mark = 0;
+    lltour[cyc[0]].actual_fwd.level = 0;
+    lltour[cyc[0]].actual_fwd.next = &(lltour[cyc[1]].actual_fwd);
+    lltour[cyc[0]].fwd = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[0]].actual_bwd.name = cyc[0];
+    lltour[cyc[0]].actual_bwd.mark = 0;
+    lltour[cyc[0]].actual_bwd.level = 0;
+    lltour[cyc[0]].actual_bwd.next = &(lltour[cyc[ncount - 1]].actual_bwd);
+    lltour[cyc[0]].bwd = &(lltour[cyc[0]].actual_bwd);
+    lltour[cyc[ncount - 1]].actual_fwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_fwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_fwd.next = &(lltour[cyc[0]].actual_fwd);
+    lltour[cyc[ncount - 1]].fwd = &(lltour[cyc[ncount - 1]].actual_fwd);
+    lltour[cyc[ncount - 1]].actual_bwd.name = cyc[ncount - 1];
+    lltour[cyc[ncount - 1]].actual_bwd.mark = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.level = 0;
+    lltour[cyc[ncount - 1]].actual_bwd.next =
+                        &(lltour[cyc[ncount - 2]].actual_bwd);
+    lltour[cyc[ncount - 1]].bwd = &(lltour[cyc[ncount - 1]].actual_bwd);
+
+
+    for (i = ncount - 2; i; i--) {
+        lltour[cyc[i]].actual_fwd.name = cyc[i];
+        lltour[cyc[i]].actual_fwd.mark = 0;
+        lltour[cyc[i]].actual_fwd.level = 0;
+        lltour[cyc[i]].actual_fwd.next = &(lltour[cyc[i + 1]].actual_fwd);
+        lltour[cyc[i]].fwd = &(lltour[cyc[i]].actual_fwd);
+        lltour[cyc[i]].actual_bwd.name = cyc[i];
+        lltour[cyc[i]].actual_bwd.mark = 0;
+        lltour[cyc[i]].actual_bwd.level = 0;
+        lltour[cyc[i]].actual_bwd.next = &(lltour[cyc[i - 1]].actual_bwd);
+        lltour[cyc[i]].bwd = &(lltour[cyc[i]].actual_bwd);
+    }
+
+    groupsize = (int) cbrt ((double) ncount);
+    supergroupsize = groupsize * groupsize;
+    printf ("groupsize = %d  supersize = %d\n", groupsize, supergroupsize);
+    fflush (stdout);
+    lltour[cyc[0]].actual_fwd.level = 1;
+    lltour[cyc[0]].actual_bwd.level = 1;
+    lltour[cyc[0]].fwd_express = &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[0]].bwd_express = &(lltour[cyc[0]].actual_bwd_express);
+    lltour[cyc[0]].actual_fwd_express.mark = 0;
+    lltour[cyc[0]].actual_bwd_express.mark = 0;
+    lltour[cyc[0]].actual_fwd_express.level = 1;
+    lltour[cyc[0]].actual_bwd_express.level = 1;
+    lltour[cyc[0]].actual_fwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_bwd_express.name = cyc[0];
+    lltour[cyc[0]].actual_fwd_express.next =
+                          &(lltour[cyc[groupsize]].actual_fwd_express);
+    i = groupsize;
+    j = ncount - groupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 1;
+        lltour[cyc[i]].actual_bwd.level = 1;
+        lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+        lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+        lltour[cyc[i]].actual_fwd_express.mark = 0;
+        lltour[cyc[i]].actual_bwd_express.mark = 0;
+        lltour[cyc[i]].actual_fwd_express.level = 1;
+        lltour[cyc[i]].actual_bwd_express.level = 1;
+        lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+        lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[i + groupsize]].actual_fwd_express);
+        lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+        i += groupsize;
+    }
+
+    lltour[cyc[i]].actual_fwd.level = 1;
+    lltour[cyc[i]].actual_bwd.level = 1;
+    lltour[cyc[i]].fwd_express = &(lltour[cyc[i]].actual_fwd_express);
+    lltour[cyc[i]].bwd_express = &(lltour[cyc[i]].actual_bwd_express);
+    lltour[cyc[i]].actual_fwd_express.mark = 0;
+    lltour[cyc[i]].actual_bwd_express.mark = 0;
+    lltour[cyc[i]].actual_fwd_express.level = 1;
+    lltour[cyc[i]].actual_bwd_express.level = 1;
+    lltour[cyc[i]].actual_fwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_bwd_express.name = cyc[i];
+    lltour[cyc[i]].actual_fwd_express.next =
+                          &(lltour[cyc[0]].actual_fwd_express);
+    lltour[cyc[i]].actual_bwd_express.next =
+                          &(lltour[cyc[i - groupsize]].actual_bwd_express);
+    lltour[cyc[0]].actual_bwd_express.next =
+                          &(lltour[cyc[i]].actual_bwd_express);
+
+    lltour[cyc[0]].actual_fwd.level = 2;
+    lltour[cyc[0]].actual_bwd.level = 2;
+    lltour[cyc[0]].actual_fwd_express.level = 2;
+    lltour[cyc[0]].actual_bwd_express.level = 2;
+    lltour[cyc[0]].next_super = &(lltour[cyc[supergroupsize]]);
+    i = supergroupsize;
+    j = ncount - supergroupsize;
+    while (i < j) {
+        lltour[cyc[i]].actual_fwd.level = 2;
+        lltour[cyc[i]].actual_bwd.level = 2;
+        lltour[cyc[i]].actual_fwd_express.level = 2;
+        lltour[cyc[i]].actual_bwd_express.level = 2;
+        lltour[cyc[i]].prev_super = &(lltour[cyc[i - supergroupsize]]);
+        lltour[cyc[i]].next_super = &(lltour[cyc[i + supergroupsize]]);
+        i += supergroupsize;
+    }
+    lltour[cyc[i]].actual_fwd.level = 2;
+    lltour[cyc[i]].actual_bwd.level = 2;
+    lltour[cyc[i]].actual_fwd_express.level = 2;
+    lltour[cyc[i]].actual_bwd_express.level = 2;
+    lltour[cyc[i]].next_super = &(lltour[cyc[0]]);
+    lltour[cyc[i]].prev_super = &(lltour[cyc[i - supergroupsize]]);
+    lltour[cyc[0]].prev_super = &(lltour[cyc[i]]);
+
+/*
+    dump_raw_cycle ();
+    dump_cycle ();
+*/
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_cycle (void)
+#else
+static void dump_cycle ()
+#endif
+{
+    int *getit, i;
+
+    printf ("dump_cycle ...\n"); fflush (stdout);
+
+    getit = CC_SAFE_MALLOC (cycle_size, int);
+    CClinkern_flipper_cycle (getit);
+
+    printf ("TOUR: ");
+    fflush (stdout);
+
+    for (i = 0; i < cycle_size; i++)
+        printf ("%2d ", getit[i]);
+    printf ("\n");
+    fflush (stdout);
+
+    {
+        oneway *p, *start;
+
+        printf ("Express TOUR: ");
+        fflush (stdout);
+        p = (find_orientation (getit[0]) ? lltour[getit[0]].bwd :
+                                           lltour[getit[0]].fwd);
+        while (!p->level)
+            p = p->next;
+        if (p == lltour[p->name].fwd)
+            p = lltour[p->name].fwd_express;
+        else
+            p = lltour[p->name].bwd_express;
+
+        i = 0;
+        start = p;
+        do {
+            printf ("%d ", p->name);
+            p = p->next;
+            i++;
+        } while (p != start && i < 2 * cycle_size);
+        printf ("\n");
+        fflush (stdout);
+    }
+
+    {
+        llnode *n, *start;
+        oneway *p;
+
+        printf ("SUPER TOUR: ");
+        fflush (stdout);
+        p = (find_orientation (getit[0]) ? lltour[getit[0]].bwd :
+                                           lltour[getit[0]].fwd);
+        while (!p->level)
+            p = p->next;
+        p = lltour[p->name].fwd_express;
+        while (p->level != 2)
+            p = p->next;
+
+        n = start = &(lltour[p->name]);
+        if (reversed) {
+            do {
+                printf ("%d ", n->fwd->name);
+                n = n->prev_super;
+            } while (n != start);
+
+        } else {
+            do {
+                printf ("%d ", n->fwd->name);
+                n = n->next_super;
+            } while (n != start);
+        }
+        printf ("\n");
+        fflush (stdout);
+    }
+
+    CC_FREE (getit, int);
+
+    printf ("Next-Prev test ... "); fflush (stdout);
+    for (i = 0; i < cycle_size; i++) {
+        CClinkern_flipper_prev (i);
+        CClinkern_flipper_next (i);
+    }
+    printf ("OK\n"); fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_orientation (int s)
+#else
+static int find_orientation (s)
+int s;
+#endif
+{
+    /* Returns 0 if next is fwd and 1 if next is bwd */
+
+    oneway *n = lltour[s].fwd;
+
+    while (!n->level)
+        n = n->next;
+
+    if (lltour[n->name].fwd == n)
+        n = lltour[n->name].fwd_express;
+    else
+        n = lltour[n->name].bwd_express;
+
+    while (n->level != 2)
+        n = n->next;
+
+    if (reversed)
+        return (n != lltour[n->name].bwd_express);
+    else
+        return (n != lltour[n->name].fwd_express);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    int *xtest;
+    oneway *start, *n;
+    int k = 0;
+
+    xtest = CC_SAFE_MALLOC (cycle_size, int);
+    test_flipper_cycle (xtest);
+
+    start = (find_orientation (xtest[0]) ? lltour[xtest[0]].bwd :
+                                           lltour[xtest[0]].fwd);
+    n = start;
+    do {
+        x[k++] = n->name;
+        n = n->next;
+    } while (n != start);
+
+#ifndef NDEBUG
+    for (k = 0; k < cycle_size; k++) {
+        assert (x[k] == xtest[k]);
+    }
+#endif
+
+    CC_FREE (xtest, int);
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (lltour)
+        CC_FREE (lltour, llnode);
+
+    test_flipper_finish ();
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    test_flipper_free_world ();
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    int temp;
+
+    if (find_orientation (x))
+        temp = lltour[x].bwd->next->name;
+    else
+        temp = lltour[x].fwd->next->name;
+
+    assert (temp == test_flipper_next (x));
+
+    return temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    int temp;
+
+    if (find_orientation (x))
+        temp = lltour[x].fwd->next->name;
+    else
+        temp = lltour[x].bwd->next->name;
+
+    assert (temp == test_flipper_prev (x));
+
+    return temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int xprev, int x, int y, int ynext)
+#else
+void CClinkern_flipper_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *oprev, *pnext;
+
+/*
+    printf ("flipper_flip (%d, %d, %d, %d)\n",  xprev, x, y, ynext);
+    fflush (stdout);
+*/
+
+    assert (xprev == CClinkern_flipper_prev (x));
+    assert (ynext == CClinkern_flipper_next (y));
+
+    if (x == y)
+        return;
+
+    if (lltour[x].bwd->next->name == xprev)
+        o = lltour[x].fwd;
+    else
+        o = lltour[x].bwd;
+
+    while (!o->level && o->name != y)
+        o = o->next;
+
+    if (o->level) {
+        if (lltour[o->name].fwd == o)
+            oprev = lltour[o->name].bwd->next;
+        else
+            oprev = lltour[o->name].fwd->next;
+        while (!oprev->level)
+            oprev = oprev->next;
+        if (lltour[y].fwd->next->name == ynext)
+            p = lltour[y].bwd;
+        else
+            p = lltour[y].fwd;
+        while (!p->level)
+            p = p->next;
+        if (lltour[p->name].fwd == p)
+            pnext = lltour[p->name].bwd->next;
+        else
+            pnext = lltour[p->name].fwd->next;
+        while (!pnext->level)
+            pnext = pnext->next;
+        express_flip (oprev->name, o->name, p->name, pnext->name);
+    }
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd->next->name == y) {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].bwd;
+                lltour[ynext].fwd->next = lltour[x].fwd;
+            }
+        } else {
+            if (lltour[x].fwd->next->name == xprev) {
+                lltour[x].fwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].bwd;
+            } else {
+                lltour[x].bwd->next = lltour[ynext].fwd;
+                lltour[ynext].bwd->next = lltour[x].fwd;
+            }
+        }
+
+        if (lltour[xprev].fwd->next->name == x) {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].bwd;
+                lltour[xprev].fwd->next = lltour[y].fwd;
+            }
+        } else {
+            if (lltour[y].fwd->next->name == ynext) {
+                lltour[y].fwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].bwd;
+            } else {
+                lltour[y].bwd->next = lltour[xprev].fwd;
+                lltour[xprev].bwd->next = lltour[y].fwd;
+            }
+        }
+    } else if (x != ynext) {
+        oneway *otemp;
+        if (lltour[xprev].fwd->level) {
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+    }
+
+    test_flipper_flip (x, y);
+
+/*
+    dump_raw_cycle ();
+    dump_cycle ();
+*/
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_raw_cycle (void)
+#else
+static void dump_raw_cycle ()
+#endif
+{
+    int i;
+
+    printf ("Raw Cycle:\n");
+    for (i = 0; i < cycle_size; i++) {
+        printf ("Node %d: %d%c %d%c [%d] ", lltour[i].fwd->name,
+              lltour[i].fwd->next->name,
+              (lltour[i].fwd->next ==
+               lltour[lltour[i].fwd->next->name].fwd ? 'F' : 'B'),
+              lltour[i].bwd->next->name,
+              (lltour[i].bwd->next ==
+               lltour[lltour[i].bwd->next->name].fwd ? 'F' : 'B'),
+              (int) lltour[i].fwd->level);
+        if (lltour[i].fwd->level)
+            printf ("X-fwd: %d%c   X->bwd: %d%c  ",
+              lltour[i].fwd_express->next->name,
+              (lltour[i].fwd_express->next ==
+               lltour[lltour[i].fwd_express->next->name].fwd ? 'F' : 'B'),
+              lltour[i].bwd_express->next->name,
+              (lltour[i].bwd_express->next ==
+               lltour[lltour[i].bwd_express->next->name].fwd ? 'F' : 'B'));
+        if (lltour[i].fwd->level == 2)
+            printf ("S-next: %d   S->prev: %d\n",
+                    lltour[i].next_super->fwd->name,
+                    lltour[i].prev_super->fwd->name);
+        else
+            printf ("\n");
+        fflush (stdout);
+    }
+    if (reversed)
+        printf ("REVERSED\n");
+    fflush (stdout);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void express_flip (int xprev, int x, int y, int ynext)
+#else
+static void express_flip (xprev, x, y, ynext)
+int xprev, x, y, ynext;
+#endif
+{
+    oneway *o, *p, *otemp;
+
+/*
+    printf ("express_flip (%d, %d, %d, %d)\n",  xprev, x, y, ynext);
+    printf ("really (%d, %d, %d, %d)\n",  lltour[xprev].bwd_express->name,
+                                          lltour[x].bwd_express->name,
+                                          lltour[y].bwd_express->name,
+                                          lltour[ynext].bwd_express->name);
+    fflush (stdout);
+*/
+
+
+    if (x == y) {
+        SWAP (lltour[x].fwd, lltour[x].bwd, otemp);
+        return;
+    } else if (xprev == ynext) {
+        SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        reversed ^= 1;
+        return;
+    }
+
+    if (lltour[x].bwd_express->next->name == xprev) {
+        o = lltour[x].fwd_express;
+    } else {
+        o = lltour[x].bwd_express;
+    }
+
+    while (o->level != 2 && o->name != y)
+        o = o->next;
+
+    if (o->level == 2) {
+        if (lltour[y].fwd_express->next->name == ynext)
+            p = lltour[y].bwd_express;
+        else
+            p = lltour[y].fwd_express;
+        while (p->level != 2)
+            p = p->next;
+        super_flip (o->name, p->name);
+    }
+
+
+    if (x != ynext && xprev != ynext) {
+        if (lltour[ynext].fwd_express->next->name == y) {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].bwd_express;
+                lltour[ynext].fwd_express->next = lltour[x].fwd_express;
+            }
+        } else {
+            if (lltour[x].fwd_express->next->name == xprev) {
+                lltour[x].fwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].bwd_express;
+            } else {
+                lltour[x].bwd_express->next = lltour[ynext].fwd_express;
+                lltour[ynext].bwd_express->next = lltour[x].fwd_express;
+            }
+        }
+
+        if (lltour[xprev].fwd_express->next->name == x) {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].bwd_express;
+                lltour[xprev].fwd_express->next = lltour[y].fwd_express;
+            }
+        } else {
+            if (lltour[y].fwd_express->next->name == ynext) {
+                lltour[y].fwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].bwd_express;
+            } else {
+                lltour[y].bwd_express->next = lltour[xprev].fwd_express;
+                lltour[xprev].bwd_express->next = lltour[y].fwd_express;
+            }
+        }
+    } else if (x != ynext) {
+        printf ("Here we are\n"); fflush (stdout);
+        if (lltour[xprev].fwd_express->level != 2)
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+/*
+        if (lltour[xprev].fwd_express->level == 2) {
+            SWAP (lltour[xprev].fwd_express, lltour[xprev].bwd_express, otemp);
+            SWAP (lltour[xprev].fwd, lltour[xprev].bwd, otemp);
+        }
+*/
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void super_flip (int ix, int iy)
+#else
+static void super_flip (ix, iy)
+int ix, iy;
+#endif
+{
+    llnode *x = &(lltour[ix]);
+    llnode *y = &(lltour[iy]);
+    llnode *xprev, *ynext;
+    llnode *n, *next, *prev;
+    oneway *otemp;
+
+/*
+    printf ("super_flip (%d, %d) ...\n", ix, iy);
+    fflush (stdout);
+*/
+
+    if (x == y) {
+        SWAP (x->fwd_express, x->bwd_express, otemp);
+        SWAP (x->fwd, x->bwd, otemp);
+        return;
+    }
+
+    if (reversed) {
+        xprev = x->next_super;
+        ynext = y->prev_super;
+
+        next = x->prev_super;
+        prev = xprev->next_super;
+
+        while (next != y && prev != ynext) {
+            next = next->prev_super;
+            prev = prev->next_super;
+        }
+
+        if (next == y) {
+            next = x->prev_super;
+            x->prev_super = x->next_super;
+            x->next_super = next;
+            SWAP (x->fwd_express, x->bwd_express, otemp);
+            SWAP (x->fwd, x->bwd, otemp);
+
+            do {
+                n = next;
+                next = n->prev_super;
+                n->prev_super = n->next_super;
+                n->next_super = next;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != y);
+
+            if (xprev != y) {
+                y->next_super = xprev;
+                x->prev_super = ynext;
+                xprev->prev_super = y;
+                ynext->next_super = x;
+            }
+        } else {
+            prev = xprev->next_super;
+            xprev->next_super = xprev->prev_super;
+            xprev->prev_super = prev;
+            SWAP (xprev->fwd_express, xprev->bwd_express, otemp);
+            SWAP (xprev->fwd, xprev->bwd, otemp);
+
+            do {
+                n = prev;
+                prev = n->next_super;
+                n->next_super = n->prev_super;
+                n->prev_super = prev;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != ynext);
+
+            if (xprev != y) {
+                y->prev_super = xprev;
+                x->next_super = ynext;
+                xprev->next_super = y;
+                ynext->prev_super = x;
+            }
+            reversed = 0;
+        }
+    } else {
+        xprev = x->prev_super;
+        ynext = y->next_super;
+
+        next = x->next_super;
+        prev = xprev->prev_super;
+
+        while (next != y && prev != ynext) {
+            next = next->next_super;
+            prev = prev->prev_super;
+        }
+
+        if (next == y) {
+            next = x->next_super;
+            x->next_super = x->prev_super;
+            x->prev_super = next;
+            SWAP (x->fwd_express, x->bwd_express, otemp);
+            SWAP (x->fwd, x->bwd, otemp);
+
+            do {
+                n = next;
+                next = n->next_super;
+                n->next_super = n->prev_super;
+                n->prev_super = next;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != y);
+
+            if (xprev != y) {
+                y->prev_super = xprev;
+                x->next_super = ynext;
+                xprev->next_super = y;
+                ynext->prev_super = x;
+            }
+        } else {
+            prev = xprev->prev_super;
+            xprev->prev_super = xprev->next_super;
+            xprev->next_super = prev;
+            SWAP (xprev->fwd_express, xprev->bwd_express, otemp);
+            SWAP (xprev->fwd, xprev->bwd, otemp);
+
+            do {
+                n = prev;
+                prev = n->prev_super;
+                n->prev_super = n->next_super;
+                n->next_super = prev;
+                SWAP (n->fwd_express, n->bwd_express, otemp);
+                SWAP (n->fwd, n->bwd, otemp);
+            } while (n != ynext);
+
+            if (xprev != y) {
+                y->next_super = xprev;
+                x->prev_super = ynext;
+                xprev->prev_super = y;
+                ynext->next_super = x;
+            }
+            reversed = 1;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    int control, temp;
+    oneway *next, *prev;
+    int war = 0;
+
+    if (x == z || x == y) {
+        temp = 1;
+    } else {
+
+        {
+            oneway *px, *py, *pz;
+
+            if (find_orientation (x))
+                px = lltour[x].bwd;
+            else
+                px = lltour[x].fwd;
+            while (!px->level && px->name != y && px->name != z)
+                px = px->next;
+            if (px->name == y) {
+                temp = 1;
+                war = 1;
+                goto GET_OUT;
+            } else if (px->name == z) {
+                temp = 0;
+                war = 2;
+                goto GET_OUT;
+            }
+
+            if (find_orientation (z))
+                pz = lltour[z].fwd;
+            else
+                pz = lltour[z].bwd;
+            while (!pz->level && pz->name != x && pz->name != y)
+                pz = pz->next;
+            if (pz->name == y) {
+                temp = 1;
+                war = 3;
+                goto GET_OUT;
+            } else if (pz->name == x) {
+                temp = 0;
+                war = 4;
+                goto GET_OUT;
+            } else if (px == pz) {
+                temp = 0;
+                war = 5;
+                goto GET_OUT;
+            }
+
+            if (find_orientation (y))
+                py = lltour[y].bwd;
+            else
+                py = lltour[y].fwd;
+            while (!py->level && py->name != x && py->name != z)
+                py = py->next;
+            if (py->name == z) {
+                temp = 1;
+                war = 6;
+                goto GET_OUT;
+            } else if (py->name == x) {
+                temp = 0;
+                war = 7;
+                goto GET_OUT;
+            } else if (py == pz) {
+                temp = 1;
+                war = 8;
+                goto GET_OUT;
+            } else if (py == px) {
+                temp = 0;
+                war = 9;
+                goto GET_OUT;
+            } else {
+                temp = express_flipper_sequence (px->name, py->name, pz->name);
+                war = 10;
+                goto GET_OUT;
+            }
+        }
+    }
+
+
+/*
+        lltour[y].fwd->mark = 1;
+        lltour[y].bwd->mark = 1;
+        lltour[z].fwd->mark = 1;
+        lltour[z].bwd->mark = 1;
+
+        if (find_orientation (x)) {
+            next = lltour[x].bwd;
+            prev = lltour[x].fwd;
+        } else {
+            next = lltour[x].fwd;
+            prev = lltour[x].bwd;
+        }
+
+        while (!next->mark && !prev->mark) {
+            next = next->next;
+            prev = prev->next;
+        }
+
+        if (next->mark) {
+            lltour[y].fwd->mark = 0;
+            lltour[y].bwd->mark = 0;
+            lltour[z].fwd->mark = 0;
+            lltour[z].bwd->mark = 0;
+            temp = (next->name == y);
+        } else {
+            lltour[y].fwd->mark = 0;
+            lltour[y].bwd->mark = 0;
+            lltour[z].fwd->mark = 0;
+            lltour[z].bwd->mark = 0;
+            temp = (prev->name == z);
+        }
+    }
+*/
+
+GET_OUT:
+
+    assert (temp == test_flipper_sequence (x, y, z));
+    return temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int express_flipper_sequence (int x, int y, int z)
+#else
+static int express_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    oneway *next, *prev;
+
+    lltour[y].fwd_express->mark = 1;
+    lltour[y].bwd_express->mark = 1;
+    lltour[z].fwd_express->mark = 1;
+    lltour[z].bwd_express->mark = 1;
+
+    if (find_orientation (x)) {
+        next = lltour[x].bwd_express;
+        prev = lltour[x].fwd_express;
+    } else {
+        next = lltour[x].fwd_express;
+        prev = lltour[x].bwd_express;
+    }
+
+    while (!next->mark && !prev->mark) {
+        next = next->next;
+        prev = prev->next;
+    }
+
+    if (next->mark) {
+        lltour[y].fwd_express->mark = 0;
+        lltour[y].bwd_express->mark = 0;
+        lltour[z].fwd_express->mark = 0;
+        lltour[z].bwd_express->mark = 0;
+        return (next->name == y);
+    } else {
+        lltour[y].fwd_express->mark = 0;
+        lltour[y].bwd_express->mark = 0;
+        lltour[z].fwd_express->mark = 0;
+        lltour[z].bwd_express->mark = 0;
+        return (prev->name == z);
+    }
+}
+
+
+/************* TEST CODE **************/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_flipper_init (int ncount, int *cyc)
+#else
+static int test_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+
+    test_flip_cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!test_flip_cyc)
+        return 1;
+    test_flip_cyc_inv = CC_SAFE_MALLOC (ncount, int);
+    if (!test_flip_cyc_inv) {
+        CC_FREE (cyc, int);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        test_flip_cyc[i] = cyc[i];
+        test_flip_cyc_inv[cyc[i]] = i;
+    }
+    test_cycle_size = ncount;
+    test_short_size = ncount/2;
+    test_reversed = 0;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_flipper_cycle (int *x)
+#else
+static int test_flipper_cycle (x)
+int *x;
+#endif
+{
+    int *p;
+
+    if (test_reversed) {
+        p = test_flip_cyc + test_cycle_size;
+        while (p > test_flip_cyc) {
+            *x++ = *--p;
+        }
+    } else {
+        p = test_flip_cyc + test_cycle_size;
+        x += test_cycle_size;
+        while (p > test_flip_cyc) {
+            *--x = *--p;
+        }
+    }
+    return test_cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void test_flipper_finish (void)
+#else
+static void test_flipper_finish ()
+#endif
+{
+    if (test_flip_cyc)
+        CC_FREE (test_flip_cyc, int);
+    if (test_flip_cyc_inv)
+        CC_FREE (test_flip_cyc_inv, int);
+    test_cycle_size = 0;
+    test_short_size = 0;
+    test_reversed = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void test_flipper_free_world (void)
+#else
+static void test_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_flipper_next (int x)
+#else
+static int test_flipper_next (x)
+int x;
+#endif
+{
+    int y;
+
+    if (test_reversed) {
+        y = test_flip_cyc_inv[x] - 1;
+        return (y >= 0) ? test_flip_cyc[y] : test_flip_cyc[test_cycle_size-1];
+    } else {
+        y = test_flip_cyc_inv[x] + 1;
+        return (y < test_cycle_size) ? test_flip_cyc[y] : test_flip_cyc[0];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_flipper_prev (int x)
+#else
+static int test_flipper_prev (x)
+int x;
+#endif
+{
+    int y;
+
+    if (test_reversed) {
+        y = test_flip_cyc_inv[x] + 1;
+        return (y < test_cycle_size) ? test_flip_cyc[y] : test_flip_cyc[0];
+    } else {
+        y = test_flip_cyc_inv[x] - 1;
+        return (y >= 0) ? test_flip_cyc[y] : test_flip_cyc[test_cycle_size-1];
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void test_flipper_flip (int x, int y)
+#else
+static void test_flipper_flip (x, y)
+int x,y;
+#endif
+{
+    int xloc = test_flip_cyc_inv[x];
+    int yloc = test_flip_cyc_inv[y];
+    int temp;
+    int gap;
+
+    if (test_reversed) {
+        SWAP (xloc, yloc, temp);
+    }
+    gap = yloc - xloc;
+    if (gap < 0) gap += test_cycle_size;
+    if (gap > test_short_size) {
+        SWAP (xloc, yloc, temp);
+        test_reversed ^= 1;
+        xloc++;
+        if (xloc >= test_cycle_size)
+            xloc = 0;
+        yloc--;
+        if (yloc < 0)
+            yloc = test_cycle_size - 1;
+        gap = test_cycle_size - gap - 2;
+    }
+    if (xloc > yloc) {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = test_flip_cyc[xloc];
+            y = test_flip_cyc[yloc];
+            test_flip_cyc[xloc] = y;
+            test_flip_cyc[yloc] = x;
+            test_flip_cyc_inv[x] = yloc--;
+            test_flip_cyc_inv[y] = xloc++;
+            if (xloc >= test_cycle_size)
+                xloc = 0;
+            if (yloc < 0)
+                yloc = test_cycle_size - 1;
+        }
+    } else {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = test_flip_cyc[xloc];
+            y = test_flip_cyc[yloc];
+            test_flip_cyc[xloc] = y;
+            test_flip_cyc[yloc] = x;
+            test_flip_cyc_inv[x] = yloc--;
+            test_flip_cyc_inv[y] = xloc++;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_flipper_sequence (int x, int y, int z)
+#else
+static int test_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    int xloc = test_flip_cyc_inv[x];
+    int yloc = test_flip_cyc_inv[y];
+    int zloc = test_flip_cyc_inv[z];
+
+    if (test_reversed) {
+        if (xloc >= yloc)
+            return yloc >= zloc || zloc >= xloc;
+        else
+            return yloc >= zloc && zloc >= xloc;
+    } else {
+        if (xloc <= yloc)
+            return yloc <= zloc || zloc <= xloc;
+        else
+            return yloc <= zloc && zloc <= xloc;
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_tw2.c b/contrib/blossom/concorde97/LINKERN/flip_tw2.c
new file mode 100644
index 0000000000000000000000000000000000000000..236a3eadd1591167944fbbcdde6c29a42a7d8dd0
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_tw2.c
@@ -0,0 +1,775 @@
+/***************************************************************************/
+/*                                                                         */
+/*      TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Two-level Tree       */
+/*                                                  - array for parent cyc */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 2, 1995                                                      */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int x, int y)                            */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This is desribed in the paper "Data structures for traveling      */
+/*   salesman" by Fredman, Johnson, McGeoch, and Ostheimer.                */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* TWO-LEVEL TREES:                                                        */
+/*                                                                         */
+/*     1. Uses the "groupsize" approach described in the paper.            */
+/*                                                                         */
+/***************************************************************************/
+
+#define USE_SEGMENT_SPLIT
+#define GROUPSIZE_FACTOR 0.50
+#define SEGMENT_SPLIT_CUTOFF 0.35
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+typedef struct parentnode {
+    struct childnode  *ends[2];
+    int                size;
+    int                rev;
+    int                index;
+} parentnode;
+
+typedef struct childnode {
+    struct parentnode *parent;
+    struct childnode  *adj[2];
+    int                id;
+    int                name;
+} childnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    same_segment_flip (childnode *a, childnode *b),
+    consecutive_segment_flip (parentnode *a, parentnode *b),
+    segment_split (parentnode *p, childnode *aprev, childnode *a,
+                   int left_or_right),
+    parflip (parentnode *a, parentnode *b);
+
+static int
+    parsegsize (parentnode *a, parentnode *b);
+
+static parentnode
+   *parnext (parentnode *x),
+   *parprev (parentnode *x);
+
+#else
+
+static void
+    same_segment_flip (),
+    consecutive_segment_flip (),
+    segment_split (),
+    parflip ();
+
+static int
+    parsegsize (parentnode *a, parentnode *b);
+
+static parentnode
+   *parnext (),
+   *parprev ();
+
+#endif
+
+static parentnode *parents = (parentnode *) NULL;
+static childnode *children = (childnode *) NULL;
+static int *par_cyc = (int *) NULL;
+static int *par_cyc_inv = (int *) NULL;
+static int reversed = 0;
+static cycle_size = 0;
+static int nsegments = 0;
+static groupsize = 100;
+#ifdef USE_SEGMENT_SPLIT
+static int split_cutoff = 100;
+#endif
+
+#define SAME_SEGMENT(a, b)                                                  \
+     (a->parent == b->parent &&                                             \
+      ((!(reversed^(a->parent->rev)) && a->id <= b->id) ||                  \
+       ((reversed^(a->parent->rev)) && a->id >= b->id)))
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j, cind, remain;
+    childnode *c, *cprev, *cnext;
+    parentnode *p;
+
+    reversed = 0;
+    cycle_size = ncount;
+    groupsize = (int) (sqrt ((double) ncount) * GROUPSIZE_FACTOR);
+    nsegments =  (ncount + groupsize - 1) / groupsize;
+#ifdef USE_SEGMENT_SPLIT
+    split_cutoff = groupsize * SEGMENT_SPLIT_CUTOFF;
+#endif
+
+    parents = CC_SAFE_MALLOC (nsegments, parentnode);
+    if (!parents)
+        return 1;
+
+    children = CC_SAFE_MALLOC (ncount + 1, childnode);
+                 /* The +1 will stop a purify burp later */
+    if (!children) {
+        CC_FREE (parents, parentnode);
+        return 1;
+    }
+
+    par_cyc = CC_SAFE_MALLOC (nsegments, int);
+    if (!par_cyc) {
+        CC_FREE (parents, parentnode);
+        CC_FREE (children, childnode);
+        return 1;
+    }
+    par_cyc_inv = CC_SAFE_MALLOC (nsegments, int);
+    if (!par_cyc_inv) {
+        CC_FREE (parents, parentnode);
+        CC_FREE (children, childnode);
+        CC_FREE (par_cyc, int);
+        return 1;
+    }
+
+    remain = ncount;
+    i = 0;
+    j = 2 * groupsize;
+    while (remain >= j) {
+        parents[i].size = groupsize;
+        remain -= groupsize;
+        i++;
+    }
+    if (remain > groupsize) {
+        parents[i].size = remain / 2;
+        remain -= (remain / 2);
+        i++;
+    }
+    parents[i].size = remain;
+    i++;
+
+    if (i != nsegments) {
+        printf ("seg count is wrong\n");
+        fflush (stdout);
+        CC_FREE (parents, parentnode);
+        CC_FREE (children, childnode);
+        CC_FREE (par_cyc, int);
+        CC_FREE (par_cyc_inv, int);
+        return 1;
+    }
+
+    c = (childnode *) NULL;
+    cnext = &(children[cyc[0]]);
+    for (i = 0, p = parents, c = children, cind = 0; i < nsegments; p++, i++) {
+        par_cyc[i] = i;
+        par_cyc_inv[i] = i;
+        p->index = i;
+        p->rev = 0;
+        p->ends[0] = cnext;
+        for (j = p->size; j > 0; j--) {
+            cprev = c;
+            c = cnext;
+            cnext = &(children[cyc[cind + 1]]);
+            c->id = cind;
+            c->name = cyc[cind];
+            c->parent = p;
+            c->adj[0] = cprev;
+            c->adj[1] = cnext;
+            cind++;
+        }
+        p->ends[1] = c;
+    }
+    children[cyc[0]].adj[0] = &(children[cyc[ncount - 1]]);
+    children[cyc[ncount - 1]].adj[1] = &(children[cyc[0]]);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    childnode *c, *start;
+    int k = 0;
+
+    start = &(children[0]);
+    c = start->adj[!(reversed^(start->parent->rev))];
+
+    x[k++] = start->name;
+    while (c != start) {
+        x[k++] = c->name;
+        c = c->adj[!(reversed^(c->parent->rev))];
+    }
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (parents)
+        CC_FREE (parents, parentnode);
+    if (children)
+        CC_FREE (children, childnode);
+    if (par_cyc)
+        CC_FREE (par_cyc, int);
+    if (par_cyc_inv)
+        CC_FREE (par_cyc_inv, int);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    return children[x].adj[!(reversed^(children[x].parent->rev))]->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    return children[x].adj[reversed^(children[x].parent->rev)]->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int x, int y)
+#else
+void CClinkern_flipper_flip (x, y)
+int x,y;
+#endif
+{
+    childnode *xc = &(children[x]);
+    childnode *yc = &(children[y]);
+
+    if (SAME_SEGMENT (xc, yc)) {
+        if (xc != yc) {
+            same_segment_flip (xc, yc);
+        }
+    } else {
+        int xdir = (reversed^(xc->parent->rev));
+        int ydir = (reversed^(yc->parent->rev));
+        childnode *xprev = xc->adj[xdir];
+        childnode *ynext = yc->adj[!ydir];
+        if (SAME_SEGMENT (ynext, xprev)) {
+            if (ynext != xprev) {
+                same_segment_flip (ynext, xprev);
+            }
+            reversed ^= 1;
+        } else {
+            if (xc->parent->ends[xdir] == xc &&
+                yc->parent->ends[!ydir] == yc) {
+                if (parsegsize (xc->parent, yc->parent) < nsegments / 2) {
+                    consecutive_segment_flip (xc->parent, yc->parent);
+                } else {
+                    consecutive_segment_flip(parnext(yc->parent),
+                                             parprev(xc->parent));
+                    reversed ^= 1;
+                }
+            } else {
+                if (xprev->parent == xc->parent) {
+                    segment_split (xc->parent, xprev, xc, 0);
+                    if (SAME_SEGMENT (xc, yc)) {
+                        if (xc != yc)
+                            same_segment_flip (xc, yc);
+                        return;
+                    } else if (SAME_SEGMENT (ynext, xprev)) {
+                        if (ynext != xprev) {
+                            same_segment_flip (ynext, xprev);
+                        }
+                        reversed ^= 1;
+                        return;
+                    }
+                }
+                if (ynext->parent == yc->parent) {
+                    segment_split (yc->parent, yc, ynext, 0);
+                    if (SAME_SEGMENT (xc, yc)) {
+                        if (xc != yc)
+                            same_segment_flip (xc, yc);
+                        return;
+                    } else if (SAME_SEGMENT (ynext, xprev)) {
+                        if (ynext != xprev) {
+                            same_segment_flip (ynext, xprev);
+                        }
+                        reversed ^= 1;
+                        return;
+                    }
+                }
+                if (parsegsize (xc->parent, yc->parent) < nsegments / 2) {
+                    consecutive_segment_flip (xc->parent, yc->parent);
+                } else {
+                    consecutive_segment_flip(parnext(yc->parent),
+                                             parprev(xc->parent));
+                    reversed ^= 1;
+                }
+
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void same_segment_flip (childnode *a, childnode *b)
+#else
+static void same_segment_flip (a, b)
+childnode *a, *b;
+#endif
+{
+    parentnode *parent = a->parent;
+    int dir = (reversed^(parent->rev));
+    childnode *aprev = a->adj[dir];
+    childnode *bnext = b->adj[!dir];
+    childnode *c, *cnext;
+
+#ifdef USE_SEGMENT_SPLIT
+    if ((dir && a->id - b->id > split_cutoff) ||
+       (!dir && b->id - a->id > split_cutoff)) {
+        if (aprev->parent == parent)
+            segment_split (parent, aprev, a, 1);
+        if (bnext->parent == parent)
+            segment_split (parent, b, bnext, 2);
+        aprev->adj[!(reversed^(aprev->parent->rev))] = b;
+        bnext->adj[reversed^(bnext->parent->rev)] = a;
+        a->adj[dir] = bnext;
+        b->adj[!dir] = aprev;
+        parent->rev ^= 1;
+        return;
+    }
+#endif
+
+    if (dir) {
+        int id = a->id;
+        aprev->adj[!(reversed^(aprev->parent->rev))] = b;
+        bnext->adj[reversed^(bnext->parent->rev)] = a;
+        cnext = b->adj[1];
+        b->adj[1] = aprev;
+        b->adj[0] = cnext;
+        b->id = id--;
+        c = cnext;
+        while (c != a) {
+            cnext = c->adj[1];
+            c->adj[1] = c->adj[0];
+            c->adj[0] = cnext;
+            c->id = id--;
+            c = cnext;
+        }
+        a->adj[1] = a->adj[0];
+        a->adj[0] = bnext;
+        a->id = id;
+        if (parent->ends[1] == a)
+            parent->ends[1] = b;
+        if (parent->ends[0] == b)
+            parent->ends[0] = a;
+    } else {
+        int id = a->id;
+        aprev->adj[!(reversed^(aprev->parent->rev))] = b;
+        bnext->adj[reversed^(bnext->parent->rev)] = a;
+        c = b->adj[0];
+        b->adj[0] = aprev;
+        b->adj[1] = c;
+        b->id = id++;
+        while (c != a) {
+            cnext = c->adj[0];
+            c->adj[0] = c->adj[1];
+            c->adj[1] = cnext;
+            c->id = id++;
+            c = cnext;
+        }
+        a->adj[0] = a->adj[1];
+        a->adj[1] = bnext;
+        a->id = id;
+        if (parent->ends[0] == a)
+            parent->ends[0] = b;
+        if (parent->ends[1] == b)
+            parent->ends[1] = a;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void consecutive_segment_flip (parentnode *a, parentnode *b)
+#else
+static void consecutive_segment_flip (a, b)
+parentnode *a, *b;
+#endif
+{
+    childnode *achild = a->ends[reversed^(a->rev)];
+    childnode *bchild = b->ends[!(reversed^(b->rev))];
+    childnode *childprev, *childnext;
+
+    if (reversed) {
+        childprev = achild->adj[!a->rev];
+        childnext = bchild->adj[b->rev];
+        childprev->adj[childprev->parent->rev] = bchild;
+        childnext->adj[!childnext->parent->rev] = achild;
+        bchild->adj[b->rev] = childprev;
+        achild->adj[!a->rev] = childnext;
+        parflip (a, b);
+    } else {
+        childprev = achild->adj[a->rev];
+        childnext = bchild->adj[!b->rev];
+        childprev->adj[!childprev->parent->rev] = bchild;
+        childnext->adj[childnext->parent->rev] = achild;
+        bchild->adj[!b->rev] = childprev;
+        achild->adj[a->rev] = childnext;
+        parflip (a, b);
+    }
+}
+
+/* split between a and aprev */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void segment_split (parentnode *p, childnode *aprev, childnode *a,
+                           int left_or_right)
+#else
+static void segment_split (p, aprev, a, left_or_right)
+parentnode *p;
+childnode *aprev, *a;
+int left_or_right;
+#endif
+{
+    int side;
+    int dir = (reversed^(p->rev));
+    int id;
+    parentnode *pnext;
+    childnode *b, *bnext;
+
+    if (dir)
+        side = p->ends[1]->id - aprev->id + 1;
+    else
+        side = aprev->id - p->ends[0]->id + 1;
+
+    if ((left_or_right == 0 && side <= p->size / 2) || left_or_right == 1) {
+        pnext = parprev(p);
+        pnext->size += side;
+        p->size -= side;
+        if (pnext->rev == p->rev) {
+            b = pnext->ends[!dir];
+            id = b->id;
+            if (dir) {
+                do {
+                    b = b->adj[0];
+                    b->id = --id;
+                    b->parent = pnext;
+                } while (b != aprev);
+            } else {
+                do {
+                    b = b->adj[1];
+                    b->id = ++id;
+                    b->parent = pnext;
+                } while (b != aprev);
+            }
+            pnext->ends[!dir] = aprev;
+            p->ends[dir] = a;
+        } else {
+            b = pnext->ends[dir];
+            id = b->id;
+            if (!dir) {
+                bnext = b->adj[0];
+                do {
+                    b = bnext;
+                    b->id = --id;
+                    b->parent = pnext;
+                    bnext = b->adj[1];
+                    b->adj[1] = b->adj[0];
+                    b->adj[0] = bnext;
+                } while (b != aprev);
+            } else {
+                bnext = b->adj[1];
+                do {
+                    b = bnext;
+                    b->id = ++id;
+                    b->parent = pnext;
+                    bnext = b->adj[0];
+                    b->adj[0] = b->adj[1];
+                    b->adj[1] = bnext;
+                } while (b != aprev);
+            }
+            pnext->ends[dir] = aprev;
+            p->ends[dir] = a;
+        }
+    } else {
+        pnext = parnext(p);
+        pnext->size += (p->size - side);
+        p->size = side;
+        if (pnext->rev == p->rev) {
+            b = pnext->ends[dir];
+            id = b->id;
+            if (dir) {
+                do {
+                    b = b->adj[1];
+                    b->id = ++id;
+                    b->parent = pnext;
+                } while (b != a);
+            } else {
+                do {
+                    b = b->adj[0];
+                    b->id = --id;
+                    b->parent = pnext;
+                } while (b != a);
+            }
+            pnext->ends[dir] = a;
+            p->ends[!dir] = aprev;
+        } else {
+            b = pnext->ends[!dir];
+            id = b->id;
+            if (!dir) {
+                bnext = b->adj[1];
+                do {
+                    b = bnext;
+                    b->id = ++id;
+                    b->parent = pnext;
+                    bnext = b->adj[0];
+                    b->adj[0] = b->adj[1];
+                    b->adj[1] = bnext;
+                } while (b != a);
+            } else {
+                bnext = b->adj[0];
+                do {
+                    b = bnext;
+                    b->id = --id;
+                    b->parent = pnext;
+                    bnext = b->adj[1];
+                    b->adj[1] = b->adj[0];
+                    b->adj[0] = bnext;
+                } while (b != a);
+            }
+            pnext->ends[!dir] = a;
+            p->ends[!dir] = aprev;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    childnode *a = &(children[x]);
+    childnode *b = &(children[y]);
+    childnode *c = &(children[z]);
+    parentnode *pa = a->parent;
+    parentnode *pb = b->parent;
+    parentnode *pc = c->parent;
+
+    if (pa == pb) {
+        if (pa == pc) {
+            if (reversed^(pa->rev)) {
+                if (a->id >= b->id) {
+                    return (b->id >= c->id || c->id >= a->id);
+                } else {
+                    return (b->id >= c->id && c->id >= a->id);
+                }
+            } else {
+                if (a->id <= b->id) {
+                    return (b->id <= c->id || c->id <= a->id);
+                } else {
+                    return (b->id <= c->id && c->id <= a->id);
+                }
+            }
+        } else {
+            if (reversed^(pa->rev)) {
+                return (a->id >= b->id);
+            } else {
+                return (a->id <= b->id);
+            }
+        }
+    } else if (pa == pc) {
+            if (reversed^(pa->rev)) {
+                return (a->id <= c->id);
+            } else {
+                return (a->id >= c->id);
+            }
+    } else if (pb == pc) {
+            if (reversed^(pb->rev)) {
+                return (b->id >= c->id);
+            } else {
+                return (b->id <= c->id);
+            }
+    } else {
+        int aloc = par_cyc_inv[pa->index];
+        int bloc = par_cyc_inv[pb->index];
+        int cloc = par_cyc_inv[pc->index];
+
+        if (reversed) {
+            if (aloc >= bloc)
+                return (bloc >= cloc || cloc >= aloc);
+            else
+                return (bloc >= cloc && cloc >= aloc);
+        } else {
+            if (aloc <= bloc)
+                return (bloc <= cloc || cloc <= aloc);
+            else
+                return (bloc <= cloc && cloc <= aloc);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static parentnode *parnext (parentnode *x)
+#else
+static parentnode *parnext (x)
+parentnode *x;
+#endif
+{
+    int y;
+
+    if (reversed) {
+        y = par_cyc_inv[x->index] - 1;
+        return (y >= 0 ? &(parents[par_cyc[y]]) :
+                         &(parents[par_cyc[nsegments-1]]));
+    } else {
+        y = par_cyc_inv[x->index] + 1;
+        return (y < nsegments ? &(parents[par_cyc[y]]) :
+                                &(parents[par_cyc[0]]));
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static parentnode *parprev (parentnode *x)
+#else
+static parentnode *parprev (x)
+parentnode *x;
+#endif
+{
+    int y;
+
+    if (!reversed) {
+        y = par_cyc_inv[x->index] - 1;
+        return (y >= 0 ? &(parents[par_cyc[y]]) :
+                         &(parents[par_cyc[nsegments-1]]));
+    } else {
+        y = par_cyc_inv[x->index] + 1;
+        return (y < nsegments ? &(parents[par_cyc[y]]) :
+                                &(parents[par_cyc[0]]));
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void parflip (parentnode *a, parentnode *b)
+#else
+static void parflip (a, b)
+parentnode *a, *b;
+#endif
+{
+    int x = a->index;
+    int y = b->index;
+    int xloc = par_cyc_inv[x];
+    int yloc = par_cyc_inv[y];
+    int temp;
+    int gap;
+
+    if (reversed) {
+        SWAP (xloc, yloc, temp);
+    }
+    gap = yloc - xloc;
+    if (gap < 0) gap += nsegments;
+
+    if (xloc > yloc) {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = par_cyc[xloc];
+            y = par_cyc[yloc];
+            parents[x].rev ^= 1;
+            parents[y].rev ^= 1;
+            par_cyc[xloc] = y;
+            par_cyc[yloc] = x;
+            par_cyc_inv[x] = yloc--;
+            par_cyc_inv[y] = xloc++;
+            if (xloc >= nsegments)
+                xloc = 0;
+            if (yloc < 0)
+                yloc = nsegments - 1;
+        }
+    } else {
+        gap++;
+        gap /= 2;
+        for (; gap; gap--) {
+            x = par_cyc[xloc];
+            y = par_cyc[yloc];
+            parents[x].rev ^= 1;
+            parents[y].rev ^= 1;
+            par_cyc[xloc] = y;
+            par_cyc[yloc] = x;
+            par_cyc_inv[x] = yloc--;
+            par_cyc_inv[y] = xloc++;
+        }
+    }
+    if (xloc == yloc)
+        parents[par_cyc[xloc]].rev ^= 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parsegsize (parentnode *a, parentnode *b)
+#else
+static int parsegsize (a, b)
+parentnode *a, *b;
+#endif
+{
+    int gap;
+
+    if (reversed)
+        gap = par_cyc_inv[a->index] - par_cyc_inv[b->index];
+    else
+        gap = par_cyc_inv[b->index] - par_cyc_inv[a->index];
+
+    if (gap < 0)
+        return  gap + nsegments;
+    else
+        return gap;
+}
diff --git a/contrib/blossom/concorde97/LINKERN/flip_two.c b/contrib/blossom/concorde97/LINKERN/flip_two.c
new file mode 100644
index 0000000000000000000000000000000000000000..15430b69260f8e59abd990166fc1134bf8c783ad
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/flip_two.c
@@ -0,0 +1,678 @@
+/***************************************************************************/
+/*                                                                         */
+/*      TOUR MAINTANENCE ROUTINES FOR LIN-KERNIGHAN - Two-level Tree       */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 2, 1995                                                      */
+/*                                                                         */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*   int CClinkern_flipper_init (int ncount, int *cyc)                     */
+/*     initializes flipper1 to an initial cycle given in cyc.              */
+/*     returns 0 on success, nonzero on failure.                           */
+/*   int CClinkern_flipper_cycle (int *p)                                  */
+/*     places the current cycle in p.                                      */
+/*     returns the number of segments in current representation.           */
+/*   void CClinkern_flipper_finish (void)                                  */
+/*     frees up temporary space allocated by CClinkern_flipper_init.       */
+/*     every flipper_init should lead to a flipper_finish call.            */
+/*   void CClinkern_flipper_free_world (void)                              */
+/*     frees up all remaining space (including ptrs)                       */
+/*     should be called when we are finished with linkern                  */
+/*   int CClinkern_flipper_next (int x)                                    */
+/*     returns the successor to x in the current cycle.                    */
+/*   int CClinkern_flipper_prev (int x)                                    */
+/*     returns the predecessor of x in the current cycle.                  */
+/*   void CClinkern_flipper_flip (int x, int y)                            */
+/*     flips the portion of the cycle from x to y (inclusive).             */
+/*   int CClinkern_flipper_sequence (int * x, int y, int z)                */
+/*     returns 1 if xyz occur as an increasing subsequence of the cycle,   */
+/*     returns 0 otherwise.                                                */
+/*                                                                         */
+/* NOTES:                                                                  */
+/*       This is desribed in the paper "Data structures for traveling      */
+/*   salesman" by Fredman, Johnson, McGeoch, and Ostheimer.                */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "linkern.h"
+
+/***************************************************************************/
+/*                                                                         */
+/* TWO-LEVEL TREES:                                                        */
+/*                                                                         */
+/*     1. Uses the "groupsize" approach described in the paper.            */
+/*                                                                         */
+/***************************************************************************/
+
+#define USE_SEGMENT_SPLIT
+#define GROUPSIZE_FACTOR 0.50
+#define SEGMENT_SPLIT_CUTOFF 0.35
+
+typedef struct parentnode {
+    struct parentnode *adj[2];
+    struct childnode  *ends[2];
+    int                size;
+    int                id;
+    int                rev;
+} parentnode;
+
+typedef struct childnode {
+    struct parentnode *parent;
+    struct childnode  *adj[2];
+    int                id;
+    int                name;
+} childnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    same_segment_flip (childnode *a, childnode *b),
+    consecutive_segment_flip (parentnode *a, parentnode *b),
+    segment_split (parentnode *p, childnode *aprev, childnode *a,
+                   int left_or_right);
+
+#else
+
+static void
+    same_segment_flip (),
+    consecutive_segment_flip (),
+    segment_split ();
+
+#endif
+
+static parentnode *parents = (parentnode *) NULL;
+static childnode *children = (childnode *) NULL;
+static int reversed = 0;
+static cycle_size = 0;
+static int nsegments = 0;
+static groupsize = 100;
+#ifdef USE_SEGMENT_SPLIT
+static int split_cutoff = 100;
+#endif
+
+#define SAME_SEGMENT(a, b)                                                  \
+     (a->parent == b->parent &&                                             \
+      ((!(reversed^(a->parent->rev)) && a->id <= b->id) ||                  \
+       ((reversed^(a->parent->rev)) && a->id >= b->id)))
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_init (int ncount, int *cyc)
+#else
+int CClinkern_flipper_init (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, j, cind, remain;
+    childnode *c, *cprev, *cnext;
+    parentnode *p;
+
+    reversed = 0;
+    cycle_size = ncount;
+    groupsize = (int) (sqrt ((double) ncount) * GROUPSIZE_FACTOR);
+    nsegments =  (ncount + groupsize - 1) / groupsize;
+#ifdef USE_SEGMENT_SPLIT
+    split_cutoff = (int) (groupsize * SEGMENT_SPLIT_CUTOFF);
+#endif
+
+    parents = CC_SAFE_MALLOC (nsegments, parentnode);
+    if (!parents)
+        return 1;
+
+    children = CC_SAFE_MALLOC (ncount + 1, childnode);
+                 /* The +1 will stop a purify burp later */
+    if (!children) {
+        CC_FREE (parents, parentnode);
+        return 1;
+    }
+
+    remain = ncount;
+    i = 0;
+    j = 2 * groupsize;
+    while (remain >= j) {
+        parents[i].size = groupsize;
+        remain -= groupsize;
+        i++;
+    }
+    if (remain > groupsize) {
+        parents[i].size = remain / 2;
+        remain -= (remain / 2);
+        i++;
+    }
+    parents[i].size = remain;
+    i++;
+
+    if (i != nsegments) {
+        printf ("seg count is wrong\n");
+        fflush (stdout);
+        CC_FREE (parents, parentnode);
+        CC_FREE (children, childnode);
+        return 1;
+    }
+
+    c = (childnode *) NULL;
+    cnext = &(children[cyc[0]]);
+    for (i = 0, p = parents, c = children, cind = 0; i < nsegments; p++, i++) {
+        p->id = i;
+        p->rev = 0;
+        p->ends[0] = cnext;
+        for (j = p->size; j > 0; j--) {
+            cprev = c;
+            c = cnext;
+            c->id = cind;
+            c->name = cyc[cind];
+            c->parent = p;
+            c->adj[0] = cprev;
+            cind++;
+            if (cind != ncount) {
+                cnext = &(children[cyc[cind]]);
+                c->adj[1] = cnext;
+            }
+        }
+        p->ends[1] = c;
+        p->adj[0] = p - 1;
+        p->adj[1] = p + 1;
+    }
+    parents[0].adj[0] = &(parents[nsegments - 1]);
+    parents[nsegments - 1].adj[1] = &(parents[0]);
+    children[cyc[0]].adj[0] = &(children[cyc[ncount - 1]]);
+    children[cyc[ncount - 1]].adj[1] = &(children[cyc[0]]);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_cycle (int *x)
+#else
+int CClinkern_flipper_cycle (x)
+int *x;
+#endif
+{
+    childnode *c, *start;
+    int k = 0;
+
+    start = &(children[0]);
+    c = start->adj[!(reversed^(start->parent->rev))];
+
+    x[k++] = start->name;
+    while (c != start) {
+        x[k++] = c->name;
+        c = c->adj[!(reversed^(c->parent->rev))];
+    }
+    return cycle_size;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_finish (void)
+#else
+void CClinkern_flipper_finish ()
+#endif
+{
+    if (parents)
+        CC_FREE (parents, parentnode);
+    if (children)
+        CC_FREE (children, childnode);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_free_world (void)
+#else
+void CClinkern_flipper_free_world ()
+#endif
+{
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_next (int x)
+#else
+int CClinkern_flipper_next (x)
+int x;
+#endif
+{
+    return children[x].adj[!(reversed^(children[x].parent->rev))]->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_prev (int x)
+#else
+int CClinkern_flipper_prev (x)
+int x;
+#endif
+{
+    return children[x].adj[reversed^(children[x].parent->rev)]->name;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClinkern_flipper_flip (int x, int y)
+#else
+void CClinkern_flipper_flip (x, y)
+int x,y;
+#endif
+{
+    childnode *xc = &(children[x]);
+    childnode *yc = &(children[y]);
+
+    if (SAME_SEGMENT (xc, yc)) {
+        if (xc != yc) {
+            same_segment_flip (xc, yc);
+        }
+    } else {
+        int xdir = (reversed^(xc->parent->rev));
+        int ydir = (reversed^(yc->parent->rev));
+        childnode *xprev = xc->adj[xdir];
+        childnode *ynext = yc->adj[!ydir];
+        if (SAME_SEGMENT (ynext, xprev)) {
+            if (ynext != xprev) {
+                same_segment_flip (ynext, xprev);
+            }
+            reversed ^= 1;
+        } else {
+            int side;
+            if (xc->parent->ends[xdir] == xc &&
+                yc->parent->ends[!ydir] == yc) {
+                if (reversed)
+                    side = xc->parent->id - yc->parent->id;
+                else
+                    side = yc->parent->id - xc->parent->id;
+                if (side < 0)
+                    side += nsegments;
+                if (side < nsegments / 2) {
+                    consecutive_segment_flip (xc->parent, yc->parent);
+                } else {
+                    consecutive_segment_flip(yc->parent->adj[!reversed],
+                                             xc->parent->adj[reversed]);
+                    reversed ^= 1;
+                }
+            } else {
+                if (xprev->parent == xc->parent) {
+                    segment_split (xc->parent, xprev, xc, 0);
+                    if (SAME_SEGMENT (xc, yc)) {
+                        if (xc != yc)
+                            same_segment_flip (xc, yc);
+                        return;
+                    } else if (SAME_SEGMENT (ynext, xprev)) {
+                        if (ynext != xprev) {
+                            same_segment_flip (ynext, xprev);
+                        }
+                        reversed ^= 1;
+                        return;
+                    }
+                }
+                if (ynext->parent == yc->parent) {
+                    segment_split (yc->parent, yc, ynext, 0);
+                    if (SAME_SEGMENT (xc, yc)) {
+                        if (xc != yc)
+                            same_segment_flip (xc, yc);
+                        return;
+                    } else if (SAME_SEGMENT (ynext, xprev)) {
+                        if (ynext != xprev) {
+                            same_segment_flip (ynext, xprev);
+                        }
+                        reversed ^= 1;
+                        return;
+                    }
+                }
+                if (reversed)
+                    side = xc->parent->id - yc->parent->id;
+                else
+                    side = yc->parent->id - xc->parent->id;
+                if (side < 0)
+                    side += nsegments;
+                if (side < nsegments / 2) {
+                    consecutive_segment_flip (xc->parent, yc->parent);
+                } else {
+                    consecutive_segment_flip(yc->parent->adj[!reversed],
+                                             xc->parent->adj[reversed]);
+                    reversed ^= 1;
+                }
+
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void same_segment_flip (childnode *a, childnode *b)
+#else
+static void same_segment_flip (a, b)
+childnode *a, *b;
+#endif
+{
+    parentnode *parent = a->parent;
+    int dir = (reversed^(parent->rev));
+    childnode *aprev = a->adj[dir];
+    childnode *bnext = b->adj[!dir];
+    childnode *c, *cnext;
+
+#ifdef USE_SEGMENT_SPLIT
+    if ((dir && a->id - b->id > split_cutoff) ||
+       (!dir && b->id - a->id > split_cutoff)) {
+        if (aprev->parent == parent)
+            segment_split (parent, aprev, a, 1);
+        if (bnext->parent == parent)
+            segment_split (parent, b, bnext, 2);
+        aprev->adj[!(reversed^(aprev->parent->rev))] = b;
+        bnext->adj[reversed^(bnext->parent->rev)] = a;
+        a->adj[dir] = bnext;
+        b->adj[!dir] = aprev;
+        parent->rev ^= 1;
+        return;
+    }
+#endif
+
+    if (dir) {
+        int id = a->id;
+        aprev->adj[!(reversed^(aprev->parent->rev))] = b;
+        bnext->adj[reversed^(bnext->parent->rev)] = a;
+        cnext = b->adj[1];
+        b->adj[1] = aprev;
+        b->adj[0] = cnext;
+        b->id = id--;
+        c = cnext;
+        while (c != a) {
+            cnext = c->adj[1];
+            c->adj[1] = c->adj[0];
+            c->adj[0] = cnext;
+            c->id = id--;
+            c = cnext;
+        }
+        a->adj[1] = a->adj[0];
+        a->adj[0] = bnext;
+        a->id = id;
+        if (parent->ends[1] == a)
+            parent->ends[1] = b;
+        if (parent->ends[0] == b)
+            parent->ends[0] = a;
+    } else {
+        int id = a->id;
+        aprev->adj[!(reversed^(aprev->parent->rev))] = b;
+        bnext->adj[reversed^(bnext->parent->rev)] = a;
+        c = b->adj[0];
+        b->adj[0] = aprev;
+        b->adj[1] = c;
+        b->id = id++;
+        while (c != a) {
+            cnext = c->adj[0];
+            c->adj[0] = c->adj[1];
+            c->adj[1] = cnext;
+            c->id = id++;
+            c = cnext;
+        }
+        a->adj[0] = a->adj[1];
+        a->adj[1] = bnext;
+        a->id = id;
+        if (parent->ends[0] == a)
+            parent->ends[0] = b;
+        if (parent->ends[1] == b)
+            parent->ends[1] = a;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void consecutive_segment_flip (parentnode *a, parentnode *b)
+#else
+static void consecutive_segment_flip (a, b)
+parentnode *a, *b;
+#endif
+{
+    parentnode *aprev = a->adj[reversed];
+    parentnode *bnext = b->adj[!reversed];
+    parentnode *c, *cnext;
+    childnode *achild = a->ends[reversed^(a->rev)];
+    childnode *bchild = b->ends[!(reversed^(b->rev))];
+    childnode *childprev, *childnext;
+    int id = a->id;
+
+    if (reversed) {
+        childprev = achild->adj[!a->rev];
+        childnext = bchild->adj[b->rev];
+        childprev->adj[childprev->parent->rev] = bchild;
+        childnext->adj[!childnext->parent->rev] = achild;
+        bchild->adj[b->rev] = childprev;
+        achild->adj[!a->rev] = childnext;
+
+        aprev->adj[0] = b;
+        bnext->adj[1] = a;
+        c = b->adj[1];
+        b->adj[1] = aprev;
+        b->adj[0] = c;
+        b->id = id--;
+        b->rev ^= 1;
+        while (c != a) {
+            cnext = c->adj[1];
+            c->adj[1] = c->adj[0];
+            c->adj[0] = cnext;
+            c->id = id--;
+            c->rev ^= 1;
+            c = cnext;
+        }
+        a->adj[1] = a->adj[0];
+        a->adj[0] = bnext;
+        a->id = id;
+        a->rev ^= 1;
+    } else {
+        childprev = achild->adj[a->rev];
+        childnext = bchild->adj[!b->rev];
+        childprev->adj[!childprev->parent->rev] = bchild;
+        childnext->adj[childnext->parent->rev] = achild;
+        bchild->adj[!b->rev] = childprev;
+        achild->adj[a->rev] = childnext;
+
+        aprev->adj[1] = b;
+        bnext->adj[0] = a;
+        c = b->adj[0];
+        b->adj[0] = aprev;
+        b->adj[1] = c;
+        b->id = id++;
+        b->rev ^= 1;
+        while (c != a) {
+            cnext = c->adj[0];
+            c->adj[0] = c->adj[1];
+            c->adj[1] = cnext;
+            c->id = id++;
+            c->rev ^= 1;
+            c = cnext;
+        }
+        a->adj[0] = a->adj[1];
+        a->adj[1] = bnext;
+        a->id = id;
+        a->rev ^= 1;
+    }
+}
+
+/* split between a and aprev */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void segment_split (parentnode *p, childnode *aprev, childnode *a,
+                           int left_or_right)
+#else
+static void segment_split (p, aprev, a, left_or_right)
+parentnode *p;
+childnode *aprev, *a;
+int left_or_right;
+#endif
+{
+    int side;
+    int dir = (reversed^(p->rev));
+    int id;
+    parentnode *pnext;
+    childnode *b, *bnext;
+
+    if (dir)
+        side = p->ends[1]->id - aprev->id + 1;
+    else
+        side = aprev->id - p->ends[0]->id + 1;
+
+    if ((left_or_right == 0 && side <= p->size / 2) || left_or_right == 1) {
+        pnext = p->adj[reversed];
+        pnext->size += side;
+        p->size -= side;
+        if (pnext->rev == p->rev) {
+            b = pnext->ends[!dir];
+            id = b->id;
+            if (dir) {
+                do {
+                    b = b->adj[0];
+                    b->id = --id;
+                    b->parent = pnext;
+                } while (b != aprev);
+            } else {
+                do {
+                    b = b->adj[1];
+                    b->id = ++id;
+                    b->parent = pnext;
+                } while (b != aprev);
+            }
+            pnext->ends[!dir] = aprev;
+            p->ends[dir] = a;
+        } else {
+            b = pnext->ends[dir];
+            id = b->id;
+            if (!dir) {
+                bnext = b->adj[0];
+                do {
+                    b = bnext;
+                    b->id = --id;
+                    b->parent = pnext;
+                    bnext = b->adj[1];
+                    b->adj[1] = b->adj[0];
+                    b->adj[0] = bnext;
+                } while (b != aprev);
+            } else {
+                bnext = b->adj[1];
+                do {
+                    b = bnext;
+                    b->id = ++id;
+                    b->parent = pnext;
+                    bnext = b->adj[0];
+                    b->adj[0] = b->adj[1];
+                    b->adj[1] = bnext;
+                } while (b != aprev);
+            }
+            pnext->ends[dir] = aprev;
+            p->ends[dir] = a;
+        }
+    } else {
+        pnext = p->adj[!reversed];
+        pnext->size += (p->size - side);
+        p->size = side;
+        if (pnext->rev == p->rev) {
+            b = pnext->ends[dir];
+            id = b->id;
+            if (dir) {
+                do {
+                    b = b->adj[1];
+                    b->id = ++id;
+                    b->parent = pnext;
+                } while (b != a);
+            } else {
+                do {
+                    b = b->adj[0];
+                    b->id = --id;
+                    b->parent = pnext;
+                } while (b != a);
+            }
+            pnext->ends[dir] = a;
+            p->ends[!dir] = aprev;
+        } else {
+            b = pnext->ends[!dir];
+            id = b->id;
+            if (!dir) {
+                bnext = b->adj[1];
+                do {
+                    b = bnext;
+                    b->id = ++id;
+                    b->parent = pnext;
+                    bnext = b->adj[0];
+                    b->adj[0] = b->adj[1];
+                    b->adj[1] = bnext;
+                } while (b != a);
+            } else {
+                bnext = b->adj[0];
+                do {
+                    b = bnext;
+                    b->id = --id;
+                    b->parent = pnext;
+                    bnext = b->adj[1];
+                    b->adj[1] = b->adj[0];
+                    b->adj[0] = bnext;
+                } while (b != a);
+            }
+            pnext->ends[!dir] = a;
+            p->ends[!dir] = aprev;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_flipper_sequence (int x, int y, int z)
+#else
+int CClinkern_flipper_sequence (x, y, z)
+int x, y, z;
+#endif
+{
+    childnode *a = &(children[x]);
+    childnode *b = &(children[y]);
+    childnode *c = &(children[z]);
+    parentnode *pa = a->parent;
+    parentnode *pb = b->parent;
+    parentnode *pc = c->parent;
+
+    if (pa == pb) {
+        if (pa == pc) {
+            if (reversed^(pa->rev)) {
+                if (a->id >= b->id) {
+                    return (b->id >= c->id || c->id >= a->id);
+                } else {
+                    return (b->id >= c->id && c->id >= a->id);
+                }
+            } else {
+                if (a->id <= b->id) {
+                    return (b->id <= c->id || c->id <= a->id);
+                } else {
+                    return (b->id <= c->id && c->id <= a->id);
+                }
+            }
+        } else {
+            if (reversed^(pa->rev)) {
+                return (a->id >= b->id);
+            } else {
+                return (a->id <= b->id);
+            }
+        }
+    } else if (pa == pc) {
+            if (reversed^(pa->rev)) {
+                return (a->id <= c->id);
+            } else {
+                return (a->id >= c->id);
+            }
+    } else if (pb == pc) {
+            if (reversed^(pb->rev)) {
+                return (b->id >= c->id);
+            } else {
+                return (b->id <= c->id);
+            }
+    } else {
+        if (reversed) {
+            if (pa->id >= pb->id) {
+                return (pb->id >= pc->id || pc->id >= pa->id);
+            } else {
+                return (pb->id >= pc->id && pc->id >= pa->id);
+            }
+        } else {
+            if (pa->id <= pb->id) {
+                return (pb->id <= pc->id || pc->id <= pa->id);
+            } else {
+                return (pb->id <= pc->id && pc->id <= pa->id);
+            }
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/LINKERN/linkern.c b/contrib/blossom/concorde97/LINKERN/linkern.c
new file mode 100644
index 0000000000000000000000000000000000000000..09c47339df18fb42e1f4d156c29ee10624295ef2
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/linkern.c
@@ -0,0 +1,2781 @@
+/***************************************************************************/
+/*                                                                         */
+/*                    ITERATED LIN-KERNIGHAN                               */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 22, 1995                                                   */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*   int CClinkern_tour (int ncount, CCdatagroup *dat, int ecount,         */
+/*           int *elist, int stallcount, int repeatcount, int *incycle,    */
+/*           int *outcycle, double *val                                    */
+/*           int run_silently, double time_bound, double length_bound,     */
+/*           char *saveit_name)                                            */
+/*    RUNS Chained Lin-Kernighan.                                          */
+/*    -ncount (the number of nodes int the graph)                          */
+/*    -dat (coordinate dat)                                                */
+/*    -ecount (the number of good edges - should not be 0)                 */
+/*    -elist (the good edges in end1 end2 format)                          */
+/*    -stallcount (the max number of 4-swaps without progress              */
+/*    -repeatcount (the number of 4-swap kicks)                            */
+/*    -incycle (a starting cycle, in node node node format - can be NULL)  */
+/*    -outcycle (returns the cycle - can be NULL)                          */
+/*    -run_slightly (if nonzero, then very little info will be printed)    */
+/*    -time_bound (if postive, then the search will stop after the kick    */
+/*       that puts the running time above this number of seconds)          */
+/*    -length_bound (if postive, then the search will stop after the kick  */
+/*       that puts the tour at or below this length)                       */
+/*    -saveit_name (if non NULL then the tour will be saved to this file   */
+/*       after every 10000 kicks - if it has improved)                     */
+/*                                                                         */
+/*    NOTES: If incycle is NULL, then a random starting cycle is used. If  */
+/*     outcycle is not NULL, then it should point to an array of length at */
+/*     least ncount. The type of flipper to be used should be defined in   */
+/*     linkern.h and added to the makefile).                               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "linkern.h"
+
+#define MAX_OUTPUT 0       /* Define to 1 to have more output */
+
+#define MAXDEPTH 50        /* Shouldn't be less than 2.  */
+#define MAK_MORTON         /* Define to some of the Mak-Morton moves */
+#undef  NODE_INSERTIONS    /* Define to use Reinelt's moves */
+#undef  FULL_MAK_MORTON    /* Define to use all of the Mak-Morton moves */
+#define USE_LESS_OR_EQUAL
+#define SUBTRACT_GSTAR
+#undef  SWITCH_LATE_DEPTH  /* To give more search freedom before LATE_DEPTH */
+#define LATE_DEPTH 10      /* Should be less than MAXDEPTH */
+
+#define GEOM_FOUR_SWAPS    /* Use geometry to find close 4-swap kicks */
+#undef  CLOSE_FOUR_SWAPS   /* Use distances to find close 4-swap kicks */
+#undef  IMPROVE_FOUR_SWAPS /* Use an LK search as a kick */
+#define IMPROVE_SWITCH  0  /* Depth to start using IMPROVE_FOUR_SWAPS  */
+#define KICK_MAXDEPTH 50   /* Max # of swaps in an IMPROVE_FOUR_SWAP kick */
+#define LONG_KICKER        /* Guides choice of first edge in a kick */
+
+#define ACCEPT_TIES        /* In Chained LK, keep new tours that tie best */
+#undef  ACCEPT_BAD_TOURS   /* Define to use a simulated-annealing approach */
+
+#undef  MARK_NEIGHBORS     /* Mark the good-edge neighbors after swaps */
+#define USE_LESS_MARKING   /* Do not mark the tour neighbors after swaps */
+#define MARK_LEVEL  10     /* Number of tour neighbors after 4-swap kick */
+
+#define BACKTRACK 2
+#define MAX_BACK 10        /* Upper bound on the XXX_count entries          */
+static int backtrack_count[BACKTRACK] = {10, 5};    /* Breadth of backtrack */
+static int weird_backtrack_count[3] = {10, 5, 2};   /* For weird backtrack */
+
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      SETTING THE PARAMETERS                             */
+/*                                                                         */
+/*      At this point (27.8.97), we have not yet made a detailed           */
+/*  computational study to choose a good selection of the various          */
+/*  parameters that can be set. The default settings appear to work well   */
+/*  for large examples, where we want to obtain a good quality tour        */
+/*  quickly. For small instances where we may want to get very close to an */
+/*  optimal tour, better performance can often be obtained by using random */
+/*  four swaps, using a denser set of good edges, and by using a wider     */
+/*  (or deeper) search in the backtracking.                                */
+/*     The default settings are as follows:                                */
+/*                                                                         */
+/*        MAXDEPTH 50   (this means that Lin-Kernighan will not consider   */
+/*                       sequences of 2-opt moves longer than 50)          */
+/*        MAX_MORTON    (this permits the code to perform the "inverse"    */
+/*                       moves described in the paper by Mak and Morton.   */
+/*        USE_LESS_OR_EQUAL  (this tells the code to consider edges that   */
+/*                       have length <= the current gain (it is usually    */
+/*                       the case that LK is implemented to allow only     */
+/*                       edges that are < the current gain))               */
+/*        SUBTRACT_GSTAR   (restricts the freedom of the search to avoid   */
+/*                       long sequences of 2-opt moves that do not have    */
+/*                       a good chance of improving on the current best    */
+/*                       gain (gstar))                                     */
+/*        GEOM_FOUR_SWAPS   (uses 4-swap kicks between nodes that are      */
+/*                       geometrically close, this is better than random   */
+/*                       4-swaps for very large instances)                 */
+/*        LONG_KICKER   (choose the initial edge in a 4-swap kick to be    */
+/*                       one that is long relative to the length of the    */
+/*                       shortest good edge meeting the node (this is an   */
+/*                       idea of Andre Rohe))                              */
+/*        USE_LESS_MARKING   (do not mark the tour neighbors of the nodes  */
+/*                       appearing in an improving swap sequence)          */
+/*        BACKTRACK 2   (backtrack at the first two levels of the search)  */
+/*        MAX_BACK 10   (do not use more than breadth 10 in a backtrack)   */
+/*        backtrack_count[BACKTRACK] = {10, 5}   (to use breadth 10 at the */
+/*                       first level and breadth 5 at the second level)    */
+/*        weird_backtrack_count[3] = {10, 5, 2}  (in the weird step, use   */
+/*                       breadth 10 at first level, 5 at second level)     */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+
+#ifdef GEOM_FOUR_SWAPS
+#include "kdtree.h"
+#endif
+
+#define BIGINT 1000000000
+#define BIGDOUBLE 100000000000.0
+
+#define OTHEREND(e,n) (e->ends[0] == n ? e->ends[1] : e->ends[0])
+#define SWAP(x,y,temp) {(temp) = (x); (x) = (y); (y) = (temp);}
+#define Edgelen(n1, n2)  dist (n1, n2)
+/*
+#define Edgelen(n1, n2)  CCutil_dat_edgelen (n1, n2, gdat)
+*/
+
+
+#ifdef CC_EXTRA_INFO_FLIP
+#define FLIP(aprev, a, b, bnext, numi) {                                   \
+    CClinkern_flipper_flip ((aprev), (a), (b), (bnext));                   \
+    flipstack[flip_counter].first = (a);                                   \
+    flipstack[flip_counter].last = (b);                                    \
+    flipstack[flip_counter].firstprev = (aprev);                           \
+    flipstack[flip_counter++].lastnext = (bnext);                          \
+}
+#else
+#define FLIP(aprev, a, b, bnext, numi) {                                   \
+    CClinkern_flipper_flip ((a), (b));                                     \
+    flipstack[flip_counter].first = (a);                                   \
+    flipstack[flip_counter++].last = (b);                                  \
+}
+#endif
+
+#ifdef    CC_NO_UNDO_SEGMENTS_FLIPPER
+#define UNFLIP(aprev, a, b, bnext, numi) {                                 \
+    flip_counter--;                                                        \
+}
+#else  /* CC_NO_UNDO_SEGMENTS_FLIPPER */
+#ifdef CC_EXTRA_INFO_FLIP
+#define UNFLIP(aprev, a, b, bnext, numi) {                                 \
+    CClinkern_flipper_flip ((aprev), (b), (a), (bnext));                   \
+    flip_counter--;                                                        \
+}
+#else
+#define UNFLIP(aprev, a, b, bnext, numi) {                                 \
+    CClinkern_flipper_flip ((b), (a));                                     \
+    flip_counter--;                                                        \
+}
+#endif
+#endif /* CC_NO_UNDO_SEGMENTS_FLIPPER */
+
+#define markedge_add(n1, n2)    add_edges[n1 ^ n2] = 1
+#define markedge_del(n1, n2)    del_edges[n1 ^ n2] = 1
+#define unmarkedge_add(n1, n2)  add_edges[n1 ^ n2] = 0
+#define unmarkedge_del(n1, n2)  del_edges[n1 ^ n2] = 0
+#define is_it_added(n1, n2)     add_edges[n1 ^ n2]
+#define is_it_deleted(n1, n2)   del_edges[n1 ^ n2]
+
+#define ADD_TO_ACTIVE_QUEUE(n, ip) {                                       \
+    if (!active[(n)]) {                                                    \
+        active[(n)] = 1;                                                   \
+        (ip) = intptralloc ();                                             \
+        (ip)->this = (n);                                                  \
+        (ip)->next = (intptr *) NULL;                                      \
+        if (bottom_active_queue)                                           \
+            bottom_active_queue->next = (ip);                              \
+        else                                                               \
+            active_queue = (ip);                                           \
+        bottom_active_queue = (ip);                                        \
+    }                                                                      \
+}
+
+typedef struct edge {
+    int other;
+    int weight;
+} edge;
+
+typedef struct edgelook {
+    struct edgelook *next;
+    int other;
+    int diff;
+    int over;
+    int seq;
+    int side;
+#ifdef MAK_MORTON
+    int mm;
+#endif
+#ifdef NODE_INSERTIONS
+    int ni;
+    int under;
+#endif
+} edgelook;
+
+typedef struct intptr {
+    int this;
+    struct intptr *next;
+} intptr;
+
+typedef struct flippair {
+    int firstprev;
+    int first;
+    int last;
+    int lastnext;
+} flippair;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    look_ahead_noback (int first, int last, int G, edgelook *winner),
+    turn (int n),
+#ifdef IMPROVE_FOUR_SWAPS
+    kickturn (int n),
+#endif
+    bigturn (int n, int tonext),
+#ifdef LONG_KICKER
+    first_long_kicker (int ncount, int *t1, int *t2),
+#endif
+#if defined(CLOSE_FOUR_SWAPS) || defined(GEOM_FOUR_SWAPS)
+    find_close_four (int ncount, int *t1, int *t2, int *t3, int *t4,
+                                 int *t5, int *t6, int *t7, int *t8),
+#endif
+    randcycle (int ncount, int *cyc),
+    insertedge (int n1, int n2, int w),
+    free_graph (int ncount),
+    linkern_free_world (void);
+
+static int
+    buildgraph (int ncount, int ecount, int *elist),
+    repeated_lin_kernighan (int ncount, int *cyc, int stallcount,
+                            int repeatcount, double *val, double time_bound,
+                            double length_bound,  char *saveit_name),
+    lin_kernighan (int ncount, double *val),
+    weird_second_step (int G, int t1, int t2),
+    step (int level, int G, int *Gstar, int first, int last),
+    step_noback (int level, int G, int *Gstar, int first, int last),
+#ifdef IMPROVE_FOUR_SWAPS
+    kick_step_noback (int level, int G, int *Gstar, int first, int last),
+#endif
+#ifdef GEOM_FOUR_SWAPS
+    find_geometric_four (int ncount, CCkdtree *kdt,
+                         int *t1, int *t2, int *t3, int *t4,
+                         int *t5, int *t6, int *t7, int *t8),
+    random_four_swap (int ncount, CCkdtree *kdt, int *delta),
+#else
+    random_four_swap (int ncount),
+#endif
+    initarrays (int ncount),
+    initcache (int ncount),
+    dist (int i, int j);
+
+static double
+    improve_tour (int start),
+#ifdef IMPROVE_FOUR_SWAPS
+    kick_improve (int ncount),
+#endif
+    cycle_length (int ncount, int *cyc);
+
+static edgelook
+   *look_ahead (int first, int last, int G, int level),
+   *weird_look_ahead (int G, int t1, int t2),
+   *weird_look_ahead2 (int G, int t2, int t3, int t4),
+   *weird_look_ahead3 (int G, int t2, int t3, int t6);
+
+#else
+
+static void
+    look_ahead_noback (),
+    turn (),
+#ifdef IMPROVE_FOUR_SWAPS
+    kickturn (),
+#endif
+    bigturn (),
+#ifdef LONG_KICKER
+    first_long_kicker (),
+#endif
+#if defined(CLOSE_FOUR_SWAPS) || defined(GEOM_FOUR_SWAPS)
+    find_close_four (),
+#endif
+    randcycle (),
+    insertedge (),
+    free_graph (),
+    linkern_free_world ();
+
+static int
+    buildgraph (),
+    repeated_lin_kernighan (),
+    lin_kernighan (),
+    weird_second_step (),
+    step (),
+    step_noback (),
+#ifdef IMPROVE_FOUR_SWAPS
+    kick_step_noback (),
+#endif
+#ifdef GEOM_FOUR_SWAPS
+    find_geometric_four (),
+    random_four_swap (),
+#else
+    random_four_swap (),
+#endif
+    initarrays (),
+    initcache (),
+    dist ();
+
+static double
+    improve_tour (),
+#ifdef IMPROVE_FOUR_SWAPS
+    kick_improve (),
+#endif
+    cycle_length ();
+
+static edgelook
+   *look_ahead (),
+   *weird_look_ahead (),
+   *weird_look_ahead2 (),
+   *weird_look_ahead3 ();
+
+#endif
+
+static int  no_output = 0;
+static char *add_edges = (char *) NULL;
+static char *del_edges = (char *) NULL;
+static char *active = (char *) NULL;
+static int  *weirdmark = (int *) NULL;
+static int  *cacheind = (int *) NULL;
+static int  *cacheval = (int *) NULL;
+static intptr *active_queue = (intptr *) NULL;
+static intptr *bottom_active_queue = (intptr *) NULL;
+static int  weirdmagic = 0;
+static int  new_tour_time = 0;
+#if defined(CC_NO_UNDO_SEGMENTS_FLIPPER) || defined(CC_FULL_SEGMENTS_FLIPPER)
+static int  new_tour_cutoff = 1;
+#endif
+static int  flip_counter = 0;
+static flippair *flipstack = (flippair *) NULL;
+#ifdef CC_USE_FLIP_CLEANING
+static int winstack_max = 0;
+static int win_counter = 0;
+static flippair *winstack = (flippair *) NULL;
+static int      *win_cycle = (int *) NULL;
+#endif
+
+static edge **goodlist = (edge **) NULL;
+static intptr **fixlist = (intptr **) NULL;
+static CCdatagroup *gdat = (CCdatagroup *) NULL;
+static edge *edgespace = (edge *) NULL;
+static int *degree = (int *) NULL;
+
+CC_PTR_ALLOC_ROUTINE (intptr, intptralloc, intptrchunklist, intptrfreelist)
+CC_PTR_FREE_ROUTINE (intptr, intptrfree, intptrfreelist)
+CC_PTR_FREE_LIST_ROUTINE (intptr, intptr_list_free, intptrfree)
+CC_PTR_FREE_WORLD_ROUTINE (intptr, intptrfree_world, intptrchunklist,
+                  intptrfreelist)
+CC_PTR_LEAKS_ROUTINE (intptr, intptr_check_leaks, intptrchunklist,
+                  intptrfreelist, this, int)
+
+CC_PTR_ALLOC_ROUTINE (edgelook, edgelookalloc, edgelookchunklist,
+                  edgelookfreelist)
+CC_PTR_FREE_ROUTINE (edgelook, edgelookfree, edgelookfreelist)
+CC_PTR_FREE_LIST_ROUTINE(edgelook, edgelook_list_free, edgelookfree)
+CC_PTR_FREE_WORLD_ROUTINE( edgelook, edgelookfree_world, edgelookchunklist,
+                  edgelookfreelist)
+CC_PTR_LEAKS_ROUTINE (edgelook, edgelook_check_leaks, edgelookchunklist,
+                  edgelookfreelist, diff, int)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClinkern_tour (int ncount, CCdatagroup *dat, int ecount,
+        int *elist, int stallcount, int repeatcount, int *incycle,
+        int *outcycle, double *val, int run_silently, double time_bound,
+        double length_bound, char *saveit_name)
+#else
+int CClinkern_tour (ncount, dat, ecount, elist, stallcount, repeatcount,
+        incycle, outcycle, val, run_silently, time_bound, length_bound,
+        saveit_name)
+int ncount;
+CCdatagroup *dat;
+int ecount;
+int *elist;
+int stallcount, repeatcount;
+int *incycle;
+int *outcycle;
+double *val;
+int run_silently;
+double time_bound;
+double length_bound;
+char *saveit_name;
+#endif
+{
+    int i;
+    double startzeit, goodzeit;
+    int *tcyc = (int *) NULL;
+    intptr *ip;
+    int rval = 0;
+
+    if (!run_silently) {
+        printf ("linkern with %d nodes ...\n", ncount);
+        fflush (stdout);
+    }
+    startzeit = CCutil_zeit ();
+
+    no_output = run_silently;
+    gdat = dat;
+    fixlist = (intptr **) NULL;
+    active_queue = (intptr *) NULL;
+    bottom_active_queue = (intptr *) NULL;
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+    new_tour_time = 0;
+#endif
+#ifdef CC_FULL_SEGMENTS_FLIPPER
+    new_tour_time = 100000;
+#endif
+#ifdef CC_SEGMENTS_FLIPPER
+    new_tour_time = (ncount / 250) + 1;  /* 5.5.95 - 250 now looks okay    */
+#endif
+
+#if defined(CC_NO_UNDO_SEGMENTS_FLIPPER) || defined(CC_FULL_SEGMENTS_FLIPPER)
+    new_tour_cutoff = 500 + ncount / 50;
+#endif
+
+#ifdef NODE_INSERTIONS
+    flipstack = CC_SAFE_MALLOC (new_tour_time + 2*MAXDEPTH + 7 + KICK_MAXDEPTH,
+                             flippair);
+#else
+    flipstack = CC_SAFE_MALLOC (new_tour_time + MAXDEPTH + 7 + KICK_MAXDEPTH,
+                             flippair);
+#endif
+    if (!flipstack) {
+        rval = 1;
+        goto CLEANUP;
+    }
+#ifdef CC_USE_FLIP_CLEANING
+    win_counter = 0;
+#ifdef CC_FULL_SEGMENTS_FLIPPER
+    winstack_max = 100000;
+#else
+    winstack_max = (500 + ncount / 50) +
+                   (2 * (new_tour_time + MAXDEPTH + 7 + KICK_MAXDEPTH));
+#endif
+    winstack = CC_SAFE_MALLOC (winstack_max, flippair);
+    if (!winstack) {
+        rval = 1;
+        goto CLEANUP;
+    }
+#ifndef CC_FULL_SEGMENTS_FLIPPER
+    winstack_max -= ( 2 * (new_tour_time + MAXDEPTH + 7 + KICK_MAXDEPTH));
+#endif
+    win_cycle = CC_SAFE_MALLOC (ncount, int);
+    if (!win_cycle) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    win_cycle[0] = -1;
+#endif  /* CC_USE_FLIP_CLEANING */
+    tcyc = CC_SAFE_MALLOC (ncount, int);
+    if (!tcyc) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    if (initarrays (ncount)) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    if (initcache (ncount)) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (buildgraph (ncount, ecount, elist)) {
+        fprintf (stderr, "buildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+#ifdef BIG_PROBLEM
+    CC_FREE (elist, int);
+#endif
+
+    randcycle (ncount, tcyc);        /* init active_queue with random order */
+    for (i = 0; i < ncount; i++) {
+        ADD_TO_ACTIVE_QUEUE (tcyc[i], ip);
+    }
+
+    if (incycle) {
+        for (i = 0; i < ncount; i++)
+            tcyc[i] = incycle[i];
+        *val = cycle_length (ncount, tcyc);
+        if (!no_output) {
+            printf ("Starting Cycle: %.0f\n", *val);
+            fflush (stdout);
+        }
+    } else {
+        goodzeit = CCutil_zeit ();
+        randcycle (ncount, tcyc);
+        *val = cycle_length (ncount, tcyc);
+        if (!no_output) {
+            printf ("Random Cycle: %.0f  (Running Time: %.2f seconds)\n",
+                    *val, CCutil_zeit () - goodzeit);
+            fflush (stdout);
+        }
+    }
+    if (repeated_lin_kernighan (ncount, tcyc, stallcount,
+              repeatcount, val, time_bound, length_bound, saveit_name)) {
+        fprintf (stderr, "repeated_lin_kernighan failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (!no_output) {
+        printf ("Best cycle length: %.0f\n", *val);
+        printf ("Lin-Kernighan Running Time: %.2f\n",
+                            CCutil_zeit () - startzeit);
+        fflush (stdout);
+    }
+
+    if (outcycle) {
+        for (i = 0; i < ncount; i++)
+            outcycle[i] = tcyc[i];
+    }
+
+CLEANUP:
+
+    CC_IFFREE (flipstack, flippair);
+    CC_IFFREE (tcyc, int);
+    CC_IFFREE (add_edges, char);
+    CC_IFFREE (del_edges, char);
+    CC_IFFREE (active, char);
+    CC_IFFREE (weirdmark, int);
+    CC_IFFREE (cacheind, int);
+    CC_IFFREE (cacheval, int);
+#ifdef CC_USE_FLIP_CLEANING
+    CC_IFFREE (winstack, flippair);
+    CC_IFFREE (win_cycle, int);
+#endif
+
+    free_graph (ncount);
+    CClinkern_flipper_free_world ();
+    linkern_free_world ();
+
+    return rval;
+}
+
+#ifdef ACCEPT_BAD_TOURS
+#define HEAT_FACTOR 0.999
+#define HEAT_RESET 100000
+#define HEAT_MULT  20
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static int repeated_lin_kernighan (int ncount, int *cyc, int stallcount,
+        int count, double *val, double time_bound, double length_bound, 
+        char *saveit_name)
+#else
+static int repeated_lin_kernighan (ncount, cyc, stallcount, count, val,
+        time_bound, length_bound, saveit_name)
+int ncount;
+int *cyc;
+int stallcount, count;
+double *val;
+double time_bound;
+double length_bound;
+char *saveit_name;
+#endif
+{
+    int round = 0, quitcount, hit;
+    double t, best = *val, oldbest = *val;
+    int delta;
+    double szeit = CCutil_zeit ();
+#ifdef ACCEPT_BAD_TOURS
+    double heat = *val / (double) (HEAT_MULT * ncount), tdelta;
+#endif
+#ifdef GEOM_FOUR_SWAPS
+    CCkdtree kdt;
+#endif
+
+#ifdef GEOM_FOUR_SWAPS
+    if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        if (CCkdtree_build (&kdt, ncount, gdat, (double *) NULL)) {
+            fprintf (stderr, "CCkdtree_build failed\n");
+            fflush (stdout);
+            return 1;
+        }
+    }
+#endif
+
+    quitcount = stallcount;
+    if (quitcount > count)
+        quitcount = count;
+
+    CClinkern_flipper_init (ncount, cyc);
+    flip_counter = 0;
+#ifdef CC_USE_FLIP_CLEANING
+    win_counter = 0;
+    win_cycle[0] = -1;
+#endif
+    if (lin_kernighan (ncount, &best)) {
+        fprintf (stderr, "lin_kernighan failed\n");
+#ifdef GEOM_FOUR_SWAPS
+        if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE)
+            CCkdtree_free (&kdt);
+#endif
+        return 1;
+    }
+#ifdef CC_USE_FLIP_CLEANING
+#ifdef CC_FULL_SEGMENTS_FLIPPER
+    {
+        int i;
+
+        if (flip_counter > 0) {
+            if (flip_counter < new_tour_cutoff) {
+                for (i = 0; i < flip_counter; i++)
+                    CClinkern_flipper_flip_perm (flipstack[i].first,
+                                       flipstack[i].last);
+                CClinkern_flipper_reset_perm (1);
+            } else {
+                CClinkern_flipper_reset_temp (ncount);
+            }
+            flip_counter = 0;
+        }
+    }
+#endif   /* CC_FULL_SEGMENTS_FLIPPER */
+    win_counter = 0;
+    win_cycle[0] = -1;
+#else
+    CClinkern_flipper_cycle (cyc);
+    CClinkern_flipper_finish ();
+#endif
+
+    if (!no_output) {
+        if (quitcount > 0)
+            printf ("%d Steps   Best: %.0f   %.2f seconds\n", round, best,
+                                CCutil_zeit () - szeit);
+        else
+            printf ("LK Cycle: %.0f\n", best);
+        fflush (stdout);
+    }
+
+    while (round < quitcount) {
+        hit = 0;
+
+#ifndef CC_USE_FLIP_CLEANING
+        CClinkern_flipper_init (ncount, cyc);
+#endif
+        flip_counter = 0;
+
+#ifdef IMPROVE_FOUR_SWAPS
+        if (round < IMPROVE_SWITCH)
+            delta = random_four_swap (ncount);
+        else
+            delta = kick_improve (ncount);
+#else
+#ifdef GEOM_FOUR_SWAPS
+        if (random_four_swap (ncount, &kdt, &delta)) {
+            fprintf (stderr, "random_four_swap failed\n");
+            fflush (stdout);
+            CCkdtree_free (&kdt);
+            return 1;
+        }
+#else
+        delta = random_four_swap (ncount);
+#endif /* GEOM_FOUR_SWAPS */
+#endif /* IMPROVE_FOUR_SWAPS */
+
+#if defined(CC_NO_UNDO_SEGMENTS_FLIPPER) || defined(CC_FULL_SEGMENTS_FLIPPER)
+        {
+            int fi;
+            CClinkern_flipper_reset_perm (0);  /* For Quick Flips */
+            for (fi = 0; fi < flip_counter; fi++) {
+                CClinkern_flipper_flip_perm (flipstack[fi].first,
+                                   flipstack[fi].last);
+            }
+            CClinkern_flipper_reset_perm (1);
+        }
+#endif
+        flip_counter = 0;
+        t = best + delta;
+
+        if (lin_kernighan (ncount, &t)) {
+            fprintf (stderr, "lin_kernighan failed\n");
+#ifdef GEOM_FOUR_SWAPS
+            if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE)
+                CCkdtree_free (&kdt);
+#endif
+            return 1;
+        }
+
+#ifdef ACCEPT_BAD_TOURS
+        if (round % HEAT_RESET == HEAT_RESET - 1) {
+            heat = oldbest / (HEAT_MULT * ncount);
+            printf ("Reset Accept-Probablility\n");
+            fflush (stdout);
+        }
+        tdelta = t - best;
+        heat *= HEAT_FACTOR;
+        if (t < best || (t > best && exp (-tdelta/heat) >
+                   (double) (CCutil_lprand () % ncount) / (double) ncount)) {
+#else
+#ifdef ACCEPT_TIES
+        if (t <= best) {
+#else
+        if (t < best) {
+#endif /* ACCEPT_TIES */
+#endif /* ACCEPT_BAD_TOURS */
+#ifdef CC_USE_FLIP_CLEANING
+#ifdef CC_FULL_SEGMENTS_FLIPPER
+            {
+                int i;
+
+                if (flip_counter > 0) {
+                    if (flip_counter < new_tour_cutoff) {
+                        for (i = 0; i < flip_counter; i++)
+                            CClinkern_flipper_flip_perm (flipstack[i].first,
+                                               flipstack[i].last);
+                        CClinkern_flipper_reset_perm (1);
+                    } else {
+                        CClinkern_flipper_reset_temp (ncount);
+                    }
+                    flip_counter = 0;
+                }
+            }
+#endif  /* CC_FULL_SEGMENTS_FLIPPER */
+            win_counter = 0;
+            win_cycle[0] = -1;
+#else
+            CClinkern_flipper_cycle (cyc);
+            CClinkern_flipper_finish ();
+#endif
+            if (t < best) {
+                best = t;
+                quitcount = round + stallcount;
+                if (quitcount > count)
+                    quitcount = count;
+                hit++;
+            }
+#ifdef ACCEPT_BAD_TOURS
+            else {
+                if (!no_output && t > best) {
+                    printf ("%d Steps   Best: %.0f   %.2f seconds (Negative %.0f) (%.0f)\n",
+                          round, t, CCutil_zeit () - szeit, t - best, oldbest);
+                    fflush (stdout);
+                }
+                best = t;
+            }
+#endif
+        } else {
+#ifdef CC_USE_FLIP_CLEANING
+#ifdef CC_FULL_SEGMENTS_FLIPPER
+            {
+                /* WON'T WORK WITH IMPROVE_FOUR_SWAPS */
+                int i;
+                for (i = 2; i >= 0; i--) {
+                    CClinkern_flipper_flip_perm (winstack[i].last,
+                                       winstack[i].first);
+                }
+            }
+            CClinkern_flipper_reset_perm (1);
+            win_cycle[0] = -1;
+            win_counter = 0;
+#else
+            if (win_cycle[0] == -1) {
+                while (win_counter) {
+                    win_counter--;
+#ifdef CC_EXTRA_INFO_FLIP
+                    CClinkern_flipper_flip (winstack[win_counter].firstprev,
+                                  winstack[win_counter].last,
+                                  winstack[win_counter].first,
+                                  winstack[win_counter].lastnext);
+#else
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+                    CClinkern_flipper_flip_perm (winstack[win_counter].last,
+                                  winstack[win_counter].first);
+#else
+                    CClinkern_flipper_flip (winstack[win_counter].last,
+                                  winstack[win_counter].first);
+#endif
+#endif  /* CC_EXTRA_INFO_FLIP */
+                }
+            } else {
+                CClinkern_flipper_finish ();
+                CClinkern_flipper_init (ncount, win_cycle);
+                while (win_counter) {
+                    win_counter--;
+#ifdef CC_EXTRA_INFO_FLIP
+                    CClinkern_flipper_flip (winstack[win_counter].firstprev,
+                                  winstack[win_counter].last,
+                                  winstack[win_counter].first,
+                                  winstack[win_counter].lastnext);
+#else
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+                    CClinkern_flipper_flip_perm (winstack[win_counter].last,
+                                  winstack[win_counter].first);
+#else
+                    CClinkern_flipper_flip (winstack[win_counter].last,
+                                  winstack[win_counter].first);
+#endif
+#endif  /* CC_EXTRA_INFO_FLIP */
+                }
+                win_cycle[0] = -1;
+            }
+#ifdef  CC_NO_UNDO_SEGMENTS_FLIPPER
+            CClinkern_flipper_reset_perm (1);
+#endif
+#endif  /* CC_FULL_SEGMENTS_FLIPPER */
+
+#else  /* CC_USE_FLIP_CLEANING */
+            CClinkern_flipper_finish ();
+#endif
+        }
+
+        round++;
+        if (!no_output && (hit || (round % 1000 == 999) || MAX_OUTPUT)) {
+            printf ("%d Steps   Best: %.0f   %.2f seconds\n", round, best,
+                                   CCutil_zeit () - szeit);
+            fflush (stdout);
+        }
+
+#ifdef BIG_PROBLEM
+        if (saveit_name && (round % 10000 == 9999) && best < oldbest) {
+#else
+        if (saveit_name && (round % 100 == 99) && best < oldbest) {
+#endif
+            int *ctemp = (int *) NULL;
+
+            ctemp = CC_SAFE_MALLOC (ncount, int);
+            if (!ctemp) {
+#ifdef GEOM_FOUR_SWAPS
+                if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE)
+                    CCkdtree_free (&kdt);
+#endif
+                return 1;
+            }
+            CClinkern_flipper_cycle (ctemp);
+#ifdef BIG_PROBLEM
+            if (CCutil_writecycle (ncount, saveit_name, ctemp)) {
+#else
+            if (CCutil_writecycle_edgelist (ncount, saveit_name, ctemp, gdat)) {
+#endif
+                fprintf (stderr, "could not write the cycle\n");
+                CC_FREE (ctemp, int);
+#ifdef GEOM_FOUR_SWAPS
+                if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE)
+                    CCkdtree_free (&kdt);
+#endif
+                return 1;
+            }
+            printf ("Wrote the tour to %s\n", saveit_name);
+            fflush (stdout);
+            CC_FREE (ctemp, int);
+            oldbest = best;
+        }
+
+        if (time_bound > 0.0 && (CCutil_zeit () - szeit) > time_bound) {
+            if (!no_output) {
+                printf ("STOP - timebound reached (%.2f seconds)\n",
+                             CCutil_zeit () - szeit);
+                fflush (stdout);
+            } else {
+                printf ("%d Steps\n", round);
+                fflush (stdout);
+            }
+            break;
+        }
+        if (length_bound > 0.0 && best <= length_bound) {
+            if (!no_output) {
+                printf ("STOP - length bound reached (%.0f)\n", length_bound);
+                fflush (stdout);
+            } else {
+                printf ("%d Steps\n", round);
+                fflush (stdout);
+            }
+            break;
+        }
+    }
+    if (!no_output && round > 0) {
+        printf ("%d Total Steps.\n", round);
+        fflush (stdout);
+    }
+
+#ifdef CC_USE_FLIP_CLEANING
+    CClinkern_flipper_cycle (cyc);
+    CClinkern_flipper_finish ();
+#endif
+
+    if (saveit_name && best < oldbest) {
+#ifdef BIG_PROBLEM
+        if (CCutil_writecycle (ncount, saveit_name, cyc)) {
+#else
+        if (CCutil_writecycle_edgelist (ncount, saveit_name, cyc, gdat)) {
+#endif
+            fprintf (stderr, "could not write the cycle\n");
+#ifdef GEOM_FOUR_SWAPS
+            if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE)
+                CCkdtree_free (&kdt);
+#endif
+            return 1;
+        }
+        printf ("Wrote the last tour to %s\n", saveit_name);
+        fflush (stdout);
+    }
+
+    t = cycle_length (ncount, cyc);
+    if (t != best) {
+        printf ("WARNING: LK incremental counter was off by %.0f\n", t - best);
+        fflush (stdout);
+        best = t;
+    }
+
+    *val = best;
+
+#ifdef GEOM_FOUR_SWAPS
+    if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE)
+        CCkdtree_free (&kdt);
+#endif
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lin_kernighan (int ncount, double *val)
+#else
+static int lin_kernighan (ncount, val)
+int ncount;
+double *val;
+#endif
+{
+    int start;
+    double win, totalwin = 0.0;
+    intptr *ip;
+
+    if (ncount < 0) {
+        printf ("Bad ncount: %d\n", ncount);
+        return 1;
+    }
+
+    while (active_queue) {
+        ip = active_queue;
+        start = ip->this;
+        active_queue = ip->next;
+        if (ip == bottom_active_queue)
+            bottom_active_queue = (intptr *) NULL;
+        intptrfree (ip);
+        active[start] = 0;
+
+        win = improve_tour (start);
+        if (win > 0.0) {
+            totalwin += win;
+            if (flip_counter >= new_tour_time) {
+#if defined(CC_NO_UNDO_SEGMENTS_FLIPPER) || defined(CC_FULL_SEGMENTS_FLIPPER)
+                {
+                    int i;
+
+                    if (flip_counter < new_tour_cutoff) {
+                        CClinkern_flipper_reset_perm (0);  /* QUICK FLIPS */
+                        for (i = 0; i < flip_counter; i++)
+                            CClinkern_flipper_flip_perm (flipstack[i].first,
+                                               flipstack[i].last);
+                        CClinkern_flipper_reset_perm (1);
+                    } else {
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+                        CClinkern_flipper_reset_perm (1);
+                        for (i = 0; i < flip_counter; i++)
+                            CClinkern_flipper_flip (flipstack[i].first,
+                                          flipstack[i].last);
+#endif
+                        CClinkern_flipper_reset_temp (ncount);
+                    }
+                }
+#endif
+#ifdef CC_USE_FLIP_CLEANING
+                {
+                    if (win_counter < winstack_max) {
+                        int i;
+                        for (i = 0; i < flip_counter; i++) {
+                            winstack[win_counter].first = flipstack[i].first;
+                            winstack[win_counter].last = flipstack[i].last;
+#ifdef CC_EXTRA_INFO_FLIP
+                            winstack[win_counter].firstprev =
+                                     flipstack[i].firstprev;
+                            winstack[win_counter].lastnext =
+                                     flipstack[i].lastnext;
+#endif
+                            win_counter++;
+                        }
+                    } else if (win_cycle[0] == -1) {
+                        int i;
+                        for (i = 0; i < flip_counter; i++) {
+                            winstack[win_counter].first = flipstack[i].first;
+                            winstack[win_counter].last = flipstack[i].last;
+#ifdef CC_EXTRA_INFO_FLIP
+                            winstack[win_counter].firstprev =
+                                     flipstack[i].firstprev;
+                            winstack[win_counter].lastnext =
+                                     flipstack[i].lastnext;
+#endif
+                            win_counter++;
+                        }
+                        CClinkern_flipper_cycle (win_cycle);
+                    }
+                }
+#endif
+#ifdef CC_SEGMENTS_FLIPPER
+                CClinkern_flipper_reset_temp (ncount);
+#endif
+                flip_counter = 0;
+            }
+            if (MAX_OUTPUT && !no_output) {
+                printf (".");
+                fflush (stdout);
+            }
+        }
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+          else {
+            CClinkern_flipper_reset_perm (0);
+        }
+#endif
+    }
+
+#ifdef CC_USE_FLIP_CLEANING
+    {
+        if (win_cycle[0] == -1) {
+            int i;
+            for (i = 0; i < flip_counter; i++) {
+                winstack[win_counter].first = flipstack[i].first;
+                winstack[win_counter].last = flipstack[i].last;
+#ifdef CC_EXTRA_INFO_FLIP
+                winstack[win_counter].firstprev = flipstack[i].firstprev;
+                winstack[win_counter].lastnext = flipstack[i].lastnext;
+#endif
+                win_counter++;
+            }
+        }
+    }
+#endif
+
+    (*val) -= totalwin;
+
+    if (MAX_OUTPUT && !no_output) {
+        printf ("\nCYCLE LENGTH: %.0f\n", *val);
+        fflush (stdout);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double improve_tour (int t1)
+#else
+static double improve_tour (t1)
+int t1;
+#endif
+{
+    int t2 = CClinkern_flipper_next (t1);
+    int G, Gstar = 0;
+
+    G = Edgelen (t1, t2);
+
+    markedge_del (t1, t2);
+
+
+    if (!step (0, G, &Gstar, t1, t2)) {
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+        CClinkern_flipper_reset_perm (0);
+#endif
+        Gstar = weird_second_step (G, t1, t2);
+    }
+    unmarkedge_del (t1, t2);
+
+    if (Gstar) {
+        turn (t1);
+        turn (t2);
+    }
+    return (double) Gstar;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int step (int level, int G, int *Gstar, int first, int last)
+#else
+static int step (level, G, Gstar, first, last)
+int level, G, *Gstar;
+int first, last;
+#endif
+{
+    int val, hit = 0, oldG = G;
+    int this, newlast;
+#if defined(MAK_MORTON) && defined(FULL_MAK_MORTON)
+    int newfirst;
+#endif
+    edgelook *list, *e;
+
+    if (level >= BACKTRACK)
+        return step_noback (level, G, Gstar, first, last);
+
+    list = look_ahead (first, last, G, level);
+    for (e = list; e; e = e->next) {
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+        if (e != list) {
+            int i;
+            CClinkern_flipper_reset_perm (0);
+            for (i = 0; i < flip_counter; i++)
+                CClinkern_flipper_flip (flipstack[i].first, flipstack[i].last);
+        }
+#endif
+#if defined(MAK_MORTON) && defined(FULL_MAK_MORTON)
+        if (e->mm) {
+            this = e->other;
+            newfirst = e->over;
+
+            G = oldG - e->diff;
+            val = G - Edgelen (newfirst, last);
+            if (val > *Gstar) {
+                *Gstar = val;
+                hit++;
+            }
+            FLIP (this, newfirst, first, last, 22220);
+
+            if (level < MAXDEPTH) {
+                markedge_add (first, this);
+                markedge_del (this, newfirst);
+                hit += step (level + 1, G, Gstar, newfirst, last);
+                unmarkedge_add (first, this);
+                unmarkedge_del (this, newfirst);
+            }
+
+            if (!hit) {
+                UNFLIP (this, newfirst, first, last, 9910);
+            } else {
+                turn (this);
+                turn (newfirst);
+                edgelook_list_free (list);
+                return 1;
+            }
+        } else
+#endif
+        {
+            this = e->other;
+            newlast = e->over;
+
+            G = oldG - e->diff;
+            val = G - Edgelen (newlast, first);
+            if (val > *Gstar) {
+                *Gstar = val;
+                hit++;
+            }
+
+            FLIP (first, last, newlast, this, 2222);
+
+            if (level < MAXDEPTH) {
+                markedge_add (last, this);
+                markedge_del (this, newlast);
+                hit += step (level + 1, G, Gstar, first, newlast);
+                unmarkedge_add (last, this);
+                unmarkedge_del (this, newlast);
+            }
+
+            if (!hit) {
+                UNFLIP (first, last, newlast, this, 991);
+            } else {
+                turn (this);
+                turn (newlast);
+                edgelook_list_free (list);
+                return 1;
+            }
+        }
+    }
+    edgelook_list_free (list);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int step_noback (int level, int G, int *Gstar, int first, int last)
+#else
+static int step_noback (level, G, Gstar, first, last)
+int level, G, *Gstar;
+int first, last;
+#endif
+{
+    edgelook e;
+
+#ifdef    SUBTRACT_GSTAR
+#ifdef    SWITCH_LATE_DEPTH
+    if (level < LATE_DEPTH)
+        look_ahead_noback (first, last, G - *Gstar, &e);
+    else
+        look_ahead_noback (first, last, G - *Gstar - level, &e);
+#else
+    look_ahead_noback (first, last, G - *Gstar - level, &e);
+#endif /* SWITCH_LATE_DEPTH */
+#else
+#ifdef    SWITCH_LATE_DEPTH
+    if (level < LATE_DEPTH)
+        look_ahead_noback (first, last, G, &e);
+    else
+        look_ahead_noback (first, last, G - level, &e);
+#else
+    look_ahead_noback (first, last, G - level, &e);
+#endif /* SWITCH_LATE_DEPTH */
+#endif /* SUBTRACT_GSTAR */
+
+    if (e.diff < BIGINT) {
+#ifdef NODE_INSERTIONS
+        if (e.ni) {
+            int hit = 0;
+            int newlast = e.other;
+            int next = e.under;
+            int prev = e.over;
+            int val;
+
+            G -= e.diff;
+            val = G - Edgelen (newlast, first);
+
+            if (val > *Gstar) {
+                *Gstar = val;
+                hit++;
+            }
+
+            FLIP (first, last, newlast, next, 222211);
+            FLIP (newlast, prev, last, next, 222212);
+
+            if (level < MAXDEPTH) {
+                markedge_add (last, newlast);
+                markedge_add (next, prev);
+                markedge_del (newlast, prev);
+                markedge_del (newlast, next);
+                hit += step_noback (level + 1, G, Gstar, first, newlast);
+                unmarkedge_add (last, newlast);
+                unmarkedge_add (next, prev);
+                unmarkedge_del (newlast, prev);
+                unmarkedge_del (newlast, next);
+            }
+
+            if (!hit) {
+                UNFLIP (newlast, prev, last, next, 222214);
+                UNFLIP (first, last, newlast, next, 222213);
+                return 0;
+            } else {
+                turn (newlast);
+                turn (next);
+                turn (prev);
+                return 1;
+            }
+        } else
+#endif /* NODE_INSERTIONS */
+        {
+#ifdef MAK_MORTON
+            if (e.mm) {
+                int hit = 0;
+                int this = e.other;
+                int newfirst = e.over;
+                int val;
+
+                G -= e.diff;
+                val = G - Edgelen (newfirst, last);
+                if (val > *Gstar) {
+                    *Gstar = val;
+                    hit++;
+                }
+                FLIP (this, newfirst, first, last, 22220);
+
+                if (level < MAXDEPTH) {
+                    markedge_add (first, this);
+                    markedge_del (this, newfirst);
+                    hit += step_noback (level + 1, G, Gstar, newfirst, last);
+                    unmarkedge_add (first, this);
+                    unmarkedge_del (this, newfirst);
+                }
+
+                if (!hit) {
+                    UNFLIP (this, newfirst, first, last, 9910);
+                    return 0;
+                } else {
+                    turn (this);
+                    turn (newfirst);
+                    return 1;
+                }
+            } else
+#endif  /* MAK_MORTON */
+            {
+                int hit = 0;
+                int this = e.other;
+                int newlast = e.over;
+                int val;
+
+                G -= e.diff;
+                val = G - Edgelen (newlast, first);
+                if (val > *Gstar) {
+                    *Gstar = val;
+                    hit++;
+                }
+
+                FLIP (first, last, newlast, this, 2222);
+
+                if (level < MAXDEPTH) {
+                    markedge_add (last, this);
+                    markedge_del (this, newlast);
+                    hit += step_noback (level + 1, G, Gstar, first, newlast);
+                    unmarkedge_add (last, this);
+                    unmarkedge_del (this, newlast);
+                }
+
+                if (!hit) {
+                    UNFLIP (first, last, newlast, this, 991);
+                    return 0;
+                } else {
+                    turn (this);
+                    turn (newlast);
+                    return 1;
+                }
+            }
+        }
+    } else {
+        return 0;
+    }
+}
+
+#ifdef IMPROVE_FOUR_SWAPS
+#ifdef CC_PROTOTYPE_ANSI
+static double kick_improve (int ncount)
+#else
+static double kick_improve (ncount)
+int ncount;
+#endif
+{
+    int t1, t2;
+    int G, Gstar = 0;
+    int hit = 0;
+
+    do {
+#ifdef LONG_KICKER
+        first_long_kicker (ncount, &t1, &t2);
+#else
+        t1 = CCutil_lprand () % ncount;
+        t2 = CClinkern_flipper_next (t1);
+#endif
+        G = Edgelen (t1, t2);
+        markedge_del (t1, t2);
+        hit = kick_step_noback (0, G, &Gstar, t1, t2);
+        unmarkedge_del (t1, t2);
+    } while (!hit);
+
+    kickturn (t1);
+    kickturn (t2);
+
+    return (double) -Gstar;
+}
+
+#define G_MULT 1.5
+
+#ifdef CC_PROTOTYPE_ANSI
+static int kick_step_noback (int level, int G, int *Gstar, int first, int last)
+#else
+static int kick_step_noback (level, G, Gstar, first, last)
+int level, G, *Gstar;
+int first, last;
+#endif
+{
+    edgelook winner;
+    int val;
+    int this, prev, newlast;
+    int lastnext = CClinkern_flipper_next (last);
+    int i;
+    int cutoff = (int) (G_MULT * (double) G);
+
+    /* NOTE: not set up for fixed edges */
+
+    winner.diff = BIGINT;
+    for (i = 0; goodlist[last][i].weight < cutoff; i++) {
+        this = goodlist[last][i].other;
+        if (!is_it_deleted (last, this) && this != first && this != lastnext) {
+            prev = CClinkern_flipper_prev (this);
+            if (!is_it_added (this, prev)) {
+                val = goodlist[last][i].weight - Edgelen (this, prev);
+                if (val < winner.diff) {
+                    winner.diff = val;
+                    winner.other = this;
+                    winner.over = prev;
+                }
+            }
+        }
+    }
+
+    if (winner.diff < BIGINT) {
+        this = winner.other;
+        newlast = winner.over;
+        G -= winner.diff;
+        *Gstar = G - Edgelen (newlast, first);
+
+        FLIP (first, last, newlast, this, 2222);
+        kickturn (this);
+        kickturn (newlast);
+#ifdef CC_USE_FLIP_CLEANING
+        if (win_counter < winstack_max) {
+            winstack[win_counter].first = last;
+            winstack[win_counter].last = newlast;
+#ifdef CC_EXTRA_INFO_FLIP
+            winstack[win_counter].firstprev = first;
+            winstack[win_counter].lastnext = this;
+#endif
+            win_counter++;
+        }
+#endif
+
+        if (level < KICK_MAXDEPTH) {
+            markedge_add (last, this);
+            markedge_del (this, newlast);
+            kick_step_noback (level + 1, G, Gstar, first, newlast);
+            unmarkedge_add (last, this);
+            unmarkedge_del (this, newlast);
+        }
+        return 1;
+    } else {
+        return 0;
+    }
+}
+#endif /* IMPROVE_FOUR_SWAPS */
+
+#ifdef CC_PROTOTYPE_ANSI
+static int weird_second_step (int len_t1_t2, int t1, int t2)
+#else
+static int weird_second_step (len_t1_t2, t1, t2)
+int len_t1_t2, t1, t2;
+#endif
+{
+    int t3, t4, t5, t6, t7, t8;
+    int oldG, G, tG, Gstar = 0, val, hit;
+    int t4next;
+    edgelook *e, *f, *h, *list, *list2, *list3;
+
+    list = weird_look_ahead (len_t1_t2, t1, t2);
+    for (h = list; h; h = h->next) {
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+        if (h != list) {
+            int i;
+            CClinkern_flipper_reset_perm (0);
+            for (i = 0; i < flip_counter; i++)
+                CClinkern_flipper_flip (flipstack[i].first, flipstack[i].last);
+        }
+#endif
+        t3 = h->other;
+        t4 = h->over;
+
+        oldG = len_t1_t2 - h->diff;
+        t4next = CClinkern_flipper_next (t4);
+
+        markedge_add (t2, t3);
+        markedge_del (t3, t4);
+        weirdmagic++;
+        weirdmark[t1] = weirdmagic;
+        weirdmark[t2] = weirdmagic;
+        weirdmark[t3] = weirdmagic;
+        weirdmark[t4next] = weirdmagic;
+
+        list2 = weird_look_ahead2 (oldG, t2, t3, t4);
+        for (e = list2; e; e = e->next) {
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+            if (e != list2) {
+                int i;
+                CClinkern_flipper_reset_perm (0);
+                for (i = 0; i < flip_counter; i++)
+                    CClinkern_flipper_flip (flipstack[i].first, flipstack[i].last);
+            }
+#endif
+            t5 = e->other;
+            t6 = e->over;
+
+            markedge_add (t4, t5);
+            if (e->seq) {
+                if (!e->side) {
+                    G = oldG - e->diff;
+                    val = G - Edgelen (t6, t1);
+                    if (val > Gstar)
+                        Gstar = val;
+                    FLIP (t1, t2, t6, t5, 3);
+                    FLIP (t2, t5, t3, t4, 4);
+
+                    markedge_del (t5, t6);
+                    hit = step (2, G, &Gstar, t1, t6);
+                    unmarkedge_del (t5, t6);
+
+                    if (!hit && Gstar)
+                        hit = 1;
+
+                    if (!hit) {
+                        UNFLIP (t2, t5, t3, t4, 992);
+                        UNFLIP (t1, t2, t6, t5, 993);
+                    } else {
+                        unmarkedge_add (t2, t3);
+                        unmarkedge_del (t3, t4);
+                        unmarkedge_add (t4, t5);
+                        turn (t3); turn (t4);
+                        turn (t5); turn (t6);
+                        edgelook_list_free (list);
+                        edgelook_list_free (list2);
+                        return Gstar;
+                    }
+                } else {
+                    G = oldG - e->diff;
+                    val = G - Edgelen (t6, t1);
+                    if (val > Gstar)
+                        Gstar = val;
+                    FLIP (t1, t2, t3, t4, 5000);
+                    FLIP (t6, t5, t2, t4, 6);
+                    FLIP (t1, t3, t6, t2, 7);
+
+                    markedge_del (t5, t6);
+                    hit = step (2, G, &Gstar, t1, t6);
+                    unmarkedge_del (t5, t6);
+
+                    if (!hit && Gstar)
+                        hit = 1;
+
+                    if (!hit) {
+                        UNFLIP (t1, t3, t6, t2, 994);
+                        UNFLIP (t6, t5, t2, t4, 995);
+                        UNFLIP (t1, t2, t3, t4, 996);
+                    } else {
+                        unmarkedge_add (t2, t3);
+                        unmarkedge_del (t3, t4);
+                        unmarkedge_add (t4, t5);
+                        turn (t3); turn (t4);
+                        turn (t5); turn (t6);
+                        edgelook_list_free (list);
+                        edgelook_list_free (list2);
+                        return Gstar;
+                    }
+                }
+            } else {
+                tG = oldG - e->diff;
+                markedge_del (t5, t6);
+                list3 = weird_look_ahead3 (tG, t2, t3, t6);
+                for (f = list3; f; f = f->next) {
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+                    if (f != list3) {
+                        int i;
+                        CClinkern_flipper_reset_perm (0);
+                        for (i = 0; i < flip_counter; i++)
+                            CClinkern_flipper_flip (flipstack[i].first,
+                                          flipstack[i].last);
+                    }
+#endif
+                    t7 = f->other;
+                    t8 = f->over;
+
+                    G = tG - f->diff;
+                    if (!f->side) {
+                        val = G - Edgelen (t8, t1);
+                        if (val > Gstar)
+                            Gstar = val;
+                        FLIP (t1, t2, t8, t7, 8);
+                        FLIP (t2, t7, t3, t4, 9);
+                        FLIP (t7, t4, t6, t5, 10);
+
+                        markedge_add (t6, t7);
+                        markedge_del (t7, t8);
+                        hit = step (3, G, &Gstar, t1, t8);
+                        unmarkedge_del (t6, t7);
+                        unmarkedge_del (t7, t8);
+
+                        if (!hit && Gstar)
+                            hit = 1;
+
+                        if (!hit) {
+                            UNFLIP (t7, t4, t6, t5, 997);
+                            UNFLIP (t2, t7, t3, t4, 998);
+                            UNFLIP (t1, t2, t8, t7, 999);
+                        } else {
+                            unmarkedge_add (t2, t3);
+                            unmarkedge_del (t3, t4);
+                            unmarkedge_add (t4, t5);
+                            unmarkedge_del (t5, t6);
+                            turn (t3); turn (t4); turn (t5);
+                            turn (t6); turn (t7); turn (t8);
+                            edgelook_list_free (list);
+                            edgelook_list_free (list2);
+                            edgelook_list_free (list3);
+                            return Gstar;
+                        }
+                    } else {
+                        val = G - Edgelen (t8, t1);
+                        if (val > Gstar)
+                            Gstar = val;
+                        FLIP (t1, t2, t6, t5, 11);
+                        FLIP (t1, t6, t8, t7, 12);
+                        FLIP (t3, t4, t2, t5, 13);
+
+                        markedge_add (t6, t7);
+                        markedge_del (t7, t8);
+                        hit = step (3, G, &Gstar, t1, t8);
+                        unmarkedge_add (t6, t7);
+                        unmarkedge_del (t7, t8);
+
+                        if (!hit && Gstar)
+                            hit = 1;
+
+                        if (!hit) {
+                            UNFLIP (t3, t4, t2, t5, 9910);
+                            UNFLIP (t1, t6, t8, t7, 9911);
+                            UNFLIP (t1, t2, t6, t5, 9912);
+                        } else {
+                            unmarkedge_add (t2, t3);
+                            unmarkedge_del (t3, t4);
+                            unmarkedge_add (t4, t5);
+                            unmarkedge_del (t5, t6);
+                            turn (t3); turn (t4); turn (t5);
+                            turn (t6); turn (t7); turn (t8);
+                            edgelook_list_free (list);
+                            edgelook_list_free (list2);
+                            edgelook_list_free (list3);
+                            return Gstar;
+                        }
+                    }
+                }
+                edgelook_list_free (list3);
+                unmarkedge_del (t5, t6);
+            }
+            unmarkedge_add (t4, t5);
+        }
+        edgelook_list_free (list2);
+        unmarkedge_add (t2, t3);
+        unmarkedge_del (t3, t4);
+    }
+    edgelook_list_free (list);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static edgelook *look_ahead (int first, int last, int G, int level)
+#else
+static edgelook *look_ahead (first, last, G, level)
+int first, last;
+int G, level;
+#endif
+{
+    edgelook *list = (edgelook *) NULL, *el;
+    int i, val;
+    int this, prev;
+    int lastnext = CClinkern_flipper_next (last);
+    int other[MAX_BACK], save[MAX_BACK];
+    int value[MAX_BACK + 1];
+#if defined(MAK_MORTON) && defined(FULL_MAK_MORTON)
+    int mm[MAX_BACK];
+#endif
+    int k, ahead = backtrack_count[level];
+
+    for (i = 0; i < ahead; i++) {
+        value[i] = BIGINT;
+#if defined(MAK_MORTON) && defined(FULL_MAK_MORTON)
+        mm[i] = 0;
+#endif
+    }
+    value[ahead] = -BIGINT;
+
+#ifdef USE_LESS_OR_EQUAL
+    for (i = 0; goodlist[last][i].weight <= G; i++) {
+#else
+    for (i = 0; goodlist[last][i].weight < G; i++) {
+#endif
+        this = goodlist[last][i].other;
+        if (!is_it_deleted (last, this) && this != first && this != lastnext) {
+            prev = CClinkern_flipper_prev (this);
+            if (!is_it_added (this, prev)) {
+                val = goodlist[last][i].weight - Edgelen (this, prev);
+                if (val < value[0]) {
+                    for (k = 0; value[k+1] > val; k++) {
+                        value[k] = value[k+1];
+                        other[k] = other[k+1];
+                        save[k] = save[k+1];
+                    }
+                    value[k] = val;
+                    other[k] = this;
+                    save[k] = prev;
+                }
+            }
+        }
+    }
+
+#if defined(MAK_MORTON) && defined(FULL_MAK_MORTON)
+    {
+        int firstprev = CClinkern_flipper_prev (first);
+        int next;
+
+#ifdef USE_LESS_OR_EQUAL
+        for (i = 0; goodlist[first][i].weight <= G; i++) {
+#else
+        for (i = 0; goodlist[first][i].weight < G; i++) {
+#endif
+            this = goodlist[first][i].other;
+            if (!is_it_deleted (first, this) && this != last &&
+                                                this != firstprev) {
+                next = CClinkern_flipper_next (this);
+                if (!is_it_added (this, next)) {
+                    val = goodlist[first][i].weight - Edgelen (this, next);
+                    if (val < value[0]) {
+                        for (k = 0; value[k+1] > val; k++) {
+                            value[k] = value[k+1];
+                            other[k] = other[k+1];
+                            save[k] = save[k+1];
+                            mm[k] = mm[k+1];
+                        }
+                        value[k] = val;
+                        other[k] = this;
+                        save[k] = next;
+                        mm[k] = 1;
+                    }
+                }
+            }
+        }
+    }
+#endif
+
+    for (i = 0; i < ahead; i++) {
+        if (value[i] < BIGINT) {
+            el = edgelookalloc ();
+            el->diff = value[i];
+            el->other = other[i];
+            el->over = save[i];
+            el->next = list;
+#if defined(MAK_MORTON) && defined(FULL_MAK_MORTON)
+            el->mm = mm[i];
+#endif
+            list = el;
+        }
+    }
+
+    return list;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void look_ahead_noback (int first, int last, int G, edgelook *winner)
+#else
+static void look_ahead_noback (first, last, G, winner)
+int first, last;
+int G;
+edgelook *winner;
+#endif
+{
+    int val;
+    int this, prev;
+    int lastnext = CClinkern_flipper_next (last);
+    int i;
+#if defined(MAK_MORTON) || defined(NODE_INSERTIONS)
+    int next;
+#endif
+
+    winner->diff = BIGINT;
+    for (i = 0; goodlist[last][i].weight < G; i++) {
+        this = goodlist[last][i].other;
+        if (!is_it_deleted (last, this) && this != first && this != lastnext) {
+            prev = CClinkern_flipper_prev (this);
+            if (!is_it_added (this, prev)) {
+                val = goodlist[last][i].weight - Edgelen (this, prev);
+                if (val < winner->diff) {
+                    winner->diff = val;
+                    winner->other = this;
+                    winner->over = prev;
+#ifdef MAK_MORTON
+                    winner->mm = 0;
+#endif
+#ifdef NODE_INSERTIONS
+                    winner->ni = 0;
+#endif
+                }
+#ifdef NODE_INSERTIONS
+                next =  CClinkern_flipper_next (this);
+                if (!is_it_added (this, next) && !is_it_deleted (prev, next)) {
+                    val += (Edgelen (next, prev) - Edgelen (this, next));
+                    if (val < winner->diff) {
+                        winner->diff = val;
+                        winner->other = this;
+                        winner->over = prev;
+                        winner->under = next;
+                        winner->ni = 1;
+                    }
+                }
+#endif
+            }
+        }
+    }
+#ifdef MAK_MORTON
+    {
+        int firstprev = CClinkern_flipper_prev (first);
+
+        for (i = 0; goodlist[first][i].weight < G; i++) {
+            this = goodlist[first][i].other;
+            if (!is_it_deleted (first, this) && this != last &&
+                                                this != firstprev) {
+                next = CClinkern_flipper_next (this);
+                if (!is_it_added (this, next)) {
+                    val = goodlist[first][i].weight - Edgelen (this, next);
+                    if (val < winner->diff) {
+                        winner->diff = val;
+                        winner->other = this;
+                        winner->over = next;
+                        winner->mm = 1;
+#ifdef NODE_INSERTIONS
+                        winner->ni = 0;
+#endif
+                    }
+                }
+            }
+        }
+    }
+#endif
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static edgelook *weird_look_ahead (int G, int t1, int t2)
+#else
+static edgelook *weird_look_ahead (G, t1, t2)
+int G, t1, t2;
+#endif
+{
+    edgelook *list, *el;
+    int i, this, next;
+    int other[MAX_BACK], save[MAX_BACK];
+    int value[MAX_BACK + 1];
+    int k, val, ahead;
+
+
+    list = (edgelook *) NULL;
+    ahead = weird_backtrack_count[0];
+    for (i = 0; i < ahead; i++)
+        value[i] = BIGINT;
+    value[ahead] = -BIGINT;
+
+#ifdef USE_LESS_OR_EQUAL
+    for (i = 0; goodlist[t2][i].weight <= G; i++) {
+#else
+    for (i = 0; goodlist[t2][i].weight < G; i++) {
+#endif
+        this = goodlist[t2][i].other;
+        if (this != t1) {
+            next = CClinkern_flipper_next (this);
+            val = goodlist[t2][i].weight - Edgelen (this, next);
+            if (val < value[0]) {
+                for (k = 0; value[k+1] > val; k++) {
+                    value[k] = value[k+1];
+                    other[k] = other[k+1];
+                    save[k] = save[k+1];
+                }
+                value[k] = val;
+                other[k] = this;
+            save[k] = next;
+            }
+        }
+    }
+    for (i = 0; i < ahead; i++) {
+        if (value[i] < BIGINT) {
+            el = edgelookalloc ();
+            el->diff = value[i];
+            el->other = other[i];
+            el->over = save[i];
+            el->next = list;
+            list = el;
+        }
+    }
+    return list;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static edgelook *weird_look_ahead2 (int G, int t2, int t3, int t4)
+#else
+static edgelook *weird_look_ahead2 (G, t2, t3, t4)
+int G, t2, t3, t4;
+#endif
+{
+    edgelook *list = (edgelook *) NULL;
+    edgelook *el;
+    int i, t5, t6;
+    int other[MAX_BACK], save[MAX_BACK], seq[MAX_BACK], side[MAX_BACK];
+    int value[MAX_BACK + 1];
+    int k, val;
+    int ahead = weird_backtrack_count[1];
+
+    for (i = 0; i < ahead; i++)
+        value[i] = BIGINT;
+    value[ahead] = -BIGINT;
+
+#ifdef USE_SEQUENCE_BURST
+    CClinkern_flipper_sequence_burst_init (t2, t3);
+#endif
+
+#ifdef USE_LESS_OR_EQUAL
+    for (i = 0; goodlist[t4][i].weight <= G; i++) {
+#else
+    for (i = 0; goodlist[t4][i].weight < G; i++) {
+#endif
+        t5 = goodlist[t4][i].other;
+        if (weirdmark[t5] != weirdmagic) {
+#ifdef USE_SEQUENCE_BURST
+            if (CClinkern_flipper_sequence_burst (t2, t5, t3)) {
+#else
+            if (CClinkern_flipper_sequence (t2, t5, t3)) {
+#endif
+                t6 = CClinkern_flipper_prev (t5);
+                val = goodlist[t4][i].weight - Edgelen (t5, t6);
+                if (val < value[0]) {
+                    for (k = 0; value[k+1] > val; k++) {
+                        value[k] = value[k+1];
+                        other[k] = other[k+1];
+                        save[k] = save[k+1];
+                        seq[k] = seq[k+1];
+                        side[k] = side[k+1];
+                    }
+                    value[k] = val;
+                    other[k] = t5;
+                    save[k] = t6;
+                    seq[k] = 1;
+                    side[k] = 0;
+                }
+                t6 = CClinkern_flipper_next (t5);
+                val = goodlist[t4][i].weight - Edgelen (t5, t6);
+                if (val < value[0]) {
+                    for (k = 0; value[k+1] > val; k++) {
+                        value[k] = value[k+1];
+                        other[k] = other[k+1];
+                        save[k] = save[k+1];
+                        seq[k] = seq[k+1];
+                        side[k] = side[k+1];
+                    }
+                    value[k] = val;
+                    other[k] = t5;
+                    save[k] = t6;
+                    seq[k] = 1;
+                    side[k] = 1;
+                }
+            } else {
+                t6 = CClinkern_flipper_prev (t5);
+                val = goodlist[t4][i].weight - Edgelen (t5, t6);
+                if (val < value[0]) {
+                    for (k = 0; value[k+1] > val; k++) {
+                        value[k] = value[k+1];
+                        other[k] = other[k+1];
+                        save[k] = save[k+1];
+                        seq[k] = seq[k+1];
+                        side[k] = side[k+1];
+                    }
+                    value[k] = val;
+                    other[k] = t5;
+                    save[k] = t6;
+                    seq[k] = 0;
+                    side[k] = 0;
+                }
+            }
+        }
+    }
+
+    for (i = 0; i < ahead; i++) {
+        if (value[i] < BIGINT) {
+            el = edgelookalloc ();
+            el->diff = value[i];
+            el->other = other[i];
+            el->over = save[i];
+            el->seq = seq[i];
+            el->side = side[i];
+            el->next = list;
+            list = el;
+        }
+    }
+    return list;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static edgelook *weird_look_ahead3 (int G, int t2, int t3, int t6)
+#else
+static edgelook *weird_look_ahead3 (G, t2, t3, t6)
+int G, t2, t3, t6;
+#endif
+{
+    edgelook *list = (edgelook *) NULL;
+    edgelook *el;
+    int i, t7, t8;
+    int other[MAX_BACK], save[MAX_BACK], side[MAX_BACK];
+    int value[MAX_BACK + 1];
+    int k, val;
+    int ahead = weird_backtrack_count[2];
+
+    for (i = 0; i < ahead; i++)
+        value[i] = BIGINT;
+    value[ahead] = -BIGINT;
+
+#ifdef USE_SEQUENCE_BURST
+    CClinkern_flipper_sequence_burst_init (t2, t3);
+#endif
+
+#ifdef USE_LESS_OR_EQUAL
+    for (i = 0; goodlist[t6][i].weight <= G; i++) {
+#else
+    for (i = 0; goodlist[t6][i].weight < G; i++) {
+#endif
+        t7 = goodlist[t6][i].other;   /* Need t7 != t2, t3, t2next, t3prev */
+        if (weirdmark[t7] != weirdmagic &&
+#ifdef USE_SEQUENCE_BURST
+                             CClinkern_flipper_sequence_burst (t2, t7, t3)) {
+#else
+                             CClinkern_flipper_sequence (t2, t7, t3)) {
+#endif
+            t8 = CClinkern_flipper_prev (t7);
+            val = goodlist[t6][i].weight - Edgelen (t7, t8);
+            if (val < value[0]) {
+                for (k = 0; value[k+1] > val; k++) {
+                    value[k] = value[k+1];
+                    other[k] = other[k+1];
+                    save[k] = save[k+1];
+                    side[k] = side[k+1];
+                }
+                value[k] = val;
+                other[k] = t7;
+                save[k] = t8;
+                side[k] = 0;
+            }
+            t8 = CClinkern_flipper_next (t7);
+            val = goodlist[t6][i].weight - Edgelen (t7, t8);
+            if (val < value[0]) {
+                for (k = 0; value[k+1] > val; k++) {
+                    value[k] = value[k+1];
+                    other[k] = other[k+1];
+                    save[k] = save[k+1];
+                    side[k] = side[k+1];
+                }
+                value[k] = val;
+                other[k] = t7;
+                save[k] = t8;
+                side[k] = 1;
+            }
+        }
+    }
+
+    for (i = 0; i < ahead; i++) {
+        if (value[i] < BIGINT) {
+            el = edgelookalloc ();
+            el->diff = value[i];
+            el->other = other[i];
+            el->over = save[i];
+            el->side = side[i];
+            el->next = list;
+            list = el;
+        }
+    }
+    return list;
+}
+
+
+
+/********************* misc ********************/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static double cycle_length (int ncount, int *cyc)
+#else
+static double cycle_length (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i;
+    double val = 0;
+
+    for (i = 1; i < ncount; i++)
+        val += (double) Edgelen (cyc[i - 1], cyc[i]);
+    val += (double) Edgelen (cyc[0], cyc[ncount - 1]);
+
+    return val;
+}
+
+#ifdef GEOM_FOUR_SWAPS
+#ifdef CC_PROTOTYPE_ANSI
+static int random_four_swap (int ncount, CCkdtree *kdt, int *delta)
+#else
+static int random_four_swap (ncount, kdt, delta)
+int ncount;
+CCkdtree *kdt;
+int *delta;
+#endif
+#else
+#ifdef CC_PROTOTYPE_ANSI
+static int random_four_swap (int ncount)
+#else
+static int random_four_swap (ncount)
+int ncount;
+#endif
+#endif
+{
+    int t1, t2, t3, t4, t5, t6, t7, t8, temp;
+
+#ifdef GEOM_FOUR_SWAPS
+    if (((gdat->norm) & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        if (find_geometric_four (ncount, kdt, &t1, &t2, &t3, &t4,
+                                              &t5, &t6, &t7, &t8)) {
+            fprintf (stderr, "find_geometric_four failed\n");
+            return 1;
+        }
+    } else {
+        find_close_four (ncount, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8);
+    }
+#else
+#ifdef CLOSE_FOUR_SWAPS
+    find_close_four (ncount, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8);
+#else
+
+#ifdef LONG_KICKER
+    first_long_kicker (ncount, &t1, &t2);
+#else
+    t1 = CCutil_lprand () % ncount;
+    t2 = CClinkern_flipper_next (t1);
+#endif
+
+    do {
+        t3 = CCutil_lprand () % ncount;
+        t4 = CClinkern_flipper_next (t3);
+    } while (t3 == t1 || t3 == t2 || t4 == t1);
+
+    do {
+        t5 = CCutil_lprand () % ncount;
+        t6 = CClinkern_flipper_next (t5);
+    } while (t5 == t1 || t5 == t2 || t5 == t3 || t5 == t4 ||
+             t6 == t1 || t6 == t3);
+
+    do {
+        t7 = CCutil_lprand () % ncount;
+        t8 = CClinkern_flipper_next (t7);
+    } while (t7 == t1 || t7 == t2 ||
+              t7 == t3 || t7 == t4 || t7 == t5 || t7 == t6 || t8 == t1 ||
+              t8 == t3 || t8 == t5 );
+#endif  /* CLOSE_FOUR_SWAPS */
+#endif  /* GEOM_FOUR_SWAPS */
+
+    if (!CClinkern_flipper_sequence (t1, t3, t5)) {
+        SWAP (t3, t5, temp);
+        SWAP (t4, t6, temp);
+    }
+    if (!CClinkern_flipper_sequence (t1, t5, t7)) {
+        SWAP (t5, t7, temp);
+        SWAP (t6, t8, temp);
+        if (!CClinkern_flipper_sequence (t1, t3, t5)) {
+            SWAP (t3, t5, temp);
+            SWAP (t4, t6, temp);
+        }
+    }
+    FLIP (t1, t2, t5, t6, 20);
+    FLIP (t4, t3, t7, t8, 21);
+    FLIP (t1, t5, t6, t2, 22);
+
+#ifdef CC_USE_FLIP_CLEANING
+    if (win_counter < winstack_max) {
+        winstack[win_counter].first = t2;
+        winstack[win_counter].last = t5;
+#ifdef CC_EXTRA_INFO_FLIP
+        winstack[win_counter].firstprev = t1;
+        winstack[win_counter].lastnext = t6;
+#endif
+        win_counter++;
+    }
+    if (win_counter < winstack_max) {
+        winstack[win_counter].first = t3;
+        winstack[win_counter].last = t7;
+#ifdef CC_EXTRA_INFO_FLIP
+        winstack[win_counter].firstprev = t4;
+        winstack[win_counter].lastnext = t8;
+#endif
+        win_counter++;
+    }
+    if (win_counter < winstack_max) {
+        winstack[win_counter].first = t5;
+        winstack[win_counter].last = t6;
+#ifdef CC_EXTRA_INFO_FLIP
+        winstack[win_counter].firstprev = t1;
+        winstack[win_counter].lastnext = t2;
+#endif
+        win_counter++;
+    }
+#endif /* CC_USE_FLIP_CLEANING */
+
+    bigturn (t1, 0);
+    bigturn (t2, 1);
+    bigturn (t3, 0);
+    bigturn (t4, 1);
+    bigturn (t5, 0);
+    bigturn (t6, 1);
+    bigturn (t7, 0);
+    bigturn (t8, 1);
+
+#ifdef GEOM_FOUR_SWAPS
+    *delta =
+           Edgelen (t1, t6) + Edgelen (t2, t5) +
+           Edgelen (t3, t8) + Edgelen (t4, t7) -
+           Edgelen (t1, t2) - Edgelen (t3, t4) -
+           Edgelen (t5, t6) - Edgelen (t7, t8);
+    return 0;
+
+#else
+    return Edgelen (t1, t6) + Edgelen (t2, t5) +
+           Edgelen (t3, t8) + Edgelen (t4, t7) -
+           Edgelen (t1, t2) - Edgelen (t3, t4) -
+           Edgelen (t5, t6) - Edgelen (t7, t8);
+#endif
+}
+
+#ifdef LONG_KICKER
+#define HUNT_PORTION_LONG 0.001
+
+#ifdef CC_PROTOTYPE_ANSI
+static void first_long_kicker (int ncount, int *t1, int *t2)
+#else
+static void first_long_kicker (ncount, t1, t2)
+int ncount;
+int *t1, *t2;
+#endif
+{
+    int longcount = (int) ((double) ncount * HUNT_PORTION_LONG) + 10;
+    int i, best, try, len, next, prev, nextl, prevl;
+
+    try = CCutil_lprand () % ncount;
+    next = CClinkern_flipper_next (try);
+    prev = CClinkern_flipper_prev (try);
+    nextl = Edgelen (try, next);
+    prevl = Edgelen (try, prev);
+    if (nextl >= prevl) {
+        *t1 = try;
+        *t2 = next;
+        best = nextl - goodlist[*t1][0].weight;
+    } else {
+        *t1 = prev;
+        *t2 = try;
+        best = prevl - goodlist[*t1][0].weight;
+    }
+
+    for (i = 0; i < longcount; i++) {
+        try = CCutil_lprand () % ncount;
+        next = CClinkern_flipper_next (try);
+        prev = CClinkern_flipper_prev (try);
+        nextl = Edgelen (try, next);
+        prevl = Edgelen (try, prev);
+        if (nextl >= prevl) {
+            len = nextl - goodlist[try][0].weight;
+            if (len > best) {
+                *t1 = try;
+                *t2 = next;
+            }
+        } else {
+            len = prevl - goodlist[try][0].weight;
+            if (len > best) {
+                *t1 = prev;
+                *t2 = try;
+            }
+        }
+    }
+}
+#endif  /* LONG_KICKER */
+
+#if defined(CLOSE_FOUR_SWAPS) || defined(GEOM_FOUR_SWAPS)
+#ifdef BIG_PROBLEM
+#define HUNT_PORTION 0.001
+#define HUNT_PORTION_LONG 0.001
+#else
+#define HUNT_PORTION 0.03
+#define HUNT_PORTION_LONG 0.001
+#endif
+#endif
+
+#if defined(CLOSE_FOUR_SWAPS) || defined(GEOM_FOUR_SWAPS)
+#define RAND_TRYS 6    /* To find the 3 other edges */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void find_close_four (int ncount,
+                             int *t1, int *t2, int *t3, int *t4,
+                            int *t5, int *t6, int *t7, int *t8)
+#else
+static void find_close_four (ncount, t1, t2, t3, t4, t5, t6, t7, t8)
+int ncount;
+int *t1, *t2, *t3, *t4, *t5, *t6, *t7, *t8;
+#endif
+{
+    int s1, s2, s3, s4, s5, s6, s7, s8;
+    int i, try;
+    int count = (int) ((double) ncount * HUNT_PORTION) + 1 + RAND_TRYS;
+
+    /* Not set up for fixed edges */
+
+#ifdef LONG_KICKER
+    first_long_kicker (ncount, &s1, &s2);
+#else
+    s1 = CCutil_lprand () % ncount;
+    s2 = CClinkern_flipper_next (s1);
+#endif
+
+    {
+        int trials[RAND_TRYS + 1];
+        int tdist[RAND_TRYS + 1];
+        int trydist;
+        int k;
+
+        tdist[RAND_TRYS] = -BIGINT;
+
+TRY_AGAIN:
+
+        for (k = 0; k < RAND_TRYS; k++)
+            tdist[k] = BIGINT;
+        for (i = 0; i < count; i++) {
+            try = CCutil_lprand () % ncount;
+            trydist = Edgelen (try, s1);
+            if (trydist < tdist[0]) {
+                for (k = 0; tdist[k + 1] > trydist; k++) {
+                    tdist[k] = tdist[k + 1];
+                    trials[k] = trials[k + 1];
+                }
+                tdist[k] = trydist;
+                trials[k] = try;
+            }
+        }
+
+        k = 0;
+        do {
+            if (k == RAND_TRYS)
+                goto TRY_AGAIN;
+            s3 = trials[k++];
+            s4 = CClinkern_flipper_next (s3);
+        } while (s3 == s1 || s3 == s2 || s4 == s1);
+
+        do {
+            if (k == RAND_TRYS)
+                goto TRY_AGAIN;
+            s5 = trials[k++];
+            s6 = CClinkern_flipper_next (s5);
+        } while (s5 == s1 || s5 == s2 || s5 == s3 ||
+                 s5 == s4 || s6 == s1 || s6 == s3);
+
+        do {
+            if (k == RAND_TRYS)
+                goto TRY_AGAIN;
+            s7 = trials[k++];
+            s8 = CClinkern_flipper_next (s7);
+        } while (s7 == s1 || s7 == s2 || s7 == s3 || s7 == s4 ||
+                 s7 == s5 || s7 == s6 || s8 == s1 || s8 == s3 ||
+                 s8 == s5);
+    }
+
+    *t1 = s1; *t2 = s2; *t3 = s3; *t4 = s4;
+    *t5 = s5; *t6 = s6; *t7 = s7; *t8 = s8;
+}
+#endif /* CLOSE_FOUR_SWAPS */
+
+
+#ifdef GEOM_FOUR_SWAPS
+#define GEO_FACTOR 50
+#define GEO_MAX    250
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_geometric_four (int ncount, CCkdtree *kdt,
+                                int *t1, int *t2, int *t3, int *t4,
+                                int *t5, int *t6, int *t7, int *t8)
+#else
+static int find_geometric_four (ncount, kdt, t1, t2, t3, t4, t5, t6, t7, t8)
+int ncount;
+CCkdtree *kdt;
+int *t1, *t2, *t3, *t4, *t5, *t6, *t7, *t8;
+#endif
+{
+    int neigh[GEO_MAX];
+    int temp, i, k, s1, s2, s3, s4, s5, s6, s7, s8;
+    int trys;
+
+#ifdef LONG_KICKER
+    first_long_kicker (ncount, &s1, &s2);
+#else
+    s1 = CCutil_lprand () % ncount;
+    s2 = CClinkern_flipper_next (s1);
+#endif
+
+    trys = ((ncount / 50) + 25 > GEO_MAX ? GEO_MAX : (ncount / 50) + 25);
+    if (trys > ncount-1) trys = ncount-1;
+    if (CCkdtree_node_k_nearest (kdt, ncount, s1, trys, gdat, (double *) NULL,
+                               neigh)) {
+        fprintf (stderr, "CCkdtree_node_k_nearest failed\n");
+        return 1;
+    }
+
+    for (i = trys; i > trys - 9; i--) {
+        k = CCutil_lprand () % i;
+        SWAP (neigh[i - 1], neigh[k], temp);
+    }
+
+    k = trys - 1;
+    do {
+        s3 = neigh[k--];
+        s4 = CClinkern_flipper_next (s3);
+    } while (s3 == s2 || s4 == s1);
+
+    do {
+        s5 = neigh[k--];
+        s6 = CClinkern_flipper_next (s5);
+    } while (s5 == s2 || s5 == s4 || s6 == s1 || s6 == s3);
+
+    do {
+        s7 = neigh[k--];
+        s8 = CClinkern_flipper_next (s7);
+    } while (s7 == s2 || s7 == s4 || s7 == s6 || s8 == s1 || s8 == s3 ||
+             s8 == s5);
+
+
+    *t1 = s1; *t2 = s2; *t3 = s3; *t4 = s4;
+    *t5 = s5; *t6 = s6; *t7 = s7; *t8 = s8;
+
+    return 0;
+}
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static void turn (int n)
+#else
+static void turn (n)
+int n;
+#endif
+{
+    intptr *ip;
+
+    /* intptralloc will not fail - the initial supply is large enough */
+
+    ADD_TO_ACTIVE_QUEUE (n, ip);
+
+#ifdef MARK_NEIGHBORS
+    {
+       int i = 0;
+       for (i = 0; i < degree[n]; i++) {
+           if (lprand () % 2) {
+               ADD_TO_ACTIVE_QUEUE (goodlist[n][i].other, ip);
+           }
+       }
+    }
+#else
+#ifndef USE_LESS_MARKING
+    {
+        int k;
+        k = CClinkern_flipper_next (n);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+        k = CClinkern_flipper_next (k);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+        k = CClinkern_flipper_prev (n);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+        k = CClinkern_flipper_prev (k);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+    }
+#endif
+#endif
+}
+
+#ifdef IMPROVE_FOUR_SWAPS
+#ifdef CC_PROTOTYPE_ANSI
+static void kickturn (int n)
+#else
+static void kickturn (n)
+int n;
+#endif
+{
+    intptr *ip;
+
+    ADD_TO_ACTIVE_QUEUE (n, ip);
+    {
+        int k;
+        k = CClinkern_flipper_next (n);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+        k = CClinkern_flipper_next (k);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+        k = CClinkern_flipper_prev (n);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+        k = CClinkern_flipper_prev (k);
+        ADD_TO_ACTIVE_QUEUE (k, ip);
+    }
+}
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static void bigturn (int n, int tonext)
+#else
+static void bigturn (n, tonext)
+int n, tonext;
+#endif
+{
+    intptr *ip;
+    int i, k;
+
+    /* intptralloc will not fail - the initial supply is large enough */
+
+    ADD_TO_ACTIVE_QUEUE (n, ip);
+
+    if (tonext) {
+        for (i = 0, k = n; i < MARK_LEVEL; i++) {
+            k = CClinkern_flipper_next (k);
+            ADD_TO_ACTIVE_QUEUE (k, ip);
+        }
+    } else {
+        for (i = 0, k = n; i < MARK_LEVEL; i++) {
+            k = CClinkern_flipper_prev (k);
+            ADD_TO_ACTIVE_QUEUE (k, ip);
+        }
+    }
+
+    for (i = 0; i < degree[n]; i++) {
+        ADD_TO_ACTIVE_QUEUE (goodlist[n][i].other, ip);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void randcycle (int ncount, int *cyc)
+#else
+static void randcycle (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, k, temp;
+
+    for (i = 0; i < ncount; i++)
+        cyc[i] = i;
+
+    for (i = ncount; i > 1; i--) {
+        k = CCutil_lprand () % i;
+        SWAP (cyc[i - 1], cyc[k], temp);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int buildgraph (int ncount, int ecount, int *elist)
+#else
+static int buildgraph (ncount, ecount, elist)
+int ncount, ecount, *elist;
+#endif
+{
+    int n1, n2, w, i;
+    edge *p;
+
+    goodlist = CC_SAFE_MALLOC (ncount, edge *);
+    if (!goodlist)
+        return 1;
+    degree = CC_SAFE_MALLOC (ncount, int);
+    if (!degree) {
+        CC_FREE (goodlist, edge *);
+        return 1;
+    }
+#if defined(HALF_LOOKS) || defined(LATE_HALF_LOOKS)
+    edgespace = CC_SAFE_MALLOC ((2 * ecount) + (2 * ncount), edge);
+#else
+    edgespace = CC_SAFE_MALLOC ((2 * ecount) + ncount, edge);
+#endif
+    if (!edgespace) {
+        CC_FREE (goodlist, edge *);
+        CC_FREE (degree, int);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+#if defined(HALF_LOOKS) || defined(LATE_HALF_LOOKS)
+        degree[i] = 2;
+#else
+        degree[i] = 1;
+#endif
+    }
+    for (i = ecount - 1; i >= 0; i--) {
+        degree[elist[2 * i]]++;
+        degree[elist[(2 * i) + 1]]++;
+    }
+
+    for (i = 0, p = edgespace; i < ncount; i++) {
+        goodlist[i] = p;
+        p += (degree[i]);
+#if defined(HALF_LOOKS) || defined(LATE_HALF_LOOKS)
+        goodlist[i][degree[i] - 2].weight = BIGINT;
+#endif
+        goodlist[i][degree[i] - 1].weight = BIGINT;
+        degree[i] = 0;
+    }
+
+
+    for (i = ecount - 1; i >= 0; i--) {
+        n1 = elist[2 * i];
+        n2 = elist[(2 * i) + 1];
+        w = Edgelen (n1, n2);
+        insertedge (n1, n2, w);
+        insertedge (n2, n1, w);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void insertedge (int n1, int n2, int w)
+#else
+static void insertedge (n1, n2, w)
+int n1;
+int n2;
+int w;
+#endif
+{
+    int i;
+    edge *e = goodlist[n1];
+
+    for (i = degree[n1] - 1; i >= 0 && e[i].weight >= w; i--) {
+        e[i + 1].weight = e[i].weight;
+        e[i + 1].other = e[i].other;
+    }
+    e[i + 1].weight = w;
+    e[i + 1].other = n2;
+    degree[n1]++;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_graph (int ncount)
+#else
+static void free_graph (ncount)
+int ncount;
+#endif
+{
+    int i;
+
+    if (goodlist)
+        CC_FREE (goodlist, edge *);
+    if (edgespace)
+        CC_FREE (edgespace, edge);
+    if (degree)
+        CC_FREE (degree, int);
+    if (fixlist) {
+        for (i = 0; i < ncount; i++) {
+            intptr_list_free (fixlist[i]);
+        }
+        CC_FREE (fixlist, intptr *);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void linkern_free_world (void)
+#else
+static void linkern_free_world ()
+#endif
+{
+    int total, onlist;
+
+    if (intptr_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding intptrs\n", total - onlist);
+    }
+    if (edgelook_check_leaks (&total, &onlist)) {
+        fprintf (stderr, "WARNING: %d outstanding edgelooks\n", total - onlist);
+    }
+    intptrfree_world ();
+    edgelookfree_world ();
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int initarrays (int ncount)
+#else
+static int initarrays (ncount)
+int ncount;
+#endif
+{
+    int i, M;
+
+    i = 0;
+    while ((1 << i) < ncount)
+        i++;
+    M = (1 << i);
+
+    add_edges = CC_SAFE_MALLOC (M, char);
+    if (!add_edges)
+        return 1;
+    del_edges = CC_SAFE_MALLOC (M, char);
+    if (!del_edges) {
+        CC_FREE (add_edges, char);
+        return 1;
+    }
+    for (i = 0; i < M; i++) {
+        add_edges[i] = 0;
+        del_edges[i] = 0;
+    }
+
+    active = CC_SAFE_MALLOC (ncount, char);
+    if (!active) {
+        CC_FREE (add_edges, char);
+        CC_FREE (del_edges, char);
+        return 1;
+    }
+    weirdmark = CC_SAFE_MALLOC (ncount, int);
+    if (!weirdmark) {
+        CC_FREE (add_edges, char);
+        CC_FREE (del_edges, char);
+        CC_FREE (active, char);
+        return 1;
+    }
+    for (i = 0; i < ncount; i++) {
+        active[i] = 0;
+        weirdmark[i] = 0;
+    }
+
+    return 0;
+}
+
+static int cacheM = 0;
+
+#ifdef CC_PROTOTYPE_ANSI
+static int initcache (int ncount)
+#else
+static int initcache (ncount)
+int ncount;
+#endif
+{
+    int i;
+
+#ifndef BENTLEY_CACHE
+    i = 0;
+    while ((1 << i) < (ncount << 2))
+        i++;
+    cacheM = (1 << i);
+#else
+    i = 0;
+    while ((1 << i) < ncount)
+        i++;
+    cacheM = (1 << i);
+#endif
+
+    cacheind = CC_SAFE_MALLOC (cacheM, int);
+    if (!cacheind) return 1;
+
+    cacheval = CC_SAFE_MALLOC (cacheM, int);
+    if (!cacheval) return 1;
+
+    for (i = 0; i < cacheM; i++) {
+        cacheind[i] = -1;
+    }
+
+#ifndef BENTLEY_CACHE
+    cacheM--;
+#endif
+
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int dist (int i, int j)   /* As in Bentley's CCkdtree paper */
+#else
+static int dist (i, j)
+int i, j;
+#endif
+{
+    int ind;
+
+    if (i > j) {
+        int temp;
+        SWAP (i, j, temp);
+    }
+
+#ifndef BENTLEY_CACHE
+    ind = (((i << 8) + i + j) & (cacheM));
+#else
+    ind = i ^ j;
+#endif
+
+    if (cacheind[ind] != i) {
+        cacheind[ind] = i;
+        cacheval[ind] = CCutil_dat_edgelen (i, j, gdat);
+    }
+
+    return cacheval[ind];
+}
diff --git a/contrib/blossom/concorde97/LINKERN/lk_main.c b/contrib/blossom/concorde97/LINKERN/lk_main.c
new file mode 100644
index 0000000000000000000000000000000000000000..63094e815a05b143ff344a27675c057e4543f5d1
--- /dev/null
+++ b/contrib/blossom/concorde97/LINKERN/lk_main.c
@@ -0,0 +1,628 @@
+/***************************************************************************/
+/*                                                                         */
+/*               CODE FOR TESTING ITERATED LIN-KERNIGHAN                   */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 17, 1995                                                   */
+/*                                                                         */
+/*  For a short describtion see usage ()                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "linkern.h"
+#include "kdtree.h"
+#include "edgegen.h"
+
+#define BIGDOUBLE 1000000000.0
+#define SWAP(x,y,temp) {(temp) = (x); (x) = (y); (y) = (temp);}
+
+static int norm = CC_EUCLIDEAN;
+static int seed = 0;
+static int binary_in = 0;
+static int tsplib_in = 0;
+static int nnodes_want = 0;
+static int usegreedy = 0;
+static int useqboruvka = 0;
+static int useboruvka = 0;
+static int userandom = 0;
+static int nearnum = 0;
+static int quadtry = 2;
+static int run_silently = 0;
+
+static int in_repeater = 0;
+static int number_runs = 0;
+static int print_final = 0;
+static double time_bound = -1.0;
+static double length_bound = -1.0;
+
+static char *nodefile = (char *) NULL;
+static char *goodfname = (char *) NULL;
+static char *cycfname = (char *) NULL;
+static char *edgegenfname = (char *) NULL;
+static char *edgecycfname = (char *) NULL;
+static char *process_name = (char *) NULL;
+static char *saveit_name = (char *) NULL;
+static char edgecyclefilename[256];
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int, char **);
+static int
+    parseargs (int, char **);
+static void
+    setupnames (char *n1, char *n2, int ncount),
+    randcycle (int ncount, int *cyc),
+    usage (char *f);
+
+#else
+
+int
+    main ();
+static int
+    parseargs ();
+static void
+    setupnames (),
+    randcycle (),
+    usage ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int k, ncount;
+    double val, best;
+    double startzeit;
+    int tempcount, *templist;
+    int *incycle = (int *) NULL, *outcycle = (int *) NULL;
+    CCdatagroup dat;
+    int rval = 0;
+
+    seed = (int) CCutil_real_zeit ();
+    if (parseargs (ac, av))
+        return 1;
+    CCutil_sprand (seed);
+
+    printf ("Chained Lin-Kernighan with seed %d\n", seed);
+    fflush (stdout);
+
+    if ((!nnodes_want && !nodefile) || (tsplib_in && !nodefile)) {
+        usage (av[0]);
+        return 1;
+    }
+
+    startzeit = CCutil_zeit ();
+    setupnames (nodefile, process_name, nnodes_want);
+
+    dat.x = (double *) NULL;
+    dat.y = (double *) NULL;
+    dat.z = (double *) NULL;
+    dat.adj = (int **) NULL;
+
+    if (tsplib_in) {
+        if (CCutil_gettsplib (nodefile, &ncount, &dat)) {
+            fprintf (stderr, "could not read the TSPLIB file\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        norm = dat.norm;
+    } else {
+        ncount = nnodes_want;
+        if (CCutil_getdata (nodefile, binary_in, norm, &ncount, &dat)) {
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (CCutil_init_dat_edgelen (&dat)) {
+        fprintf (stderr, "CCutil_init_dat_edgelen failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    incycle = CC_SAFE_MALLOC (ncount, int);
+    if (!incycle) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    if (cycfname) {
+        if (CCutil_getcycle (ncount, cycfname, incycle)) {
+            fprintf (stderr, "CCutil_getcycle failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    } else if (edgecycfname) {
+        if (CCutil_getcycle_edgelist (ncount, edgecycfname, incycle)) {
+            fprintf (stderr, "CCutil_getcycle_edgelist failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (goodfname) {
+        int *templen = (int *) NULL;
+        if (CCutil_getedgelist (ncount, goodfname, &tempcount, &templist,
+                                &templen)) {
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (templen)
+            CC_FREE (templen, int);
+        printf ("Read good-edge file: %d edges\n", tempcount);
+        fflush (stdout);
+    } else if (edgegenfname) {
+        CCedgegengroup plan;
+        if (CCedgegen_read (edgegenfname, &plan)) {
+            fprintf (stderr, "CCedgegen_read failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (CCedgegen_edges (&plan, ncount, &dat, (double *) NULL, &tempcount,
+                             &templist)) {
+            fprintf (stderr, "CCedgegen_edges failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if ((norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+        CCkdtree localkt;
+        double kzeit = CCutil_zeit ();
+
+        if ((!goodfname && !edgegenfname) || (!cycfname && !edgecycfname)) {
+            if (CCkdtree_build (&localkt, ncount, &dat, (double *) NULL)) {
+                fprintf (stderr, "CCkdtree_build failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            printf ("Time to build kdtree: %.2f\n", CCutil_zeit () - kzeit);
+            fflush (stdout);
+
+            if (!goodfname && !edgegenfname) {
+                kzeit = CCutil_zeit ();
+                if (nearnum) {
+                    if (CCkdtree_k_nearest (&localkt, ncount, nearnum, &dat,
+                               (double *) NULL, 1, &tempcount, &templist)) {
+                        fprintf (stderr, "CCkdtree_k_nearest failed\n");
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                    if (!run_silently) {
+                        printf ("Time to find %d-nearest: %.2f\n", nearnum,
+                                                     CCutil_zeit () - kzeit);
+                        fflush (stdout);
+                    }
+                } else {
+                    if (CCkdtree_quadrant_k_nearest (&localkt, ncount, quadtry,
+                           &dat, (double *) NULL, 1, &tempcount, &templist)) {
+                        fprintf (stderr, "CCkdtree-quad nearest code failed\n");
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                    if (!run_silently) {
+                        printf ("Time to find quad %d-nearest: %.2f\n", quadtry,
+                                                     CCutil_zeit () - kzeit);
+                        fflush (stdout);
+                    }
+                }
+            }
+            if (!cycfname && !edgecycfname) {
+                kzeit = CCutil_zeit ();
+                if (usegreedy) {
+                    if (CCkdtree_greedy_tour (&localkt, ncount,
+                              &dat, incycle, &val)) {
+                        fprintf (stderr, "CCkdtree greedy-tour failed\n");
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                } else if (useqboruvka) {
+                    if (CCkdtree_qboruvka_tour (&localkt, ncount,
+                              &dat, incycle, &val)) {
+                        fprintf (stderr, "CCkdtree qboruvak-tour failed\n");
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                } else if (useboruvka) {
+                    if (CCkdtree_boruvka_tour (&localkt, ncount,
+                              &dat, incycle, &val)) {
+                        fprintf (stderr, "CCkdtree boruvka-tour failed\n");
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                } else if (userandom) {
+                    randcycle (ncount, incycle);
+                } else {
+                    if (CCkdtree_nearest_neighbor_tour (&localkt, ncount,
+                           CCutil_lprand () % ncount, &dat, incycle, &val)) {
+                        fprintf (stderr, "CCkdtree NN-tour failed\n");
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                }
+                if (!run_silently) {
+                    printf ("Time to grow tour: %.2f\n", CCutil_zeit() - kzeit);
+                    fflush (stdout);
+                }
+            }
+            CCkdtree_free (&localkt);
+        }
+    } else if ((norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+        double xzeit = CCutil_zeit ();
+        if (!goodfname && !edgegenfname) {
+            if (nearnum) {
+                if (CCedgegen_x_k_nearest (ncount, nearnum, &dat,
+                            (double *) NULL, 1, &tempcount, &templist)) {
+                    fprintf (stderr, "CCedgegen_x_k_nearest failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                if (!run_silently) {
+                    printf ("Time to find %d-nearest: %.2f\n", nearnum,
+                                                 CCutil_zeit () - xzeit);
+                    fflush (stdout);
+                }
+            } else {
+                if (CCedgegen_x_quadrant_k_nearest (ncount, quadtry, &dat,
+                                 (double *) NULL, 1, &tempcount, &templist)) {
+                    fprintf (stderr, "x-quad nearest code failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+                if (!run_silently) {
+                    printf ("Time to find quad %d-nearest: %.2f\n", quadtry,
+                                                 CCutil_zeit () - xzeit);
+                    fflush (stdout);
+                }
+            }
+        }
+        if (!cycfname && !edgecycfname) {
+            xzeit = CCutil_zeit ();
+            if (userandom) {
+                randcycle (ncount, incycle);
+            } else {
+                if (CCedgegen_x_nearest_neighbor_tour (ncount,
+                         CCutil_lprand () % ncount, &dat, incycle, &val)) {
+                    fprintf (stderr, "x_nearest_neighbor_tour failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+            }
+            if (!run_silently) {
+                printf ("Time to grow tour: %.2f\n", CCutil_zeit () - xzeit);
+                fflush (stdout);
+            }
+        }
+    } else {
+        double jzeit = CCutil_zeit ();
+        if (!goodfname && !edgegenfname) {
+            if (!nearnum)
+                nearnum = 4 * quadtry;
+            if (CCedgegen_junk_k_nearest (ncount, nearnum, &dat,
+                      (double *) NULL, 1, &tempcount, &templist)) {
+                fprintf (stderr, "CCedgegen_junk_k_nearest failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            if (!run_silently) {
+                printf ("Time to find %d nearest: %.2f\n",
+                         nearnum, CCutil_zeit () - jzeit);
+                fflush (stdout);
+            }
+        }
+        if (!cycfname && !edgecycfname) {
+            if (userandom) {
+                randcycle (ncount, incycle);
+            } else {
+                if (CCedgegen_junk_nearest_neighbor_tour (ncount,
+                         CCutil_lprand () % ncount, &dat, incycle, &val)) {
+                    fprintf (stderr, "junk_nearest_neighbor_tour failed\n");
+                    rval = 1;
+                    goto CLEANUP;
+                }
+            }
+            if (!run_silently) {
+                printf ("Time to grow tour: %.2f\n", CCutil_zeit () - jzeit);
+                fflush (stdout);
+            }
+        }
+    }
+
+    outcycle = CC_SAFE_MALLOC (ncount, int);
+    if (!outcycle) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (number_runs) {
+        k = 0;
+        best = BIGDOUBLE;
+        do {
+            printf ("\nStarting Run %d\n", k);
+            if (CClinkern_tour (ncount, &dat, tempcount, templist, 100000000,
+                   in_repeater, incycle, outcycle, &val, run_silently,
+                   time_bound, length_bound, (char *) NULL)) {
+                fprintf (stderr, "CClinkern_tour failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            if (val < best) {
+                best = val;
+                if (print_final) {
+                    if (CCutil_writecycle_edgelist (ncount, edgecyclefilename,
+                            outcycle, &dat)) {
+                        fprintf (stderr, "could not write the cycle\n");
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                }
+            }
+        } while (++k < number_runs);
+        printf ("Overall Best Cycle: %.0f\n", val);
+        fflush (stdout);
+    } else {
+        double lkzeit = CCutil_zeit ();
+        int attempt = 1;
+        do {
+            if (CClinkern_tour (ncount, &dat, tempcount, templist, 10000000,
+               in_repeater, incycle, outcycle, &val,
+               run_silently, time_bound, length_bound, saveit_name)) {
+                fprintf (stderr, "CClinkern_tour failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            if (length_bound != -1 && val > length_bound) {
+                printf ("Cycle of value %.0f  -  did not reach %.0f\n",
+                    val, length_bound);
+                printf ("Try again. Number of attempts: %d\n", ++attempt);
+            }
+        } while (length_bound != -1 && val > length_bound);
+        if (print_final) {
+            if (CCutil_writecycle_edgelist (ncount, edgecyclefilename,
+                        outcycle, &dat)) {
+                fprintf (stderr, "could not write the cycle\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+        }
+        if (run_silently)
+            printf ("Lin-Kernighan Running Time: %.2f\n", CCutil_zeit()-lkzeit);
+        printf ("Final Cycle: %.0f\n", val);
+        fflush (stdout);
+    }
+    printf ("Total Running Time: %.2f\n", CCutil_zeit () - startzeit);
+    fflush (stdout);
+
+CLEANUP:
+
+#ifndef BIG_PROBLEM
+    if (templist)
+        CC_FREE (templist, int);
+#endif
+    if (incycle)
+        CC_FREE (incycle, int);
+    if (outcycle)
+        CC_FREE (outcycle, int);
+    CCutil_freedatagroup (ncount, &dat);
+
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: CCuitl_bigcunk free world failed\n");
+        return 1;
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void setupnames (char *n1, char *n2, int ncount)
+#else
+static void setupnames (n1, n2, ncount)
+char *n1;
+char *n2;
+int ncount;
+#endif
+{
+    if (n2) {
+        sprintf (edgecyclefilename, "ecycle.out.%s", n2);
+    } else if (n1) {
+        char *p = CCutil_strrchr (n1, '/');
+        if (!p)
+            p = n1;
+        else
+            p++;
+        sprintf (edgecyclefilename, "ecycle.out.%s", p);
+    } else {
+        sprintf (edgecyclefilename, "ecycle.out.%d", ncount);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void randcycle (int ncount, int *cyc)
+#else
+static void randcycle (ncount, cyc)
+int ncount;
+int *cyc;
+#endif
+{
+    int i, k, temp;
+
+    for (i = 0; i < ncount; i++)
+        cyc[i] = i;
+
+    for (i = ncount; i > 1; i--) {
+        k = CCutil_lprand () % i;
+        SWAP (cyc[i - 1], cyc[k], temp);
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "a:bD:g:h:jk:ln:pq:Qr:R:s:S:t:Tuvy:Y:0123456789")) != EOF)
+        switch (c) {
+        case 'a':
+            nearnum = atoi (CCutil_bix_optarg);
+            break;
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'D':
+            edgegenfname = CCutil_bix_optarg;
+            break;
+        case 'g':
+            goodfname = CCutil_bix_optarg;
+            break;
+        case 'h':
+            length_bound = atof (CCutil_bix_optarg);
+            break;
+        case 'j':
+            useqboruvka++;
+            break;
+        case 'k':
+            nnodes_want = atoi (CCutil_bix_optarg);
+            break;
+        case 'l':
+            userandom++;
+            break;
+        case 'n':
+            process_name = CCutil_bix_optarg;
+            break;
+        case 'p':
+            print_final++;
+            break;
+        case 'q':
+            quadtry = atoi (CCutil_bix_optarg);
+            break;
+        case 'Q':
+            run_silently++;
+            break;
+        case 'r':
+            number_runs = atoi (CCutil_bix_optarg);
+            break;
+        case 'R':
+            in_repeater = atoi (CCutil_bix_optarg);
+            break;
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 'S':
+            saveit_name = CCutil_bix_optarg;
+            break;
+        case 't':
+            time_bound = atof (CCutil_bix_optarg);
+            break;
+        case 'T':
+            tsplib_in = 1;
+            break;
+        case 'u':
+            usegreedy++;
+            break;
+        case 'v':
+            useboruvka++;
+            break;
+        case 'y':
+            cycfname = CCutil_bix_optarg;
+            break;
+        case 'Y':
+            edgecycfname = CCutil_bix_optarg;
+            break;
+        case '0':
+            norm = CC_MAXNORM;
+            break;
+        case '1':
+            norm = CC_EUCLIDEAN_CEIL;
+            break;
+        case '2':
+            norm = CC_EUCLIDEAN;
+            break;
+        case '3':
+            norm = CC_EUCLIDEAN_3D;
+            break;
+        case '4':
+            norm = CC_IBM;
+            break;
+        case '5':
+            norm = CC_ATT;
+            break;
+        case '6':
+            norm = CC_GEOGRAPHIC;
+            break;
+        case '7':
+            norm = CC_MATRIXNORM;
+            break;
+        case '8':
+            norm = CC_DSJRANDNORM;
+            break;
+        case '9':
+            norm = CC_CRYSTAL;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+        default:
+            usage (av[0]);
+            break;
+        }
+    if (CCutil_bix_optind < ac)
+        nodefile = av[CCutil_bix_optind++];
+
+    if (CCutil_bix_optind > ac) {
+        usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "usage: %s [- see below -] [dat_file]\n", f);
+    fprintf (stderr, "   -b    dat file in binary ints\n");
+    fprintf (stderr, "   -k #  number of nodes for random problem\n");
+    fprintf (stderr, "   -s #  random number seed\n");
+    fprintf (stderr, "   -n s  process name (used for naming output file)\n");
+    fprintf (stderr, "   -p    dump final cycle\n");
+    fprintf (stderr, "   -S s  save tour in S after every 10000 kicks\n");
+    fprintf (stderr, "   -a #  use #-nearest as good edge set\n");
+    fprintf (stderr, "   -D f  edgegen description file\n");
+    fprintf (stderr, "   -g f  good edge file\n");
+    fprintf (stderr, "   -q #  use quad #-nearest as edge set (default 3)\n");
+    fprintf (stderr, "   -r #  number of runs\n");
+    fprintf (stderr, "   -R #  number of kicks in iterated Lin-Kernighan\n");
+    fprintf (stderr, "   -y f  starting cycle\n");
+    fprintf (stderr, "   -Y f  starting cycle (as an edgelist)\n");
+    fprintf (stderr, "   -u    greedy starting cycle (for kd-norms)\n");
+    fprintf (stderr, "   -j    quick-boruvka starting cycle (for kd-norms)\n");
+    fprintf (stderr, "   -v    boruvka starting cycle (for kd-norms)\n");
+    fprintf (stderr, "   -l    random starting cycle\n");
+    fprintf (stderr, "   -T    the dat file is a TSPLIB file\n");
+    fprintf (stderr, "   -t d  running time bound in seconds\n");
+    fprintf (stderr, "   -h d  tour length bound (stop when we hit d)\n");
+    fprintf (stderr, "   -Q    run silently\n");
+    fprintf (stderr, "   -0    Max norm for edge lengths\n");
+    fprintf (stderr, "   -1    Ceiling Euclidean norm - from DSJ\n");
+    fprintf (stderr, "   -2    Rounded Euclidean norm (default)\n");
+    fprintf (stderr, "   -3    Rounded Euclidean 3D norm\n");
+    fprintf (stderr, "   -(4 5 6 7 8 9) IBM ATT GEO MATRIX DSJRAND CRYSTAL norm\n");
+}
diff --git a/contrib/blossom/concorde97/LP/Makefile b/contrib/blossom/concorde97/LP/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b3d32923c04f3b46ebba59a816ed9735df359722
--- /dev/null
+++ b/contrib/blossom/concorde97/LP/Makefile
@@ -0,0 +1,33 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=lp.a
+
+ifneq ($(CPLEX_LIB),)
+LIBSRCS=lpcplex.c
+else
+LIBSRCS=lpsolve.c
+endif
+ALLSRCS=lpsolve.c lpcplex.c
+
+all: $(LIB)
+
+clean:
+	-rm -f *.$o $(LIB)
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+lpcplex.$o:  lpcplex.c  $(I)/machdefs.h $(I)/util.h     $(I)/macrorus.h \
+        $(I)/lp.h       
+lpsolve.$o:  lpsolve.c  $(I)/machdefs.h $(I)/util.h     $(I)/macrorus.h \
+        $(I)/lp.h       
diff --git a/contrib/blossom/concorde97/LP/lpcplex.c b/contrib/blossom/concorde97/LP/lpcplex.c
new file mode 100644
index 0000000000000000000000000000000000000000..e2affa81108533b293116d2ebb5607891afcfb84
--- /dev/null
+++ b/contrib/blossom/concorde97/LP/lpcplex.c
@@ -0,0 +1,1408 @@
+/***************************************************************************/
+/*                                                                         */
+/*              Interface Routines to The CPLEX LP Solver                  */
+/*                                                                         */
+/*  NOTE: Use this code in place of lpsolve.c to access the Cplex 4.1      */
+/*   library. You will also need to link the cplex library via the         */
+/*   makefile.                                                             */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: April 17, 1997                                                   */
+/*        June 19, 1997 (bico, REB)                                        */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*                                                                         */
+/*    void CClp_init_struct (CClp *lp)                                     */
+/*      INITIALIZES the fields of the LP structure to NULL.                */
+/*                                                                         */
+/*    int CClp_init (CClp *lp)                                             */
+/*      INITIALIZES the LP.                                                */
+/*                                                                         */
+/*   void CClp_free (CClp *lp)                                             */
+/*      FREES the LP (but not pointer to the LP).                          */
+/*                                                                         */
+/*   int CClp_loadlp (CClp *lp, char *name, int ncols, int nrows,          */
+/*            int objsense, double *obj, double *rhs, char *sense,         */
+/*            int *matbeg, int *matcnt,                                    */
+/*            int *matind, double *matval,                                 */
+/*            double *lb, double *ub)                                      */
+/*      LOADS the data into the LP. The memory is used by the LP solver,   */
+/*       and thus should not be freed until after a call to CClp_free.     */
+/*        -name attaches a name to the LP (it can be used by the LP solver */
+/*         in io routines)                                                 */
+/*        -ncols and nrows give the number of columns and rows in the LP   */
+/*        -objsense should be -1 for minimize and 1 for maximize           */
+/*        -obj and rhs are arrays giving the objective function and rhs    */
+/*        -sense is an array specifying 'L', 'E', or 'G' for each of the   */
+/*         rows                                                            */
+/*        -matbeg, matcnt, matind, and matval give the coefficients of     */
+/*         the contraint matrix in column by column order. matbeg gives    */
+/*         gives the index of the start of each column; matcnt gives the   */
+/*         number of coefficients in each column; matind gives the indices */
+/*         of the rows where the coefficients are located in the contraint */
+/*         matrix (so for column j, the indices are given in matcnt[j]     */
+/*         locations starting at matind[matbeg[j]]; and matval gives the   */
+/*         actual coefficients (organized like matind).                    */
+/*        -lb and ub are arrays giving the upper and lower bounds of       */
+/*         the variables.                                                  */
+/*                                                                         */
+/*   int CClp_opt (CClp *lp, int method)                                   */
+/*      CALLS designated LP solution method.                               */
+/*                                                                         */
+/*   int CClp_dualopt (CClp *lp)                                           */
+/*      CALLS the dual simplex method.                                     */
+/*                                                                         */
+/*   int CClp_limited_dualopt (CClp *lp, int lim, double *upperbound,      */
+/*           int *status)                                                  */
+/*      CALLS the dual simplex method with a limit on the number of pivots.*/
+/*        -upperbound it is used to cutoff the dual simplex method (when   */
+/*         the objective value reaches upperbound); it can be NULL         */
+/*        -status returns the status of the optimization (it can be NULL)  */
+/*                                                                         */
+/*   void CClp_pivotin (CClp *lp, int i)                                   */
+/*      Puts slack/artificial on row i into the resident basis             */
+/*      If there is no resident basis, the call fails                      */
+/*                                                                         */
+/*   int CClp_primalopt (CClp *lp)                                         */
+/*      CALLS the primal simplex method.                                   */
+/*                                                                         */
+/*   int CClp_addrows (CClp *lp, int newrows, int newnz, double *rhs,      */
+/*            char *sense, int *rmatbeg, int *rmatind, double *rmatval)    */
+/*      ADDS the rows to the LP.                                           */
+/*        -newrows is the number of rows to be added                       */
+/*        -newnz is the number of nonzero coefficients in the new rows     */
+/*        -rhs is an array of the rhs values for the new rows              */
+/*        -sense is 'L', 'E', or 'G' for each of the new rows              */
+/*        -rmatbeg, rmatind, and rmatval give the coefficients of the      */
+/*         new rows in sparse format. The arrays can be freed after the    */
+/*         call.                                                           */
+/*                                                                         */
+/*   int CClp_addcols (CClp *lp, int newcols, int newnz, double *obj,      */
+/*            int *cmatbeg, int *cmatind, double *cmatval,                 */
+/*            double *lb, double *ub)                                      */
+/*      ADDS the columns to the LP.                                        */
+/*                                                                         */
+/*   int CClp_delete_row (CClp *lp, int i)                                 */
+/*      DELETES row i of the LP.                                           */
+/*                                                                         */
+/*   int CClp_delete_set_of_rows (CClp *lp, int *delstat)                  */
+/*      DELETES the rows corresponding to 1 entries in delstat.            */
+/*        -delstat is a 0/1 array having an entry for each row             */
+/*                                                                         */
+/*   int CClp_delete_column (CClp *lp, int i)                              */
+/*      DELETES column i from the LP.                                      */
+/*                                                                         */
+/*   int CClp_delete_set_of_columns (CClp *lp, int *delstat)               */
+/*      DELETES the columns corresponding to the 1 entries in delstat.     */
+/*        -delstat is a 0/1 array having an entry for each column          */
+/*                                                                         */
+/*   int CClp_setbnd (CClp *lp, int col, char lower_or_upper, double bnd)  */
+/*      SETS the bound on the variable index by col.                       */
+/*        -lower_or_upper should be either 'L' or 'U'                      */
+/*                                                                         */
+/*   void CClp_init_basis (CClpbasis *b)                                   */
+/*      INITIALIZES the fields of the basis structure.                     */
+/*                                                                         */
+/*   void CClp_free_basis (CClpbasis *b)                                   */
+/*      FREEs the basis structure.                                         */
+/*                                                                         */
+/*   int CClp_get_basis_and_norms (CClp *lp, CClpbasis *b)                 */
+/*      RETURNS the current basis and dual norms.                          */
+/*      Note: The arrays are allocated by this function are should be      */
+/*       freed by a call to CC_lp_free_basis ().                           */
+/*                                                                         */
+/*   int CClp_load_basis_and_norms (CClp *lp, CClpbasis *b)                */
+/*      LOADS the basis and norm int the LP.                               */
+/*      Note: If the norms field is not set, then just the basis is loaded.*/
+/*                                                                         */
+/*   int CClp_basis (CClp *lp, int *cstat, int *rstat)                     */
+/*      RETURNS the current basis. cstat or rstat can by NULL.             */
+/*        -cstat should be an array of length at least ncols               */
+/*        -rstat should be an array of length at least nrows               */
+/*                                                                         */
+/*   int CClp_loadbasis (CClp *lp, int *cstat, int *rstat)                 */
+/*      LOADS the basis into the LP.                                       */
+/*                                                                         */
+/*   int CClp_getbasis_and_norms (CClp *lp, int *cstat, int *rstat,        */
+/*          double *dnorm)                                                 */
+/*      RETURNS the current basis and dual norms - these items should be   */
+/*       used as a pair, in calls to CClp_loadbasis_and_norms.             */
+/*        -dnorms should be an array of length at least nrows              */
+/*                                                                         */
+/*   int CClp_loadbasis_and_norms (CClp *lp,int *cstat, int *rstat,        */
+/*          double *dnorm)                                                 */
+/*      LOADS the basis and dual norms into the LP. (This pair should      */
+/*       have been obtained by a call to CClp_getbasis_and_norms.          */
+/*                                                                         */
+/*   int CClp_x (CClp *lp, double *x)                                      */
+/*      RETURNS the current LP solution.                                   */
+/*        -x should be an array of length at least ncols                   */
+/*                                                                         */
+/*   int CClp_rc (CClp *lp, double *rc)                                    */
+/*      RETURNS the current reduced costs.                                 */
+/*        -rc should be an array of length at least ncols                  */
+/*                                                                         */
+/*   int CClp_pi_range (CClp *lp, double *pi, int from, int to)            */
+/*      RETURNS the dual values on the constraints indexed [from, to].     */
+/*        -pi should be an array of length at least (to-from+1)            */
+/*                                                                         */
+/*   int CClp_objval (CClp *lp, double *obj)                               */
+/*      RETURNS the objective value of the lp.                             */
+/*                                                                         */
+/*   int CClp_nonzeros (CClp *lp)                                          */
+/*      RETURNS the number of nonzeros in the LP.                          */
+/*                                                                         */
+/*   int CClp_status (CClp *lp, int *status)                               */
+/*      CHECKS whether the current lp is infeasible or whether an optimal  */
+/*       solution has been found. It returns an error if the LP has not    */
+/*       not been optimized.                                               */
+/*        -lp is the lp                                                    */
+/*        -status returns 0 if the lp has an optimal solution and 1 if it  */
+/*         is infeasible.                                                  */
+/*                                                                         */
+/*   int CClp_getweight (CClp *lp, int nrows, int *rmatbeg, int *rmatind,  */
+/*          double *rmatval, double *weight)                               */
+/*      COMPUTES the duals of the steepest edge norms for the n rows       */
+/*       specified in rmatbeg, rmatind, and rmatval.                       */
+/*        -weight returns the array of weights; the array should be at     */
+/*         least nrows long                                                */
+/*                                                                         */
+/*   int CClp_dump_lp (CClp *lp, char *fname)                              */
+/*      WRITES the LP to file fname.                                       */
+/*                                                                         */
+/*   int CClp_getgoodlist (CClp *lp, int *goodlist, int *ngood,            */
+/*          double *downpen, double *uppen)                                */
+/*      RETURNS an array of the column indices corresponding to variables  */
+/*       that move in both the up and down directions. This is a useful    */
+/*       list of candidates for strong branching.                          */
+/*        -goodlist, downpen and uppen should be arrays of length at       */
+/*         least ncols.                                                    */
+/*                                                                         */
+/*   int CClp_strongbranch (CClp *lp, int *candidatelist, int ncand,       */
+/*          double *downpen, double *uppen, int iterations,                */
+/*          double *upperbound)                                            */
+/*      RETURNS estimates of the lp values obtained by setting each of the */
+/*        ncand variables listed in candidatelist to 0 and 1. The estimates*/
+/*        are obtained by performing iterations pivots of dual simplex     */
+/*        method. If upperbound is not NULL, then it is used to cutoff the */
+/*        dual simplex method.                                             */
+/*         -downpen and uppen should be arrays of length at least ncand    */
+/*                                                                         */
+/*    int CClp_getfarkasmultipliers (CClp *lp, double *y)                  */
+/*      RETURNS the multipliers for a Farkas' proof after dualopt returns  */
+/*       with an unbound lp.                                               */
+/*        -y should point to an array at least as long as the number of    */
+/*         rows                                                            */
+/*      The y[] computed will satisfy the following:                       */
+/*                                                                         */
+/*         y_i <= 0  for <= constraints                                    */
+/*         y_i >= 0  for >= constraints                                    */
+/*                                                                         */
+/*         y'b - sum (y'A_j * u_j: y'A_j > 0)                              */
+/*             - sum (y'A_j * l_j: y'A_j < 0) > 0                          */
+/*                                                                         */
+/*      where b is the rhs vector, u_j is the upper bound on variable x_j, */
+/*      l_j the lower bound, and A_j the constraint matrix column for x_j. */
+/*                                                                         */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "machdefs.h"
+#include "util.h"
+#include "macrorus.h"
+#include "lp.h"
+#include <cplex.h>
+
+#undef CC_CPLEX_DISPLAY
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_init_struct (CClp *lp)
+#else
+void CClp_init_struct (lp)
+CClp *lp;
+#endif
+{
+    lp->cplex_env    = (CPXENVptr) NULL;
+    lp->cplex_lp     =  (CPXLPptr) NULL;
+    lp->lp_allocated = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_init (CClp *lp)
+#else
+int CClp_init (lp)
+CClp *lp;
+#endif
+{
+    int rval = 0;
+
+    CClp_init_struct (lp);
+
+    lp->cplex_env = CPXopenCPLEXdevelop (&rval);
+    if (rval) {
+        fprintf (stderr, "cplex open failed\n"); goto CLEANUP;
+    }
+
+#ifdef CC_CPLEX_DISPLAY
+    /* the documentation doesn't say what the return value means */
+    rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_SCRIND, 1);
+    if (rval) {
+        fprintf (stderr, "cplex set SCR_IND failed\n"); goto CLEANUP;
+    }
+
+    rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_SIMDISPLAY, 1);
+    if (rval) {
+        fprintf (stderr, "cplex setitfoind failed\n"); goto CLEANUP;
+    }
+#endif
+
+    rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_ADVIND, 1);
+    if (rval) {
+        fprintf (stderr, "cplex setadvind failed\n"); goto CLEANUP;
+    }
+    rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_DPRIIND,
+                           CPX_DPRIIND_STEEP);
+    if (rval) {
+        fprintf (stderr, "cplex setdpriind failed\n"); goto CLEANUP;
+    }
+    rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PPRIIND,
+                           CPX_PPRIIND_STEEP);
+    if (rval) {
+        fprintf (stderr, "cplex setppriind failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    if (rval) {
+        CClp_free (lp);
+    } else {
+        lp->lp_allocated = 1;
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_free (CClp *lp)
+#else
+void CClp_free (lp)
+CClp *lp;
+#endif
+{
+    if (lp->cplex_env) {
+        if (lp->cplex_lp) {
+            CPXfreeprob (lp->cplex_env, &lp->cplex_lp);
+        }
+        CPXcloseCPLEX (&lp->cplex_env);
+    }
+    lp->lp_allocated = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_loadlp (CClp *lp, char *name, int ncols, int nrows,
+                 int objsense, double *obj, double *rhs, char *sense,
+                 int *matbeg, int *matcnt,
+                 int *matind, double *matval,
+                 double *lb, double *ub)
+
+#else
+int CClp_loadlp (lp, name, ncols, nrows, objsense, obj, rhs, sense, matbeg,
+                 matcnt, matind, matval, lb, ub)
+CClp *lp;
+char *name;
+int ncols, nrows;
+int objsense;
+double *obj, *rhs;
+char *sense;
+int *matbeg, *matcnt, *matind;
+double *matval, *lb, *ub;
+#endif
+{
+    int  rval = 0;
+
+    lp->cplex_lp = CPXcreateprob (lp->cplex_env, &rval, name);
+    if (!lp->cplex_lp || rval) {
+       fprintf (stderr, "CPXcreateprob failed\n"); return 1;
+    }
+
+    rval = CPXcopylp (lp->cplex_env, lp->cplex_lp, ncols, nrows,
+                      objsense, obj, rhs, sense, matbeg, matcnt,
+                      matind, matval, lb, ub, (double *) NULL);
+    if (rval) {
+       fprintf (stderr, "CPXcopylp failed\n");  return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_opt (CClp *lp, int method)
+#else
+int CClp_opt (lp, method)
+CClp *lp;
+int method;
+#endif
+{
+    int  rval = 0;
+
+    switch (method) {
+        case CClp_METHOD_DUAL:
+            rval = CClp_dualopt (lp);
+            break;
+            /* The purpose of this function is to support calls to other
+               LP algorithms, such CPXbaropt.  However, the current
+               version of concorde (14 August 1997) does not use this
+               feature */
+        default: 
+            rval = 1;
+            fprintf (stderr, "Nonexistent method in CClp_opt\n");
+            break;
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_dualopt (CClp *lp)
+#else
+int CClp_dualopt (lp)
+CClp *lp;
+#endif
+{
+    int rval;
+    int solstat;
+#ifdef  CC_CPLEX_WRITE_DUAL
+    static int  probcnt = 0;
+    char probname[100];
+
+    sprintf (probname, "%s.dual%d.sav", lp->lpspace.probname, probcnt);
+    probcnt++;
+    printf ("Writing %s\n", probname);
+    CPXsavwrite (lp->cplex_env, lp->cplex_lp, probname);
+#endif
+
+    rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
+    if (rval) {
+        if (rval == CPXERR_PRESLV_INForUNBD) {
+            int old;
+            printf ("Cplex presolved failed, switch to simplex\n");
+            fflush (stdout);
+            if (CPXgetintparam (lp->cplex_env, CPX_PARAM_PREIND, &old)) {
+                fprintf (stderr, "CPXsetintparam failed\n");
+                return 1;
+            }
+            if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, CPX_OFF)) {
+                fprintf (stderr, "CPXsetintparam failed\n");
+                return 1;
+            }
+            rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
+            if (rval) {
+                fprintf (stderr, "Cplex failed\n");
+                return 1;
+            }
+            if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, old)) {
+                fprintf (stderr, "CPXsetintparam failed\n");
+                return 1;
+            }
+        } else {
+            fprintf (stderr, "Cplex failed\n");
+            return 1;
+        }
+    }
+    solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
+    if (solstat == CPX_UNBOUNDED) {
+        printf ("Infeasible in cplex_dualopt\n");
+        return 2;
+    } else if (solstat != CPX_OPTIMAL && solstat != CPX_OPTIMAL_INFEAS) {
+        fprintf (stderr, "Cplex optimization status %d\n", solstat);
+        if (solstat == CPX_IT_LIM_FEAS) {
+            int itlim;
+            rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_ITLIM, &itlim);
+            if (!rval) {
+                printf ("cplex interation limit: %d\n", itlim);
+                fflush (stdout);
+            }
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#define CC_MAX_REFACTORFREQ  150
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_limited_dualopt (CClp *lp, int iterationlim, int *status,
+                          double *objupperlim)
+#else
+int CClp_limited_dualopt (lp, iterationlim, status, objupperlim)
+CClp *lp;
+int iterationlim;
+int *status;
+double *objupperlim;
+#endif
+{
+    int rval = 0;
+    int sval = 0;
+    int solstat;
+
+    int got_iterationlim = 0;
+    int got_presolveind  = 0;
+    int got_objupperlim  = 0;
+    int got_refactorfreq = 0;
+
+    int    old_iterationlim;
+    int    old_presolveind;
+    double old_objupperlim;
+    int    old_refactorfreq;
+
+    rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_ITLIM, &old_iterationlim);
+    if (rval) {
+        fprintf (stderr, "CPXgetintparam failed\n"); goto CLEANUP;
+    }
+    got_iterationlim = 1;
+
+    rval = CPXgetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM, &old_objupperlim);
+    if (rval) {
+        fprintf (stderr, "CPXgetdblparam failed\n"); goto CLEANUP;
+    }
+    got_objupperlim = 1;
+
+    rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_PREIND, &old_presolveind);
+    if (rval) {
+        fprintf (stderr, "CPXgetintparam failed\n"); goto CLEANUP;
+    }
+    got_presolveind = 1;
+
+    rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_REINV, &old_refactorfreq);
+    if (rval) {
+        fprintf (stderr, "CPXgetintparam failed\n"); goto CLEANUP;
+    }
+    got_refactorfreq = 1;
+
+    rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_ITLIM, iterationlim);
+    if (rval) {
+        fprintf (stderr, "CPXsetintparam failed\n"); goto CLEANUP;
+    }
+
+    if ( iterationlim < CC_MAX_REFACTORFREQ ) {
+        rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_REINV, iterationlim+1);
+        if (rval) {
+            fprintf (stderr, "CPXsetintparam failed\n"); goto CLEANUP;
+        }
+    }
+
+    if (objupperlim) {
+        rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM, *objupperlim);
+        if (rval) {
+            fprintf (stderr, "CPXsetdblparam failed\n"); goto CLEANUP;
+        }
+    }
+
+    rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
+    if (rval) {
+        if (rval == CPXERR_PRESLV_INForUNBD) {
+            printf ("Cplex presolve failed, force simplex\n");
+            fflush (stdout);
+
+            if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, CPX_OFF)) {
+                fprintf (stderr, "CPXsetintparam failed\n"); goto CLEANUP;
+            }
+            rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
+            if (rval) {
+                fprintf (stderr, "Cplex failed\n"); goto CLEANUP;
+            }
+        } else {
+            fprintf (stderr, "Cplex failed\n"); goto CLEANUP;
+        }
+    }
+    solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
+    if (solstat==CPX_IT_LIM_INFEAS) {
+        rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM, -1.0E75);
+        if (rval) {
+            fprintf (stderr, "CPXsetdblparam failed\n"); goto CLEANUP;
+        }
+        /* We could be even more aggressive here and make the iteration
+           limit infinite, but that approach seems contrary to the
+           intent of this function.  Hence, the repeat test for
+           CPX_IT_LIM_INFEAS below -- REB, 1 July 97 */
+        rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
+        if (rval) {
+            fprintf (stderr, "Cplex failed\n"); goto CLEANUP;
+        }
+    }
+
+    if (solstat == CPX_UNBOUNDED) {
+        printf ("Infeasible in cplex_dualopt\n"); fflush (stdout);
+        if (status) *status = CClp_INFEASIBLE;
+    } else if (solstat == CPX_IT_LIM_INFEAS) {
+        printf ("LP infeasible after the limited number of iterations\n");
+        fflush (stdout);
+        if (status) *status = CClp_UNKNOWN;
+    } else if (solstat != CPX_OPTIMAL && solstat != CPX_OPTIMAL_INFEAS &&
+               solstat != CPX_IT_LIM_FEAS && solstat != CPX_OBJ_LIM) {
+        fprintf (stderr, "Cplex optimization status %d\n", solstat);
+        if (status) *status = CClp_FAILURE;
+    } else {
+        if (status) *status = CClp_SUCCESS;
+    }
+
+CLEANUP:
+
+    if (got_iterationlim == 1) {
+        sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_ITLIM,
+                               old_iterationlim);
+        if (sval) {
+            fprintf (stderr, "CPXsetintparam failed\n");
+            rval = 1;
+        }
+    }
+
+    if (got_objupperlim == 1) {
+        sval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
+                               old_objupperlim);
+        if (sval) {
+            fprintf (stderr, "CPXsetdblparam failed\n");
+            rval = 1;
+        }
+    }
+
+    if (got_presolveind == 1) {
+        sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND,
+                               old_presolveind);
+        if (sval) {
+            fprintf (stderr, "CPXsetintparam failed\n");
+            rval = 1;
+        }
+    }
+
+    if (got_refactorfreq == 1) {
+        sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_REINV,
+                               old_refactorfreq);
+        if (sval) {
+            fprintf (stderr, "CPXsetintparam failed\n");
+            rval = 1;
+        }
+    }
+
+    if (rval && status) {
+        *status = CClp_FAILURE;
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_primalopt (CClp *lp)
+#else
+int CClp_primalopt (lp)
+CClp *lp;
+#endif
+{
+    int rval;
+    int solstat;
+#ifdef  CC_CPLEX_WRITE_PRIMAL
+    static int  probcnt = 0;
+    char probname[100];
+
+    sprintf (probname, "%s.prim%d.sav", lp->lpspace.probname, probcnt);
+    probcnt++;
+    printf ("Writing %s\n", probname);
+    CPXsavwrite (lp->cplex_env, lp->cplex_lp, probname);
+#endif
+
+    rval = CPXprimopt (lp->cplex_env, lp->cplex_lp);
+    if (rval) {
+        fprintf (stderr, "Cplex optimize failed\n");
+        return 1;
+    }
+    solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
+    if (solstat == CPX_INFEASIBLE) {
+        printf ("Infeasible.\n");
+        return 2;
+    } else if (solstat != CPX_OPTIMAL && solstat != CPX_OPTIMAL_INFEAS) {
+        fprintf (stderr, "Cplex optimization status %d\n", solstat);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_addrows (CClp *lp, int newrows, int newnz, double *rhs, char *sense,
+                  int *rmatbeg, int *rmatind, double *rmatval)
+#else
+int CClp_addrows (lp, newrows, newnz, rhs, sense, rmatbeg, rmatind, rmatval)
+CClp *lp;
+int newrows, newnz;
+double *rhs;
+char *sense;
+int *rmatbeg, *rmatind;
+double *rmatval;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXaddrows (lp->cplex_env, lp->cplex_lp, 0, newrows, newnz,
+                       rhs, sense, rmatbeg, rmatind, rmatval,
+                       (char **) NULL, (char **) NULL);
+    if (rval) fprintf (stderr, "CPXaddrows failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_addcols (CClp *lp, int newcols, int newnz, double *obj,
+                  int *cmatbeg, int *cmatind, double *cmatval,
+                  double *lb, double *ub)
+#else
+int CClp_addcols (lp, newcols, newnz, obj, cmatbeg, cmatind, cmatval, lb, ub)
+CClp *lp;
+int newcols, newnz;
+double *obj;
+int *cmatbeg, *cmatind;
+double *cmatval;
+double *lb, *ub;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXaddcols (lp->cplex_env, lp->cplex_lp, newcols, newnz, obj,
+                   cmatbeg, cmatind, cmatval, lb, ub, (char **) NULL);
+    if (rval) fprintf (stderr, "CPXaddcols failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_row (CClp *lp, int i)
+#else
+int CClp_delete_row (lp, i)
+CClp *lp;
+int i;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXdelrows (lp->cplex_env, lp->cplex_lp, i, i);
+    if (rval) fprintf (stderr, "CPXdelrows failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_set_of_rows (CClp *lp, int *delstat)
+#else
+int CClp_delete_set_of_rows (lp, delstat)
+CClp *lp;
+int *delstat;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXdelsetrows (lp->cplex_env, lp->cplex_lp, delstat);
+    if (rval) fprintf (stderr, "CPXdelsetrows failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_column (CClp *lp, int i)
+#else
+int CClp_delete_column (lp, i)
+CClp *lp;
+int i;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXdelcols (lp->cplex_env, lp->cplex_lp, i, i);
+    if (rval) fprintf (stderr, "CPXdelcols failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_set_of_columns (CClp *lp, int *delstat)
+#else
+int CClp_delete_set_of_columns (lp, delstat)
+CClp *lp;
+int *delstat;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXdelsetcols (lp->cplex_env, lp->cplex_lp, delstat);
+    if (rval) fprintf (stderr, "CPXdelsetcols failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_setbnd (CClp *lp, int col, char lower_or_upper, double bnd)
+#else
+int CClp_setbnd (lp, col, lower_or_upper, bnd)
+CClp *lp;
+int col;
+char lower_or_upper;
+double bnd;
+#endif
+{
+    int cindex[1];
+    double bd[1];
+    char lu[1];
+    int rval;
+
+    cindex[0] = col;
+    lu[0] = lower_or_upper;
+    bd[0] = bnd;
+
+    rval = CPXchgbds (lp->cplex_env, lp->cplex_lp, 1, cindex, lu, bd);
+    if (rval) {
+        fprintf (stderr, "Couldn't set bnd on variable %d in cplex\n", col);
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_init_basis (CClpbasis *b)
+#else
+void CClp_init_basis (b)
+CClpbasis *b;
+#endif
+{
+    if (b) {
+        b->cstat = (int *) NULL;
+        b->rstat = (int *) NULL;
+        b->dnorm = (double *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_free_basis (CClpbasis *b)
+#else
+void CClp_free_basis (b)
+CClpbasis *b;
+#endif
+{
+    if (b) {
+        CC_IFFREE (b->cstat, int);
+        CC_IFFREE (b->rstat, int);
+        CC_IFFREE (b->dnorm, double);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_get_basis_and_norms (CClp *lp, CClpbasis *b)
+#else
+int CClp_get_basis_and_norms (lp, b)
+CClp *lp;
+CClpbasis *b;
+#endif
+{
+    int rval = 0;
+    int ncols, nrows;
+
+    CClp_init_basis (b);
+
+    ncols = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
+    if (ncols == 0) {
+        fprintf (stderr, "No columns in LP\n");
+        rval = 1; goto CLEANUP;
+    }
+    nrows = CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
+    if (nrows == 0) {
+        fprintf (stderr ,"No rows in LP\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    b->cstat = CC_SAFE_MALLOC (ncols, int);
+    b->rstat = CC_SAFE_MALLOC (nrows, int);
+    b->dnorm = CC_SAFE_MALLOC (nrows, double);
+    if (!b->cstat || !b->rstat || !b->dnorm) {
+        fprintf (stderr, "out of memory in CClp_get_basis_and_norms\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CPXgetbasednorms (lp->cplex_env, lp->cplex_lp, b->cstat, b->rstat,
+                             b->dnorm);
+    if (rval) {
+        fprintf (stderr, "CPXgetbasednorms failed\n"); goto CLEANUP;
+    }
+
+    return 0;
+
+CLEANUP:
+
+    CClp_free_basis (b);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_load_basis_and_norms (CClp *lp, CClpbasis *b)
+#else
+int CClp_load_basis_and_norms (lp, b)
+CClp *lp;
+CClpbasis *b;
+#endif
+{
+    int rval = 0;
+
+    if (b->cstat && b->rstat && b->dnorm) {
+        rval = CPXcopybasednorms (lp->cplex_env, lp->cplex_lp, b->cstat,
+                                  b->rstat, b->dnorm);
+        if (rval) {
+            fprintf (stderr, "CPXcopybasednorms failed\n"); goto CLEANUP;
+        }
+    } else if (b->cstat && b->rstat) {
+        rval = CPXloadbase (lp->cplex_env, lp->cplex_lp, b->cstat, b->rstat);
+        if (rval) {
+            fprintf (stderr, "CPXloadbase failed\n"); goto CLEANUP;
+        }
+    } else {
+        printf ("WARNING: No basis or norms in call to load_basis_and_norms\n");
+        fflush (stdout);
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_basis (CClp *lp, int *cstat, int *rstat)
+#else
+int CClp_basis (lp, cstat, rstat)
+CClp *lp;
+int *cstat;
+int *rstat;
+#endif
+{
+    int rval;
+
+    rval = CPXgetbase (lp->cplex_env, lp->cplex_lp, cstat, rstat);
+    if (rval) {
+        fprintf (stderr, "CPXgetbase failed\n");
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_loadbasis (CClp *lp, int *cstat, int *rstat)
+#else
+int CClp_loadbasis (lp, cstat, rstat)
+CClp *lp;
+int *cstat, *rstat;
+#endif
+{
+    int rval;
+
+    rval = CPXloadbase (lp->cplex_env, lp->cplex_lp, cstat, rstat);
+    if (rval) {
+        fprintf (stderr, "CPXloadbase failed\n");
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getbasis_and_norms (CClp *lp, int *cstat, int *rstat, double *dnorm)
+#else
+int CClp_getbasis_and_norms (lp, cstat, rstat, dnorm)
+CClp *lp;
+int *cstat, *rstat;
+double *dnorm;
+#endif
+{
+    int rval;
+
+    rval = CPXgetbasednorms (lp->cplex_env, lp->cplex_lp, cstat, rstat,
+                             dnorm);
+    if (rval) {
+        fprintf (stderr, "CPXgetbasednorms failed\n");
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_loadbasis_and_norms (CClp *lp, int *cstat, int *rstat,
+                                 double *dnorm)
+#else
+int CClp_loadbasis_and_norms (lp, cstat, rstat, dnorm)
+CClp *lp;
+int *cstat, *rstat;
+double *dnorm;
+#endif
+{
+    int rval;
+
+    rval = CPXcopybasednorms (lp->cplex_env, lp->cplex_lp, cstat, rstat,
+                              dnorm);
+    if (rval) {
+        fprintf (stderr, "CPXcopybasednorms failed\n");
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_x (CClp *lp, double *x)
+#else
+int CClp_x (lp, x)
+CClp *lp;
+double *x;
+#endif
+{
+    int rval = 0;
+    int ncols;
+
+    ncols = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
+    if (ncols == 0) {
+        fprintf (stderr, "No columns in LP\n");
+        return 1;
+    }
+    rval = CPXgetx (lp->cplex_env, lp->cplex_lp, x, 0, ncols - 1);
+    if (rval) {
+        fprintf (stderr, "CPXgetx failed\n");
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_rc (CClp *lp, double *rc)
+#else
+int CClp_rc (lp, rc)
+CClp *lp;
+double *rc;
+#endif
+{
+    int rval = 0;
+    int ncols;
+
+    ncols = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
+    if (ncols == 0) {
+        fprintf (stderr, "No columns in LP\n"); return 1;
+    }
+    rval = CPXgetdj (lp->cplex_env, lp->cplex_lp, rc, 0, ncols - 1);
+    if (rval) {
+        fprintf (stderr, "CPXgetdj failed\n"); return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_pi_range (CClp *lp, double *pi, int from, int to)
+#else
+int CClp_pi_range (lp, pi, from, to)
+CClp *lp;
+double *pi;
+int from, to;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXgetpi (lp->cplex_env, lp->cplex_lp, pi, from, to);
+    if (rval) {
+        fprintf (stderr, "CPXgetpi failed\n"); return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_objval (CClp *lp, double *obj)
+#else
+int CClp_objval (lp, obj)
+CClp *lp;
+double *obj;
+#endif
+{
+    int rval;
+
+    rval = CPXgetobjval (lp->cplex_env, lp->cplex_lp, obj);
+    if (rval) {
+        fprintf (stderr, "CPXgetobjval failed\n");
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_nonzeros (CClp *lp)
+#else
+int CClp_nonzeros (lp)
+CClp *lp;
+#endif
+{
+    int k;
+
+    k = CPXgetnumnz (lp->cplex_env, lp->cplex_lp);
+    printf ("NONZEROS = %d\n", k); fflush (stdout);
+    return k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_status (CClp *lp, int *status)
+#else
+int CClp_status (lp, status)
+CClp *lp;
+int *status;
+#endif
+{
+    int solmethod, solstat;
+
+    solmethod = CPXgetmethod (lp->cplex_env, lp->cplex_lp);
+    if (solmethod == CPXALG_PRIMAL || solmethod == CPXALG_DUAL) {
+        solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
+        if (solstat == CPX_OPTIMAL || solstat == CPX_OPTIMAL_INFEAS) {
+            *status = 0;
+            return 0;
+        } else if (solstat == CPX_UNBOUNDED && solmethod == CPXALG_DUAL) {
+            *status = 1;
+            return 0;
+        } else {
+            fprintf (stderr, "lp in an unknown state: %d %d\n",
+                           solmethod, solstat);
+            *status = -1;
+            return 1;
+        }
+    } else {
+        fprintf (stderr, "lp not solved by usual methods: %d\n", solmethod);
+        *status = -2;
+        return 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getweight (CClp *lp, int nrows, int *rmatbeg, int *rmatind,
+                    double *rmatval, double *weight)
+#else
+int CClp_getweight (lp, nrows, rmatbeg, rmatind, rmatval, weight)
+CClp *lp;
+int nrows;
+int *rmatbeg;
+int *rmatind;
+double *rmatval;
+double *weight;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXgetweight (lp->cplex_env, lp->cplex_lp, nrows,
+                         rmatbeg, rmatind, rmatval, weight, CPX_DPRIIND_STEEP);
+    if (rval) {
+        fprintf (stderr, "CPXgetweight failed\n");
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_dump_lp (CClp *lp, char *fname)
+#else
+int CClp_dump_lp (lp, fname)
+CClp *lp;
+char *fname;
+#endif
+{
+    int rval = 0;
+
+    rval = CPXlpwrite (lp->cplex_env, lp->cplex_lp, fname);
+    if (rval) {
+        fprintf (stderr, "CPXlpwrite failed\n");
+    }
+    return rval;
+}
+
+#define OURCPLEXZERO    (1.0E-10)
+#define OURCPLEX_INTTOL (0.0001)
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getgoodlist (CClp *lp, int *goodlist, int *goodlen_p,
+                      double *downpen, double *uppen)
+#else
+int CClp_getgoodlist (lp, goodlist, goodlen_p, downpen, uppen)
+CClp *lp;
+int *goodlist;
+int *goodlen_p;
+double *downpen;
+double *uppen;
+#endif
+{
+    int  rval = 0;
+    int  ncols, i, k;
+    int  *cstat = (int *) NULL;
+    double *x = (double *) NULL;
+
+    /* Call CPXdualopt and verify optimality */
+
+    if ( CPXdualopt (lp->cplex_env, lp->cplex_lp) ) {
+        fprintf (stderr, "CPXdualopt failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    ncols = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
+    if ( ncols == 0 ) {
+        fprintf (stderr, "No columns in LP\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    x = CC_SAFE_MALLOC (ncols, double);
+    if (x == (double *) NULL) {
+        fprintf (stderr, "out of memory in branch_getgoodlist\n");
+        rval = 1; goto CLEANUP;
+    }
+    if (CPXgetx (lp->cplex_env, lp->cplex_lp, x, 0, ncols-1)) {
+        fprintf (stderr, "CPXgetx failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    cstat = CC_SAFE_MALLOC (ncols, int);
+    if ( cstat == (int *) NULL ) {
+        fprintf (stderr, "Out of memory\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    /* Get basis */
+
+    if ( CPXgetbase (lp->cplex_env, lp->cplex_lp, cstat, (int *) NULL) ) {
+        fprintf (stderr, "CPXgetbase failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    /* Make initial goodlist and goodlen */
+
+    *goodlen_p = 0;
+    for (i = 0; i < ncols; i++) {
+       if ( cstat[i] == 1 ) {
+          goodlist[(*goodlen_p)++] = i;
+       }
+    }
+
+    /* Call CPXmdleave */
+
+    if ( CPXmdleave (lp->cplex_env, lp->cplex_lp, goodlist, *goodlen_p,
+                     downpen, uppen)) {
+       fprintf (stderr, "CPXmdleave failed\n");
+       rval = 1; goto CLEANUP;
+    }
+
+    /* Keep only the nondegenerate ones */
+
+    k = *goodlen_p;
+    *goodlen_p = 0;
+    for (i = 0; i < k; i++) {
+       if ( CC_OURABS (downpen[i]) > OURCPLEXZERO   &&
+            CC_OURABS (uppen[i])   > OURCPLEXZERO   &&
+            x[goodlist[i]] >= OURCPLEX_INTTOL    &&
+            x[goodlist[i]] <= 1 - OURCPLEX_INTTOL  ) {
+          goodlist[*goodlen_p]  = goodlist[i];
+          downpen[*goodlen_p] = x[goodlist[i]] * downpen[i];
+          uppen[*goodlen_p]   = (1.0 - x[goodlist[i]]) * uppen[i];
+          (*goodlen_p)++;
+       }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (cstat, int);
+    CC_IFFREE (x, double);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_strongbranch (CClp *lp, int *candidatelist, int ncand,
+                       double *downpen, double *uppen, int iterations,
+                       double *upperbound)
+#else
+int CClp_strongbranch (lp, candidatelist, ncand, downpen, uppen, iterations,
+                       upperbound)
+CClp *lp;
+int *candidatelist;
+int ncand;
+double *downpen;
+double *uppen;
+int iterations;
+double *upperbound;
+#endif
+{
+    double oldupperbound;
+    int rval = 0;
+    int sval = 0;
+
+    if (upperbound) {
+        rval = CPXgetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
+                               &oldupperbound);
+        if (rval) {
+            fprintf (stderr, "CPXgetdblparam failed\n"); return rval;
+        }
+        rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
+                               *upperbound);
+        if (rval) {
+            fprintf (stderr, "CPXsetdblparam failed\n"); return rval;
+        }
+    }
+
+    rval = CPXstrongbranch (lp->cplex_env, lp->cplex_lp, candidatelist,
+                            ncand, downpen, uppen, iterations);
+    if (rval) {
+        fprintf (stderr, "CPXstrongbranch failed\n");
+        if (upperbound) {
+            sval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
+                                   oldupperbound);
+            if (sval) {
+                fprintf (stderr,
+                         "CPXsetdblparam failed with return code %d\n",
+                         sval);
+            }
+        }
+        return rval;
+    }
+
+    if (upperbound) {
+        rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
+                               oldupperbound);
+        if (rval) {
+            fprintf (stderr, "CPXsetdblparam failed\n"); return rval;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getfarkasmultipliers (CClp *lp, double *y)
+#else
+int CClp_getfarkasmultipliers (lp, y)
+CClp *lp;
+double *y;
+#endif
+{
+    int  rval = 0;
+
+    int  i = 0, nrows, idiv, jdiv;
+    double  val, lb, ub;
+    int  *bhead =  (int *) NULL;
+    char  *sense = (char *) NULL;
+
+    if ( lp->cplex_env == (struct cpxenv *) NULL ||
+         lp->cplex_lp  == (struct cpxlp *)  NULL) {
+        rval = 1;  fprintf (stderr, "env object or lp object is NULL\n");
+        goto CLEANUP;
+    }
+
+    if ( CPXgetmethod (lp->cplex_env, lp->cplex_lp) != CPXALG_DUAL  ||
+         CPXgetstat (lp->cplex_env, lp->cplex_lp )  != CPX_UNBOUNDED  ) {
+        rval = 1;  fprintf (stderr, "Incorrect solution type\n");
+        goto CLEANUP;
+    }
+
+    if ( CPXgetijdiv (lp->cplex_env, lp->cplex_lp, &idiv, &jdiv) ) {
+        rval = 1;  fprintf (stderr, "CPXgetijdiv failed\n");
+        goto CLEANUP;
+    }
+
+    if ( (jdiv == -1  &&  idiv == -1) ||
+         (jdiv != -1  &&  idiv != -1)   ) {
+        rval = 1;  fprintf (stderr, "CPLEX returned illegal indices\n");
+        goto CLEANUP;
+    }
+
+    nrows = CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
+    if ( nrows == 0 ) {
+        rval = 1;  fprintf (stderr, "lp->cplex_lp has no rows\n");
+        goto CLEANUP;
+    }
+
+    bhead = CC_SAFE_MALLOC (nrows, int);
+    sense = CC_SAFE_MALLOC (nrows, char);
+    if ( bhead == (int *) NULL ||
+         sense == (char *) NULL   ) {
+        rval = -1;  fprintf (stderr, "Out of memory\n");
+        goto CLEANUP;
+    }
+
+    if ( CPXgetbhead (lp->cplex_env, lp->cplex_lp, bhead, NULL) ) {
+        rval = 1;  fprintf (stderr, "CPXgetbhead failed\n");
+        goto CLEANUP;
+    }
+
+    if ( CPXgetsense (lp->cplex_env, lp->cplex_lp, sense, 0, nrows-1) ) {
+        rval = 1;  fprintf (stderr, "CPXgetsense failed\n");
+        goto CLEANUP;
+    }
+
+    if ( jdiv >= 0 ) {
+        for (i = 0; i < nrows; i++) {
+            if ( bhead[i] == jdiv )  break;
+        }
+        if ( i == nrows ) {
+            rval = 1;  fprintf (stderr, "Basis index not found\n");
+            goto CLEANUP;
+        }
+        if ( CPXgetx (lp->cplex_env, lp->cplex_lp, &val, jdiv, jdiv) ) {
+            rval = 1;  fprintf (stderr, "CPXgetx failed\n");
+            goto CLEANUP;
+        }
+        if ( CPXgetlb (lp->cplex_env, lp->cplex_lp, &lb, jdiv, jdiv) ) {
+            rval = 1;  fprintf (stderr, "CPXgetlb failed\n");
+            goto CLEANUP;
+        }
+        if ( CPXgetub (lp->cplex_env, lp->cplex_lp, &ub, jdiv, jdiv) ) {
+            rval = 1;  fprintf (stderr, "CPXgetub failed\n");
+            goto CLEANUP;
+        }
+    } else {
+        for (i = 0; i < nrows; i++) {
+            if ( bhead[i] ==  -idiv-1 )  break;
+        }
+        if ( i == nrows ) {
+            rval = 1;  fprintf (stderr, "Basis index not found\n");
+            goto CLEANUP;
+        }
+        if ( CPXgetslack (lp->cplex_env, lp->cplex_lp, &val, idiv, idiv) ) {
+            rval = 1;  fprintf (stderr, "CPXgetslack failed\n");
+            goto CLEANUP;
+        }
+        lb = 0.0;
+        if ( sense[idiv] == 'E' )  ub = 0.0;
+        else                       ub = INFBOUND;
+        if ( sense[idiv] == 'G' )  val *= -1.0;
+    }
+
+    if ( CPXbinvrow (lp->cplex_env, lp->cplex_lp, i, y) ) {
+        rval = 1;  fprintf (stderr, "CPXbinvrow failed\n");
+        goto CLEANUP;
+    }
+
+    if ( val < lb ) {
+        for (i = 0; i < nrows; i++)  y[i] *= -1.0;
+    }
+
+    for (i = 0; i < nrows; i++) {
+        if ( sense[i] == 'L'  &&  y[i] > 0.0 )  y[i] = 0.0;
+        if ( sense[i] == 'G'  &&  y[i] < 0.0 )  y[i] = 0.0;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (bhead, int);
+    CC_IFFREE (sense, char);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_pivotin (CClp *lp, int i)
+#else
+void CClp_pivotin (lp, i)
+CClp *lp;
+int i;
+#endif
+{
+    int locali = i;
+
+    if ( CPXpivotin (lp->cplex_env, lp->cplex_lp, &locali, 1) ) {
+        fprintf (stderr, "CPXpivotin failed, continuing anyway\n");
+    }
+}
+
diff --git a/contrib/blossom/concorde97/LP/lpsolve.c b/contrib/blossom/concorde97/LP/lpsolve.c
new file mode 100644
index 0000000000000000000000000000000000000000..374ede332c091796ac0f9ccb02650769a8abaf24
--- /dev/null
+++ b/contrib/blossom/concorde97/LP/lpsolve.c
@@ -0,0 +1,797 @@
+/***************************************************************************/
+/*                                                                         */
+/*              Interface Routines to an LP Solver                         */
+/*                                                                         */
+/*                                                                         */
+/*                                                                         */
+/*  NOTE: These are just dummy routines. To make use of the LP-based       */
+/*   portion of concorde you will need to write an interface between these */
+/*   routines and an LP solve. To use the CPLEX 4.1 library, the code in   */
+/*   lpcplex.c can be used instead of this file.                           */
+/*                                                                         */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: April 17, 1997                                                   */
+/*        June 19, 1997 (bico, REB)                                        */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*                                                                         */
+/*    void CClp_init_struct (CClp *lp)                                     */
+/*      INITIALIZES the fields of the LP structure to NULL.                */
+/*                                                                         */
+/*    int CClp_init (CClp *lp)                                             */
+/*      INITIALIZES the LP.                                                */
+/*                                                                         */
+/*   void CClp_free (CClp *lp)                                             */
+/*      FREES the LP (but not pointer to the LP).                          */
+/*                                                                         */
+/*   int CClp_loadlp (CClp *lp, char *name, int ncols, int nrows,          */
+/*            int objsense, double *obj, double *rhs, char *sense,         */
+/*            int *matbeg, int *matcnt,                                    */
+/*            int *matind, double *matval,                                 */
+/*            double *lb, double *ub)                                      */
+/*      LOADS the data into the LP. The memory is used by the LP solver,   */
+/*       and thus should not be freed until after a call to CClp_free.     */
+/*        -name attaches a name to the LP (it can be used by the LP solver */
+/*         in io routines)                                                 */
+/*        -ncols and nrows give the number of columns and rows in the LP   */
+/*        -objsense should be -1 for minimize and 1 for maximize           */
+/*        -obj and rhs are arrays giving the objective function and rhs    */
+/*        -sense is an array specifying 'L', 'E', or 'G' for each of the   */
+/*         rows                                                            */
+/*        -matbeg, matcnt, matind, and matval give the coefficients of     */
+/*         the contraint matrix in column by column order. matbeg gives    */
+/*         gives the index of the start of each column; matcnt gives the   */
+/*         number of coefficients in each column; matind gives the indices */
+/*         of the rows where the coefficients are located in the contraint */
+/*         matrix (so for column j, the indices are given in matcnt[j]     */
+/*         locations starting at matind[matbeg[j]]; and matval gives the   */
+/*         actual coefficients (organized like matind).                    */
+/*        -lb and ub are arrays giving the upper and lower bounds of       */
+/*         the variables.                                                  */
+/*                                                                         */
+/*   int CClp_opt (CClp *lp, int method)                                   */
+/*      CALLS designated LP solution method.                               */
+/*                                                                         */
+/*   int CClp_dualopt (CClp *lp)                                           */
+/*      CALLS the dual simplex method.                                     */
+/*                                                                         */
+/*   int CClp_limited_dualopt (CClp *lp, int lim, double *upperbound,      */
+/*           int *status)                                                  */
+/*      CALLS the dual simplex method with a limit on the number of pivots.*/
+/*        -upperbound it is used to cutoff the dual simplex method (when   */
+/*         the objective value reaches upperbound); it can be NULL         */
+/*        -status returns the status of the optimization (it can be NULL)  */
+/*                                                                         */
+/*   void CClp_pivotin (CClp *lp, int i)                                   */
+/*      Puts slack/artificial on row i into the resident basis             */
+/*      If there is no resident basis, the call fails                      */
+/*                                                                         */
+/*   int CClp_primalopt (CClp *lp)                                         */
+/*      CALLS the primal simplex method.                                   */
+/*                                                                         */
+/*   int CClp_addrows (CClp *lp, int newrows, int newnz, double *rhs,      */
+/*            char *sense, int *rmatbeg, int *rmatind, double *rmatval)    */
+/*      ADDS the rows to the LP.                                           */
+/*        -newrows is the number of rows to be added                       */
+/*        -newnz is the number of nonzero coefficients in the new rows     */
+/*        -rhs is an array of the rhs values for the new rows              */
+/*        -sense is 'L', 'E', or 'G' for each of the new rows              */
+/*        -rmatbeg, rmatind, and rmatval give the coefficients of the      */
+/*         new rows in sparse format. The arrays can be freed after the    */
+/*         call.                                                           */
+/*                                                                         */
+/*   int CClp_addcols (CClp *lp, int newcols, int newnz, double *obj,      */
+/*            int *cmatbeg, int *cmatind, double *cmatval,                 */
+/*            double *lb, double *ub)                                      */
+/*      ADDS the columns to the LP.                                        */
+/*                                                                         */
+/*   int CClp_delete_row (CClp *lp, int i)                                 */
+/*      DELETES row i of the LP.                                           */
+/*                                                                         */
+/*   int CClp_delete_set_of_rows (CClp *lp, int *delstat)                  */
+/*      DELETES the rows corresponding to 1 entries in delstat.            */
+/*        -delstat is a 0/1 array having an entry for each row             */
+/*                                                                         */
+/*   int CClp_delete_column (CClp *lp, int i)                              */
+/*      DELETES column i from the LP.                                      */
+/*                                                                         */
+/*   int CClp_delete_set_of_columns (CClp *lp, int *delstat)               */
+/*      DELETES the columns corresponding to the 1 entries in delstat.     */
+/*        -delstat is a 0/1 array having an entry for each column          */
+/*                                                                         */
+/*   int CClp_setbnd (CClp *lp, int col, char lower_or_upper, double bnd)  */
+/*      SETS the bound on the variable index by col.                       */
+/*        -lower_or_upper should be either 'L' or 'U'                      */
+/*                                                                         */
+/*   void CClp_init_basis (CClpbasis *b)                                   */
+/*      INITIALIZES the fields of the basis structure.                     */
+/*                                                                         */
+/*   void CClp_free_basis (CClpbasis *b)                                   */
+/*      FREEs the basis structure.                                         */
+/*                                                                         */
+/*   int CClp_get_basis_and_norms (CClp *lp, CClpbasis *b)                 */
+/*      RETURNS the current basis and dual norms.                          */
+/*      Note: The arrays are allocated by this function are should be      */
+/*       freed by a call to CC_lp_free_basis ().                           */
+/*                                                                         */
+/*   int CClp_load_basis_and_norms (CClp *lp, CClpbasis *b)                */
+/*      LOADS the basis and norm int the LP.                               */
+/*      Note: If the norms field is not set, then just the basis is loaded.*/
+/*                                                                         */
+/*   int CClp_basis (CClp *lp, int *cstat, int *rstat)                     */
+/*      RETURNS the current basis. cstat or rstat can by NULL.             */
+/*        -cstat should be an array of length at least ncols               */
+/*        -rstat should be an array of length at least nrows               */
+/*                                                                         */
+/*   int CClp_loadbasis (CClp *lp, int *cstat, int *rstat)                 */
+/*      LOADS the basis into the LP.                                       */
+/*                                                                         */
+/*   int CClp_getbasis_and_norms (CClp *lp, int *cstat, int *rstat,        */
+/*          double *dnorm)                                                 */
+/*      RETURNS the current basis and dual norms - these items should be   */
+/*       used as a pair, in calls to CClp_loadbasis_and_norms.             */
+/*        -dnorms should be an array of length at least nrows              */
+/*                                                                         */
+/*   int CClp_loadbasis_and_norms (CClp *lp,int *cstat, int *rstat,        */
+/*          double *dnorm)                                                 */
+/*      LOADS the basis and dual norms into the LP. (This pair should      */
+/*       have been obtained by a call to CClp_getbasis_and_norms.          */
+/*                                                                         */
+/*   int CClp_x (CClp *lp, double *x)                                      */
+/*      RETURNS the current LP solution.                                   */
+/*        -x should be an array of length at least ncols                   */
+/*                                                                         */
+/*   int CClp_rc (CClp *lp, double *rc)                                    */
+/*      RETURNS the current reduced costs.                                 */
+/*        -rc should be an array of length at least ncols                  */
+/*                                                                         */
+/*   int CClp_pi_range (CClp *lp, double *pi, int from, int to)            */
+/*      RETURNS the dual values on the constraints indexed [from, to].     */
+/*        -pi should be an array of length at least (to-from+1)            */
+/*                                                                         */
+/*   int CClp_objval (CClp *lp, double *obj)                               */
+/*      RETURNS the objective value of the lp.                             */
+/*                                                                         */
+/*   int CClp_nonzeros (CClp *lp)                                          */
+/*      RETURNS the number of nonzeros in the LP.                          */
+/*                                                                         */
+/*   int CClp_status (CClp *lp, int *status)                               */
+/*      CHECKS whether the current lp is infeasible or whether an optimal  */
+/*       solution has been found. It returns an error if the LP has not    */
+/*       not been optimized.                                               */
+/*        -lp is the lp                                                    */
+/*        -status returns 0 if the lp has an optimal solution and 1 if it  */
+/*         is infeasible.                                                  */
+/*                                                                         */
+/*   int CClp_getweight (CClp *lp, int nrows, int *rmatbeg, int *rmatind,  */
+/*          double *rmatval, double *weight)                               */
+/*      COMPUTES the duals of the steepest edge norms for the n rows       */
+/*       specified in rmatbeg, rmatind, and rmatval.                       */
+/*        -weight returns the array of weights; the array should be at     */
+/*         least nrows long                                                */
+/*                                                                         */
+/*   int CClp_dump_lp (CClp *lp, char *fname)                              */
+/*      WRITES the LP to file fname.                                       */
+/*                                                                         */
+/*   int CClp_getgoodlist (CClp *lp, int *goodlist, int *ngood,            */
+/*          double *downpen, double *uppen)                                */
+/*      RETURNS an array of the column indices corresponding to variables  */
+/*       that move in both the up and down directions. This is a useful    */
+/*       list of candidates for strong branching.                          */
+/*        -goodlist, downpen and uppen should be arrays of length at       */
+/*         least ncols.                                                    */
+/*                                                                         */
+/*   int CClp_strongbranch (CClp *lp, int *candidatelist, int ncand,       */
+/*          double *downpen, double *uppen, int iterations,                */
+/*          double *upperbound)                                            */
+/*      RETURNS estimates of the lp values obtained by setting each of the */
+/*        ncand variables listed in candidatelist to 0 and 1. The estimates*/
+/*        are obtained by performing iterations pivots of dual simplex     */
+/*        method. If upperbound is not NULL, then it is used to cutoff the */
+/*        dual simplex method.                                             */
+/*         -downpen and uppen should be arrays of length at least ncand    */
+/*                                                                         */
+/*    int CClp_getfarkasmultipliers (CClp *lp, double *y)                  */
+/*      RETURNS the multipliers for a Farkas' proof after dualopt returns  */
+/*       with an unbound lp.                                               */
+/*        -y should point to an array at least as long as the number of    */
+/*         rows                                                            */
+/*      The y[] computed will satisfy the following:                       */
+/*                                                                         */
+/*         y_i <= 0  for <= constraints                                    */
+/*         y_i >= 0  for >= constraints                                    */
+/*                                                                         */
+/*         y'b - sum (y'A_j * u_j: y'A_j > 0)                              */
+/*             - sum (y'A_j * l_j: y'A_j < 0) > 0                          */
+/*                                                                         */
+/*      where b is the rhs vector, u_j is the upper bound on variable x_j, */
+/*      l_j the lower bound, and A_j the constraint matrix column for x_j. */
+/*                                                                         */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "machdefs.h"
+#include "util.h"
+#include "macrorus.h"
+#include "lp.h"
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    lp_message (void);
+
+#else
+
+static void
+    lp_message ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void lp_message (void)
+#else
+static void lp_message ()
+#endif
+{
+    fprintf (stderr, "need to link an lp solver to use this function\n");
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_init_struct (CClp *lp)
+#else
+void CClp_init_struct (lp)
+CClp *lp;
+#endif
+{
+    if (lp) lp_message ();
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_init (CClp *lp)
+#else
+int CClp_init (lp)
+CClp *lp;
+#endif
+{
+    if (lp) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_free (CClp *lp)
+#else
+void CClp_free (lp)
+CClp *lp;
+#endif
+{
+    if (lp) lp_message ();
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_loadlp (CClp *lp, char *name, int ncols, int nrows,
+                 int objsense, double *obj, double *rhs, char *sense,
+                 int *matbeg, int *matcnt,
+                 int *matind, double *matval,
+                 double *lb, double *ub)
+
+#else
+int CClp_loadlp (lp, name, ncols, nrows, objsense, obj, rhs, sense, matbeg,
+                 matcnt, matind, matval, lb, ub)
+CClp *lp;
+char *name;
+int ncols, nrows;
+int objsense;
+double *obj, *rhs;
+char *sense;
+int *matbeg, *matcnt, *matind;
+double *matval, *lb, *ub;
+#endif
+{
+    if (lp || name || ncols || nrows || objsense || obj || rhs || sense
+           || matbeg || matcnt || matind || matval || lb || ub) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_opt (CClp *lp, int method)
+#else
+int CClp_opt (lp, method)
+CClp *lp;
+int method;
+#endif
+{
+    if (lp || method) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_dualopt (CClp *lp)
+#else
+int CClp_dualopt (lp)
+CClp *lp;
+#endif
+{
+    if (lp) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_limited_dualopt (CClp *lp, int iterationlim, int *status,
+        double *objupperlim)
+#else
+int CClp_limited_dualopt (lp, iterationlim, status, objupperlim)
+CClp *lp;
+int iterationlim;
+int *status;
+double *objupperlim;
+#endif
+{
+    if (lp || iterationlim || status || objupperlim) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_primalopt (CClp *lp)
+#else
+int CClp_primalopt (lp)
+CClp *lp;
+#endif
+{
+    if (lp) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_addrows (CClp *lp, int newrows, int newnz, double *rhs, char *sense,
+                  int *rmatbeg, int *rmatind, double *rmatval)
+#else
+int CClp_addrows (lp, newrows, newnz, rhs, sense, rmatbeg, rmatind, rmatval)
+CClp *lp;
+int newrows, newnz;
+double *rhs;
+char *sense;
+int *rmatbeg, *rmatind;
+double *rmatval;
+#endif
+{
+    if (lp || newrows || newnz || rhs || sense || rmatbeg || rmatind
+           || rmatval) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_addcols (CClp *lp, int newcols, int newnz, double *obj,
+                  int *cmatbeg, int *cmatind, double *cmatval,
+                  double *lb, double *ub)
+#else
+int CClp_addcols (lp, newcols, newnz, obj, cmatbeg, cmatind, cmatval, lb, ub)
+CClp *lp;
+int newcols, newnz;
+double *obj;
+int *cmatbeg, *cmatind;
+double *cmatval;
+double *lb, *ub;
+#endif
+{
+    if (lp || newcols || newnz || obj || cmatbeg || cmatind || cmatval
+           || lb || ub) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_row (CClp *lp, int i)
+#else
+int CClp_delete_row (lp, i)
+CClp *lp;
+int i;
+#endif
+{
+    if (lp || i) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_set_of_rows (CClp *lp, int *delstat)
+#else
+int CClp_delete_set_of_rows (lp, delstat)
+CClp *lp;
+int *delstat;
+#endif
+{
+    if (lp || delstat) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_column (CClp *lp, int i)
+#else
+int CClp_delete_column (lp, i)
+CClp *lp;
+int i;
+#endif
+{
+    if (lp || i) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_delete_set_of_columns (CClp *lp, int *delstat)
+#else
+int CClp_delete_set_of_columns (lp, delstat)
+CClp *lp;
+int *delstat;
+#endif
+{
+    if (lp || delstat) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_setbnd (CClp *lp, int col, char lower_or_upper, double bnd)
+#else
+int CClp_setbnd (lp, col, lower_or_upper, bnd)
+CClp *lp;
+int col;
+char lower_or_upper;
+double bnd;
+#endif
+{
+    if (lp || col || lower_or_upper || bnd) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_init_basis (CClpbasis *b)
+#else
+void CClp_init_basis (b)
+CClpbasis *b;
+#endif
+{
+    if (b) lp_message ();
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_free_basis (CClpbasis *b)
+#else
+void CClp_free_basis (b)
+CClpbasis *b;
+#endif
+{
+    if (b) lp_message ();
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_get_basis_and_norms (CClp *lp, CClpbasis *b)
+#else
+int CClp_get_basis_and_norms (lp, b)
+CClp *lp;
+CClpbasis *b;
+#endif
+{
+    if (lp || b) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_load_basis_and_norms (CClp *lp, CClpbasis *b)
+#else
+int CClp_load_basis_and_norms (lp, b)
+CClp *lp;
+CClpbasis *b;
+#endif
+{
+    if (lp || b) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_basis (CClp *lp, int *cstat, int *rstat)
+#else
+int CClp_basis (lp, cstat, rstat)
+CClp *lp;
+int *cstat;
+int *rstat;
+#endif
+{
+    if (lp || cstat || rstat) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_loadbasis (CClp *lp, int *cstat, int *rstat)
+#else
+int CClp_loadbasis (lp, cstat, rstat)
+CClp *lp;
+int *cstat, *rstat;
+#endif
+{
+    if (lp || cstat || rstat) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getbasis_and_norms (CClp *lp, int *cstat, int *rstat, double *dnorm)
+#else
+int CClp_getbasis_and_norms (lp, cstat, rstat, dnorm)
+CClp *lp;
+int *cstat, *rstat;
+double *dnorm;
+#endif
+{
+    if (lp || cstat || rstat || dnorm) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_loadbasis_and_norms (CClp *lp, int *cstat, int *rstat,
+        double *dnorm)
+#else
+int CClp_loadbasis_and_norms (lp, cstat, rstat, dnorm)
+CClp *lp;
+int *cstat, *rstat;
+double *dnorm;
+#endif
+{
+    if (lp || cstat || rstat || dnorm) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_x (CClp *lp, double *x)
+#else
+int CClp_x (lp, x)
+CClp *lp;
+double *x;
+#endif
+{
+    if (lp || x) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_rc (CClp *lp, double *rc)
+#else
+int CClp_rc (lp, rc)
+CClp *lp;
+double *rc;
+#endif
+{
+    if (lp || rc) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_pi_range (CClp *lp, double *pi, int from, int to)
+#else
+int CClp_pi_range (lp, pi, from, to)
+CClp *lp;
+double *pi;
+int from, to;
+#endif
+{
+    if (lp || pi || from || to) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_objval (CClp *lp, double *obj)
+#else
+int CClp_objval (lp, obj)
+CClp *lp;
+double *obj;
+#endif
+{
+    if (lp || obj) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_nonzeros (CClp *lp)
+#else
+int CClp_nonzeros (lp)
+CClp *lp;
+#endif
+{
+    if (lp) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_status (CClp *lp, int *status)
+#else
+int CClp_status (lp, status)
+CClp *lp;
+int *status;
+#endif
+{
+    if (lp || status) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getweight (CClp *lp, int nrows, int *rmatbeg, int *rmatind,
+                    double *rmatval, double *weight)
+#else
+int CClp_getweight (lp, nrows, rmatbeg, rmatind, rmatval, weight)
+CClp *lp;
+int nrows;
+int *rmatbeg;
+int *rmatind;
+double *rmatval;
+double *weight;
+#endif
+{
+    if (lp || nrows || rmatbeg || rmatind || rmatval || weight) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_dump_lp (CClp *lp, char *fname)
+#else
+int CClp_dump_lp (lp, fname)
+CClp *lp;
+char *fname;
+#endif
+{
+    if (lp || fname ) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getgoodlist (CClp *lp, int *goodlist, int *goodlen_p,
+        double *downpen, double *uppen)
+#else
+int CClp_getgoodlist (lp, goodlist, goodlen_p, downpen, uppen)
+CClp *lp;
+int *goodlist;
+int *goodlen_p;
+double *downpen;
+double *uppen;
+#endif
+{
+    if (lp || goodlist || goodlen_p || downpen || uppen) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_strongbranch (CClp *lp, int *candidatelist, int ncand,
+        double *downpen, double *uppen, int iterations, double *upperbound)
+#else
+int CClp_strongbranch (lp, candidatelist, ncand, downpen, uppen, iterations,
+        upperbound)
+CClp *lp;
+int *candidatelist;
+int ncand;
+double *downpen;
+double *uppen;
+int iterations;
+double *upperbound;
+#endif
+{
+    if (lp || candidatelist || ncand || downpen || uppen || iterations
+           || upperbound) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CClp_getfarkasmultipliers (CClp *lp, double *y)
+#else
+int CClp_getfarkasmultipliers (lp, y)
+CClp *lp;
+double *y;
+#endif
+{
+    if (lp || y) {
+        lp_message (); return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CClp_pivotin (CClp *lp, int i)
+#else
+void CClp_pivotin (lp, i)
+CClp *lp;
+int i;
+#endif
+{
+    if (lp || i) lp_message ();
+}
diff --git a/contrib/blossom/concorde97/Makefile b/contrib/blossom/concorde97/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..ea06d1ee1c798d704f5221ce8311e01c0dbf34bc
--- /dev/null
+++ b/contrib/blossom/concorde97/Makefile
@@ -0,0 +1,29 @@
+SHELL=/bin/sh
+
+DIRS=BIGGUY CUT EDGEGEN FMATCH KDTREE LINKERN LP TSP UTIL XSTUFF
+
+.PHONY: top
+top: concorde.h concorde.a
+
+all: concorde.h concorde.a
+	for i in $(DIRS); do $(MAKE) -C $$i $@; done
+
+.PHONY: concorde.a
+concorde.a:
+	for i in $(DIRS); do $(MAKE) -C $$i concorde.a; done
+
+INC_LIST=INCLUDE/util.h     INCLUDE/bigguy.h   INCLUDE/lp.h       \
+         INCLUDE/kdtree.h   INCLUDE/cut.h      INCLUDE/edgegen.h  \
+         INCLUDE/tsp.h      INCLUDE/Xstuff.h   INCLUDE/fmatch.h   \
+         INCLUDE/linkern.h  INCLUDE/macrorus.h
+
+concorde.h: INCLUDE/prefix.h $(INC_LIST) Makefile
+	cat INCLUDE/prefix.h > concorde.h
+	cat $(INC_LIST) | grep -v '#include' >> concorde.h
+
+clean:
+	-rm -f *.o concorde.h concorde.a
+	for i in $(DIRS); do $(MAKE) -C $$i $@; done
+
+%:
+	for i in $(DIRS); do $(MAKE) -C $$i $@; done
diff --git a/contrib/blossom/concorde97/Makefile.conf b/contrib/blossom/concorde97/Makefile.conf
new file mode 100644
index 0000000000000000000000000000000000000000..c77a920327da3d5ec1e54531843c7d96899ad73e
--- /dev/null
+++ b/contrib/blossom/concorde97/Makefile.conf
@@ -0,0 +1,242 @@
+### This file contains some compilation configuration options.
+### The bottom half of this file contains several predefined configurations.
+### A predefined configuration can be selected by using using a definition
+### "SYS=sysname" at the top of this file, where sysname is the name used
+### in this file to describe the configuration.
+###
+### Or, you can create your own configuration by modifying the default values
+### after the comment "DEFAULT VALUES BEGIN HERE"
+###
+### Note that if you are using cplex, you will have to modify the cplex
+### variables even if you use a predefined configuration.
+###
+### The predefined systems are (the os and compiler versions given are the
+### ones on which the configuration has been tested):
+###
+### vendor/processor       o/s                compiler       configuration name
+### -------------------    --------           --------       ------------------
+### DEC Alpha              Digital Unix 4.0A  cc             ALPHA
+### DEC Alpha              Digital Unix 4.0a  gcc 2.7.2.1    ALPHA_GCC
+### DEC Alpha              Linux/Alpha 2.0.27 gcc            ALPHA_LINUX
+### Intel x86-compatible   Solaris/x86 2.5    gcc 2.7.2.1    INTEL_SOLARIS
+### Intel x86-compatible   Solaris/x86 2.5    cc 3.0.1       INTEL_SOLARIS_CC
+### *Intel x86-compatible  Linux/x86 1.2.13   gcc 2.7.2      INTEL_LINUX
+### **Intel x86-compatible FreeBSD            gcc            INTEL_BSD
+### IBM RS6000             AIX 4.2.1          cc             RS6000
+### IBM RS6000             AIX 4.2.1          gcc 2.7.2      RS6000_GCC
+### IBM RS6000             AIX 3.2.5          cc             RS6000
+### IBM RS6000             AIX 3.2.5          gcc 2.7.2      RS6000_GCC
+### Silicon Graphics       IRIX 5.3           cc             SILICON
+### Silicon Graphics       IRIX 5.3           gcc 2.7.2.2    SILICON_GCC
+### Sun UltraSparc         Solaris 2.5.1      gcc 2.7.2.1    SPARC
+### Sun UltraSparc         Solaris 2.5.1      cc 4.0,p42     SPARC_CC
+### *Sun Sparc             Solaris 2.5.1      gcc 2.7.2.1    SPARC
+### *Sun Sparc             Solaris 2.5.1      cc 4.2         SPARC_CC
+### *Sun Sparc             SunOS 4.1.3_U1     acc 3.0.1      SUNOS
+### *Sun Sparc             SunOS 4.1.3_U1     gcc 2.7.2      SUNOS_GCC
+### *Sun Sparc             SunOS 4.1.3_U1     cc             SUNOS_CC
+###
+
+### Uncomment and modify this line to specify a predefined configuration
+# SYS=SILICON
+
+### CC is the name of the C compiler
+CC=gcc -m32
+
+### OPTFLAGS are optimization flags to the compiler
+OPTFLAGS=-O
+
+### COMFLAGS are flags to be passed to the compiler, in addition to
+### the OPTFLAGS.  Flags which turn on additional warnings are recommended.
+COMFLAGS=
+
+### LOADFLAGS are flags to be passed to the linker, in addition to
+### the OPTFLAGS
+LOADFLAGS=
+
+### RANLIB is the name of a program which creates index information in
+### a library archive.  Some systems (for example, IRIX), don't require
+### ranlib.  In this case, set RANLIB=/bin/true.
+RANLIB=ranlib
+# RANLIB=/bin/true
+
+### OBJNAME is the extension used for the compiled files output by the
+### compiler and read by the linker.  It is almost always o.
+OBJNAME=o
+
+### CCSYSNAME is the name of the system in INCLUDE/config.h.
+### CCSYS_STANDARD is good on several systems with an ANSI C compiler,
+### and CCSYS_STANDARD_KNR is good on a few with an older, K&R C compiler.
+CCSYSNAME=CCSYS_STANDARD
+
+############################################################
+###
+### the following are only necessary if you are using CPLEX.
+###
+############################################################
+
+### CPLEX_LIB is the name (and location) of your cplex library
+# CPLEX_LIB=/usr/cplex/libcplex.a
+
+### CPLEX_INCLUDE_DIR is the location of your cplex.h
+# CPLEX_INCLUDE_DIR=/usr/cplex/
+
+##########################################################################
+###
+### PREDEFINED CONFIGURATIONS START HERE
+###
+##########################################################################
+
+### ALPHA: a DEC Alpha running Digital Unix with cc
+ifeq ($(SYS),ALPHA)
+OPTFLAGS=-tune host -O4
+COMFLAGS=-std1 -warnprotos -portable
+CC=cc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### ALPHA_GCC: a DEC Alpha running Digital Unix with gcc
+ifeq ($(SYS),ALPHA_GCC)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### ALPHA_LINUX: a DEC Alpha running Linux with gcc
+ifeq ($(SYS),ALPHA_LINUX)
+OPTFLAGS=-O3
+# -pedantic -Wtraditional -Wmissing-prototypes -Wmissing-declarations
+# generate many warnings for header files
+COMFLAGS=-ansi -Wall -Wshadow -W -W -Wstrict-prototypes -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### INTEL_BSD: an Intel x86-compatible running FreeBSD with gcc
+ifeq ($(SYS),INTEL_BSD)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### INTEL_LINUX: an Intel x86-compatible running Linux with gcc
+ifeq ($(SYS),INTEL_LINUX)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### INTEL_SOLARIS: an Intel x86-compatible running Solaris with gcc
+ifeq ($(SYS),INTEL_SOLARIS)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### INTEL_SOLARIS_CC: a SUN Sparc running Solaris with cc
+ifeq ($(SYS),INTEL_SOLARIS_CC)
+OPTFLAGS=-xO2
+COMFLAGS=-fd -v -Xc
+CC=cc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### RS6000: an IBM RS6000 running AIX with cc
+ifeq ($(SYS),RS6000)
+OPTFLAGS=-O
+CC=cc
+COMFLAGS=-D_POSIX_SOURCE -qlanglvl=ansi
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### RS6000_GCC: an IBM RS6000 running AIX with gcc
+ifeq ($(SYS),RS6000_GCC)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### SILICON: A Silicon Graphics running IRIX with cc
+ifeq ($(SYS),SILICON)
+OPTFLAGS=-O2
+COMFLAGS=-ansi -fullwarn
+CC=cc
+RANLIB=/bin/true
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### SILICON_GCC: A Silicon Graphics running IRIX with gcc
+ifeq ($(SYS),SILICON_GCC)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+RANLIB=/bin/true
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### SPARC: a SUN Sparc running Solaris with gcc
+ifeq ($(SYS),SPARC)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### SPARC_CC: a SUN Sparc running Solaris with cc
+ifeq ($(SYS),SPARC_CC)
+OPTFLAGS=-xO2
+COMFLAGS=-fd -v -Xc
+CC=cc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### SUNOS: A Sun Sparc running SunOS with acc
+ifeq ($(SYS),SUNOS)
+OPTFLAGS=-O2 -fast
+CC=/usr/lang/acc
+COMFLAGS=-Xc
+CCSYSNAME=CCSYS_STANDARD
+endif
+
+### SUNOS_CC: A Sun Sparc running SunOS with cc
+ifeq ($(SYS),SUNOS_CC)
+OPTFLAGS=-O2
+CC=cc
+CCSYSNAME=CCSYS_STANDARD_KNR
+endif
+
+### SUNOS_GCC: a SUN Sparc running SunOS with gcc
+ifeq ($(SYS),SUNOS_GCC)
+OPTFLAGS=-O3
+COMFLAGS=-ansi -pedantic -Wall -Wshadow -W -Wtraditional -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wnested-externs
+CC=gcc
+CCSYSNAME=CCSYS_SUNOS_GCC
+endif
+
+##########################################################################
+###
+### PREDEFINED CONFIGURATIONS END HERE
+###
+##########################################################################
+
+ifeq ($(CCSYSNAME),)
+CCSYSFLAG=-DCCSYS_UNKNOWN
+else
+CCSYSFLAG=-D$(CCSYSNAME)
+endif
+
+ifeq ($(CPLEX_INCLUDE_DIR),)
+CPLEX_INCFLAG=
+else
+CPLEX_INCFLAG=-I$(CPLEX_INCLUDE_DIR)
+endif
+
+CFLAGS=$(CCSYSFLAG) -I$(INCLUDE) $(CPLEX_INCFLAG) $(COMFLAGS) $(OPTFLAGS)
+LDFLAGS=$(OPTFLAGS) $(LOADFLAGS)
+
+o=$(OBJNAME)
diff --git a/contrib/blossom/concorde97/TSP/Makefile b/contrib/blossom/concorde97/TSP/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..557c732a81abc1b7fb715f1518a645b74cc6e6b7
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/Makefile
@@ -0,0 +1,91 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=tsp.a
+LIBSRCS=prob_io.c  tsp_lp.c   qsparse.c  cliqhash.c generate.c edgemap.c \
+        ex_price.c cutcall.c  tighten.c  cutpool.c  branch.c   control.c \
+        cliqwork.c teething.c bcontrol.c xtour.c
+ALLSRCS=concorde.c poolcat.c  $(LIBSRCS)
+LIBS=$(ROOT)/LINKERN/linkern.a $(ROOT)/EDGEGEN/edgegen.a \
+     $(ROOT)/KDTREE/kdtree.a   $(ROOT)/FMATCH/fmatch.a   \
+     $(ROOT)/XSTUFF/Xstuff.a   $(ROOT)/UTIL/util.a       \
+     $(ROOT)/BIGGUY/bigguy.a   $(ROOT)/CUT/cut.a         \
+     $(ROOT)/LP/lp.a
+
+all: concorde poolcat $(LIB)
+
+concorde: concorde.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ $(CPLEX_LIB) -lm
+
+poolcat: poolcat.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ $(CPLEX_LIB) -lm
+
+clean:
+	-rm -f *.$o $(LIB) concorde poolcat
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+bcontrol.$o: bcontrol.c $(I)/machdefs.h $(I)/util.h     $(I)/edgegen.h  \
+        $(I)/tsp.h      $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+branch.$o:   branch.c   $(I)/machdefs.h $(I)/util.h     $(I)/macrorus.h \
+        $(I)/tsp.h      $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       \
+        $(I)/cut.h      $(I)/kdtree.h   
+cliqhash.$o: cliqhash.c $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+cliqwork.$o: cliqwork.c $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+concorde.$o: concorde.c $(I)/machdefs.h $(I)/util.h     $(I)/edgegen.h  \
+        $(I)/tsp.h      $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   $(I)/linkern.h  $(I)/macrorus.h 
+control.$o:  control.c  $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   $(I)/Xstuff.h   
+cutcall.$o:  cutcall.c  $(I)/machdefs.h $(I)/macrorus.h $(I)/util.h     \
+        $(I)/tsp.h      $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       \
+        $(I)/cut.h      $(I)/kdtree.h   
+cutpool.$o:  cutpool.c  $(I)/machdefs.h $(I)/util.h     $(I)/macrorus.h \
+        $(I)/tsp.h      $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       \
+        $(I)/cut.h      $(I)/kdtree.h   
+edgemap.$o:  edgemap.c  $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   $(I)/macrorus.h 
+ex_price.$o: ex_price.c $(I)/machdefs.h $(I)/util.h     $(I)/macrorus.h \
+        $(I)/bigguy.h   $(I)/tsp.h      $(I)/edgegen.h  $(I)/lp.h       \
+        $(I)/cut.h      $(I)/kdtree.h   
+generate.$o: generate.c $(I)/machdefs.h $(I)/util.h     $(I)/macrorus.h \
+        $(I)/tsp.h      $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       \
+        $(I)/cut.h      $(I)/kdtree.h   
+poolcat.$o:  poolcat.c  $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+prob_io.$o:  prob_io.c  $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+qsparse.$o:  qsparse.c  $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+teething.$o: teething.c $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+tighten.$o:  tighten.c  $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   
+tsp_lp.$o:   tsp_lp.c   $(I)/machdefs.h $(I)/util.h     $(I)/macrorus.h \
+        $(I)/fmatch.h   $(I)/edgegen.h  $(I)/linkern.h  $(I)/tsp.h      \
+        $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      $(I)/kdtree.h   
+xtour.$o:    xtour.c    $(I)/machdefs.h $(I)/util.h     $(I)/edgegen.h  \
+        $(I)/linkern.h  $(I)/tsp.h      $(I)/bigguy.h   $(I)/lp.h       \
+        $(I)/cut.h      $(I)/kdtree.h   
diff --git a/contrib/blossom/concorde97/TSP/bcontrol.c b/contrib/blossom/concorde97/TSP/bcontrol.c
new file mode 100644
index 0000000000000000000000000000000000000000..6fce5b7edb878ba864fad713da07241a29190536
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/bcontrol.c
@@ -0,0 +1,713 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  THE CONTROLLER FOR BRANCHING RUNS                      */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: July 21, 1997                                                    */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_init_cutselect (CCtsp_lp *lp, CCtsp_cutselect *s)          */
+/*     INITIALIZES the cut selctions                                       */
+/*     Note: The lp should be solved before this call.                     */
+/*                                                                         */
+/*    int CCtsp_cutting_loop (CCtsp_lp *lp, CCtsp_cutselect *sel,          */
+/*            int savelp)                                                  */
+/*     CALLS the cutting plane and pricing routines.                       */
+/*      -sel should be set with the desired cut selection.                 */
+/*      -savelp should be set to a nonzero value to write the lps to after */
+/*       rounds of cuts                                                    */
+/*     Note: It returns a 2 if the lp becomes infeasible                   */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "edgegen.h"
+#include "tsp.h"
+
+typedef struct tsp_bbnode {
+    int id;
+    double lowerbound;
+    int status;
+    int workstatus;
+    struct tsp_bbnode *prev;
+    struct tsp_bbnode *next;
+    struct tsp_bbnode *parent;
+    struct tsp_bbnode *child0;
+    struct tsp_bbnode *child1;
+} tsp_bbnode;
+
+#define BB_NEEDS_CUTTING   (1)
+#define BB_NEEDS_BRANCHING (2)
+#define BB_DONE            (3)
+#define BB_IDLE            (1)
+#define BB_WORKING         (2)
+
+
+CC_PTR_ALLOC_ROUTINE (tsp_bbnode, tsp_bbnode_alloc, tsp_bbnode_chunklist,
+        tsp_bbnode_freelist)
+CC_PTR_FREE_WORLD_ROUTINE (tsp_bbnode, tsp_bbnode_free_world,
+        tsp_bbnode_chunklist, tsp_bbnode_freelist)
+CC_PTR_LEAKS_ROUTINE (tsp_bbnode, tsp_bbnode_check_leaks,
+        tsp_bbnode_chunklist, tsp_bbnode_freelist, id, int)
+CC_PTR_FREE_ROUTINE (tsp_bbnode, tsp_bbnode_free, tsp_bbnode_freelist)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    init_bbnode (tsp_bbnode *bbnode),
+    insert_bbnode (tsp_bbnode **firstbbnode, tsp_bbnode *bbnode),
+    delete_bbnode (tsp_bbnode **firstbbnode, tsp_bbnode *bbnode),
+    free_tree (tsp_bbnode **bbnode);
+
+static int
+    add_children (tsp_bbnode **firstbbnode, tsp_bbnode *parent,
+        int id0, int id1, double val0, double val1, int prune0, int prune1);
+
+static tsp_bbnode
+    *select_bbnode (tsp_bbnode *firstbbnode);
+
+#else
+
+static void
+    init_bbnode (),
+    insert_bbnode (),
+    delete_bbnode (),
+    free_tree ();
+
+static int
+    add_children ();
+
+static tsp_bbnode
+    *select_bbnode ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static void init_bbnode (tsp_bbnode *bbnode)
+#else
+static void init_bbnode (bbnode)
+tsp_bbnode *bbnode;
+#endif
+{
+    bbnode->id = 0;
+    bbnode->lowerbound = 0.0;
+    bbnode->status =     BB_NEEDS_CUTTING;
+    bbnode->workstatus = BB_IDLE;
+    bbnode->prev = (tsp_bbnode *) NULL;
+    bbnode->next = (tsp_bbnode *) NULL;
+    bbnode->parent = (tsp_bbnode *) NULL;
+    bbnode->child0 = (tsp_bbnode *) NULL;
+    bbnode->child1 = (tsp_bbnode *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_bfs_brancher (char *probname, int id, double lowerbound,
+        CCtsp_cutselect *sel, double *upbound, int *bbcount, int usecliques,
+        CCdatagroup *dat, int *ptour, CCtsp_lpcuts *pool, int ncount,
+        int *besttour)
+#else
+int CCtsp_bfs_brancher (probname, id, lowerbound, sel, upbound, bbcount,
+        usecliques, dat, ptour, pool, ncount, besttour)
+char *probname;
+int id;
+double lowerbound;
+CCtsp_cutselect *sel;
+double *upbound;
+int *bbcount;
+int usecliques;
+CCdatagroup *dat;
+int *ptour;
+CCtsp_lpcuts *pool;
+int ncount;
+int *besttour;
+#endif
+{
+    int rval = 0;
+    int  max_id = 0;
+    int id0, id1, prune, prune0, prune1, foundtour, count = 0;
+    double val0, val1, val;
+    CCtsp_branchobj *b = (CCtsp_branchobj *) NULL;
+    tsp_bbnode *bbnode = (tsp_bbnode *) NULL;
+    tsp_bbnode *firstbbnode = (tsp_bbnode *) NULL;
+    tsp_bbnode *rootbbnode  = (tsp_bbnode *) NULL;
+
+    *bbcount = 0;
+
+    if (max_id < id) max_id = id;
+    rootbbnode = tsp_bbnode_alloc ();
+    if (!rootbbnode) {
+        fprintf (stderr, "Failed to allocate root node\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    init_bbnode (rootbbnode);
+    rootbbnode->id = id;
+    rootbbnode->lowerbound = lowerbound;
+    firstbbnode = rootbbnode;
+    *bbcount = 1;
+
+    while (firstbbnode) {
+        bbnode = select_bbnode (firstbbnode);
+        if (!bbnode) {
+            fprintf (stderr, "No IDLE bbnodes\n");
+            rval = 1; goto CLEANUP;
+        }
+        printf ("Task %d: %s on node %d\n", count++,
+             (bbnode->status == BB_NEEDS_CUTTING ? "Cutting" : "Branching"),
+              bbnode->id);
+        fflush (stdout);
+
+        switch (bbnode->status) {
+        case BB_NEEDS_CUTTING:
+            bbnode->workstatus = BB_WORKING;
+            rval = CCtsp_bb_cutting (probname, bbnode->id, ncount, dat, ptour,
+                         upbound, pool, sel, &val, &prune, &foundtour,
+                         besttour);
+            if (rval) {
+                fprintf (stderr, "CCtsp_bb_cutting failed\n"); goto CLEANUP;
+            }
+            if (foundtour) {
+                printf ("TOUR FOUND - upperbound is %.2f\n", *upbound);
+                fflush (stdout);
+                rval = CCtsp_dumptour (ncount, dat, ptour, probname, besttour);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_dumptour failed\n"); goto CLEANUP;
+                }
+            }
+            if (prune) {
+                printf ("BBnode can be pruned: upperbound %.2f\n", *upbound);
+                fflush (stdout);
+                delete_bbnode (&firstbbnode, bbnode);
+                rval = CCtsp_prob_file_delete (probname, bbnode->id);
+                if (rval) goto CLEANUP;
+            } else {
+                bbnode->status     = BB_NEEDS_BRANCHING;
+                bbnode->workstatus = BB_IDLE;
+                bbnode->lowerbound = val;
+            }
+            break;
+        case BB_NEEDS_BRANCHING:
+            bbnode->workstatus = BB_WORKING;
+            rval = CCtsp_bb_find_branch (probname, bbnode->id, ncount, dat,
+                     ptour, upbound, pool, &b, usecliques, &foundtour,
+                     besttour);
+            if (rval) {
+                fprintf (stderr, "CCtsp_bb_find_branch failed\n"); goto CLEANUP;
+            }
+            if (foundtour) {
+                printf ("TOUR FOUND - upperbound is %.2f\n", *upbound);
+                fflush (stdout);
+                rval = CCtsp_dumptour (ncount, dat, ptour, probname, besttour);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_dumptour failed\n"); goto CLEANUP;
+                }
+            } else {
+                printf ("Found Branch - split problem into children\n");
+                fflush (stdout);
+                id0 = ++max_id;
+                id1 = ++max_id;
+                rval = CCtsp_bb_splitprob (probname, bbnode->id, ncount, dat,
+                         ptour, *upbound, pool, &b[0], id0, id1, &val0, &val1,
+                         &prune0, &prune1);
+                CCtsp_free_branchobj (&b[0]);
+                CC_IFFREE (b, CCtsp_branchobj);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_bb_splitprob failed\n");
+                    goto CLEANUP;
+                }
+
+                rval = add_children (&firstbbnode, bbnode, id0, id1,
+                           val0, val1, prune0, prune1);
+                if (rval) {
+                    fprintf (stderr, "add_children failed\n"); goto CLEANUP;
+                }
+                (*bbcount) += 2;
+            }
+            delete_bbnode (&firstbbnode, bbnode);
+            rval = CCtsp_prob_file_delete (probname, bbnode->id);
+            if (rval) goto CLEANUP;
+            break;
+        default:
+            printf ("Not working bbnode: %d (status %d)\n", bbnode->id,
+                                                            bbnode->status);
+            fflush (stdout);
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+CLEANUP:
+
+    CCtsp_free_branchobj (&b[0]);
+    CC_IFFREE (b, CCtsp_branchobj);
+    free_tree (&rootbbnode);
+    tsp_bbnode_free_world ();
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_children (tsp_bbnode **firstbbnode, tsp_bbnode *parent,
+        int id0, int id1, double val0, double val1, int prune0, int prune1)
+#else
+static int add_children (firstbbnode, parent, id0, id1, val0, val1,
+        prune0, prune1)
+tsp_bbnode **firstbbnode;
+tsp_bbnode *parent;
+int id0, id1;
+double val0, val1;
+int prune0, prune1;
+#endif
+{
+    int rval = 0;
+    tsp_bbnode *child = (tsp_bbnode *) NULL;
+
+    if (val0 == CCtsp_LP_MAXDOUBLE) {
+        printf ("Child 0 is infeasible\n"); fflush (stdout);
+    } else if (prune0) {
+        printf ("Child 0 is pruned\n"); fflush (stdout);
+    } else {
+        child = tsp_bbnode_alloc ();
+        if (!child) {
+            fprintf (stderr, "Failed to allocate child 0\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        init_bbnode (child);
+        child->id = id0;
+        child->lowerbound = val0;
+
+        parent->child0 = child;
+        insert_bbnode (firstbbnode, child);
+    }
+
+    if (val1 == CCtsp_LP_MAXDOUBLE) {
+        printf ("Child 1 is infeasible\n"); fflush (stdout);
+    } else if (prune1) {
+        printf ("Child 1 is pruned\n"); fflush (stdout);
+    } else {
+        child = tsp_bbnode_alloc ();
+        if (!child) {
+            fprintf (stderr, "Failed to allocate child 0\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        init_bbnode (child);
+        child->id = id1;
+        child->lowerbound = val1;
+
+        parent->child1 = child;
+        insert_bbnode (firstbbnode, child);
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_tree (tsp_bbnode **bbnode)
+#else
+static void free_tree (bbnode)
+tsp_bbnode **bbnode;
+#endif
+{
+    if (!(*bbnode))  return;
+    free_tree (&((*bbnode)->child0));
+    free_tree (&((*bbnode)->child1));
+    tsp_bbnode_free (*bbnode);
+    *bbnode = (tsp_bbnode *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static tsp_bbnode *select_bbnode (tsp_bbnode *firstbbnode)
+#else
+static tsp_bbnode *select_bbnode (firstbbnode)
+tsp_bbnode *firstbbnode;
+#endif
+{
+    double bestbound  = CCtsp_LP_MAXDOUBLE;
+    double lowerbound = CCtsp_LP_MAXDOUBLE;
+    tsp_bbnode *bestbbnode = (tsp_bbnode *) NULL;
+    tsp_bbnode *b;
+    int count = 0;
+
+    for (b = firstbbnode; b; b = b->next) {
+        if (b->lowerbound < lowerbound) {
+            lowerbound = b->lowerbound;
+        }
+        count++;
+    }
+    printf ("LOWER BOUND: %f   ACTIVE NODES: %d\n", lowerbound, count);
+    fflush (stdout);
+
+    if (firstbbnode) {
+        /* Find the best bbnode */
+        for (b = firstbbnode; b; b = b->next) {
+            if (b->workstatus == BB_IDLE && b->lowerbound < bestbound) {
+                bestbound = b->lowerbound;
+                bestbbnode = b;
+            }
+        }
+    }
+
+    if (!bestbbnode) {
+        printf ("No idle bbnodes\n"); fflush (stdout);
+    } else {
+
+
+        printf ("Selected bbnode:  id %d  lowerbound %.2f\n", 
+                bestbbnode->id, bestbound);
+        fflush (stdout);
+        if (count > 1) {
+            printf ("Remaining active bbnodes:\n");
+            fflush (stdout);
+            for (b = firstbbnode; b; b = b->next) {
+                if (b->id != bestbbnode->id) {
+                    printf ("  id %d  lowerbound %.2f\n", b->id, b->lowerbound);
+                    fflush (stdout);
+                }
+            }
+        }
+    }
+
+    return bestbbnode;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void insert_bbnode (tsp_bbnode **firstbbnode, tsp_bbnode *bbnode)
+#else
+static void insert_bbnode (firstbbnode, bbnode)
+tsp_bbnode **firstbbnode, *bbnode;
+#endif
+{
+    if (!bbnode) return;
+
+    bbnode->prev = (tsp_bbnode *) NULL;
+    bbnode->next = *firstbbnode;
+    if (*firstbbnode)  (*firstbbnode)->prev = bbnode;
+    *firstbbnode = bbnode;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void delete_bbnode (tsp_bbnode **firstbbnode, tsp_bbnode *bbnode)
+#else
+static void delete_bbnode (firstbbnode, bbnode)
+tsp_bbnode **firstbbnode;
+tsp_bbnode *bbnode;
+#endif
+{
+    tsp_bbnode *next, *prev;
+
+    if (!bbnode) return;
+
+    bbnode->status = BB_DONE;
+    bbnode->workstatus = BB_IDLE;
+    if (*firstbbnode == bbnode) {
+        *firstbbnode = bbnode->next;
+    }
+    prev = bbnode->prev;
+    next = bbnode->next;
+    if (prev) prev->next = next;
+    if (next) next->prev = prev;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_easy_dfs_brancher (CCtsp_lp *lp, CCtsp_cutselect *sel, int depth,
+        double *upbound, int *bbcount, int usecliques, int *besttour)
+#else
+int CCtsp_easy_dfs_brancher (lp, sel, depth, upbound, bbcount, usecliques,
+        besttour)
+CCtsp_lp *lp;
+CCtsp_cutselect *sel;
+int depth;
+double *upbound;
+int *bbcount;
+int usecliques;
+int *besttour;
+#endif
+{
+    int rval = 0;
+    int ngot, prune, i;
+    int *cyc = (int *) NULL;
+    double val, bnd;
+    double oldbound = lp->lowerbound;
+    CCtsp_branchobj *b = (CCtsp_branchobj *) NULL;
+
+    if (!lp->full_edges_valid) {
+        fprintf (stderr, "CCtsp_easy_dfs_brancher needs valid extra edges\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    printf ("Node %d\n", *bbcount); fflush (stdout);
+    (*bbcount)++;
+    CCtsp_print_branchhistory (lp);
+
+    rval = CCtsp_pricing_loop (lp, &bnd);
+    if (rval) {
+        fprintf (stderr, "CCtsp_pricing_loop failed\n");  goto CLEANUP;
+    }
+    lp->lowerbound = bnd;
+    lp->upperbound = *upbound;
+
+    if (lp->lowerbound >= lp->upperbound - 0.9) {
+        rval = CCtsp_verify_lp_prune (lp, &prune);
+        if (rval) {
+            fprintf (stderr, "CCtsp_verify_lp_prune failed\n"); goto CLEANUP;
+        }
+        if (prune) {
+            printf ("PRUNE SEARCH: upperbound = %f\n", *upbound);
+            fflush (stdout);
+            rval = 0; goto CLEANUP;
+        } else {
+            fprintf (stderr, "exact pricing could not prune the search\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_cutting_loop (lp, sel, 0);
+    if (rval == 2) {
+        rval = CCtsp_verify_infeasible_lp (lp, &prune);
+        if (rval) {
+            fprintf (stderr ,"CCtsp_verify_infeasible_lp failed\n");
+            goto CLEANUP;
+        }
+        if (prune) {
+            printf ("PRUNE SEARCH - infeasible LP\n"); fflush (stdout);
+            rval = 0; goto CLEANUP;
+        } else {
+            fprintf (stderr, "exact pricing did not verify an infeasible LP\n");
+            rval = 1; goto CLEANUP;
+        }
+    } else if (rval) {
+        fprintf (stderr, "CCtsp_cutting_loop failed\n"); goto CLEANUP;
+    }
+
+    if (lp->lowerbound < lp->upperbound - 0.9) {
+        rval = CCtsp_call_x_heuristic (lp, &val, besttour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_call_x_heuristic failed\n");
+            goto CLEANUP;
+        }
+        if (val < lp->upperbound) {
+            printf ("New upperbound from x-heuristic: %.2f\n", val);
+            lp->upperbound = val;
+            *upbound = val;
+            rval = CCtsp_dumptour (lp->graph.ncount, lp->dat, lp->perm,
+                                   lp->name, besttour);
+            if (rval) {
+                fprintf (stderr, "CCtsp_dumptour failed\n"); goto CLEANUP;
+            }
+        }
+    }
+
+    if (lp->lowerbound >= lp->upperbound - 0.9) {
+        rval = CCtsp_verify_lp_prune (lp, &prune);
+        if (rval) {
+            fprintf (stderr, "CCtsp_verify_lp_prune failed\n"); goto CLEANUP;
+        }
+        if (prune) {
+            printf ("PRUNE SEARCH: upperbound = %f\n", *upbound);
+            fflush (stdout);
+            rval = 0; goto CLEANUP;
+        } else {
+            fprintf (stderr, "exact pricing could not prune the search\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    oldbound = lp->lowerbound;
+    printf ("Find branch object ...\n"); fflush (stdout);
+    rval = CCtsp_find_branch (lp, 1, &ngot, &b, &val, &cyc, usecliques);
+    if (rval) {
+        fprintf (stderr, "CCtsp_find_branch failed\n");
+        goto CLEANUP;
+    }
+
+    if (ngot == 0) {
+        printf ("TOUR FOUND: %.2f\n", val); fflush (stdout);
+        if (val < *upbound) {
+            *upbound = val;
+            lp->upperbound = val;
+            for (i = 0; i < lp->graph.ncount; i++) {
+                besttour[i] = cyc[i];
+            }
+            rval = CCtsp_dumptour (lp->graph.ncount, lp->dat, lp->perm,
+                                   lp->name, besttour);
+            if (rval) {
+                fprintf (stderr, "CCtsp_dumptour failed\n"); goto CLEANUP;
+            }
+        }
+        CC_IFFREE (cyc, int);
+        rval = CCtsp_verify_lp_prune (lp, &prune);
+        if (rval) {
+            fprintf (stderr, "CCtsp_verify_lp_prune failed\n");
+            goto CLEANUP;
+        }
+        if (prune) {
+            printf ("with new tour, the node can be pruned\n"); fflush (stdout);
+            rval = 0; goto CLEANUP;
+        } else {
+            fprintf (stderr, "could not verify the pruning\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+
+    /**** Down-Side Branch ****/
+
+
+    if (b[0].ends[0] != -1) {
+        printf ("Branch: set edge (%d, %d) to 0 (depth %d)\n",
+                     b[0].ends[0], b[0].ends[1], depth);
+        b[0].rhs = 0;
+    } else {
+        printf ("Branch: set clique <= 2 (depth %d)\n", depth);
+        b[0].rhs = 2; b[0].sense = 'L';
+    }
+    fflush (stdout);
+    rval = CCtsp_execute_branch (lp, &b[0]);
+    if (rval) {
+        fprintf (stderr, "CCtsp_execute_branch failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_easy_dfs_brancher (lp, sel, depth + 1, upbound, bbcount,
+                                    usecliques, besttour);
+    if (rval) {
+        fprintf (stderr, "CCtsp_easy_dfs_brancher failed\n"); goto CLEANUP;
+    }
+    rval = CCtsp_execute_unbranch (lp, (CClpbasis *) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_execute_unbranch failed\n"); goto CLEANUP;
+    }
+    lp->lowerbound = oldbound;
+
+
+    /**** Up-Side Branch ****/
+
+
+    if (b[0].ends[0] != -1) {
+        printf ("Branch: set edge (%d, %d) to 1 (depth %d)\n",
+                     b[0].ends[0], b[0].ends[1], depth);
+        b[0].rhs = 1;
+    } else {
+        printf ("Branch: set clique >= 4 (depth %d)\n", depth);
+        b[0].rhs   = 4; b[0].sense = 'G';
+    }
+    fflush (stdout);
+    rval = CCtsp_execute_branch (lp, &b[0]);
+    if (rval) {
+        fprintf (stderr, "CCtsp_execute_branch failed\n"); goto CLEANUP;
+    }
+
+    rval = CCtsp_easy_dfs_brancher (lp, sel, depth + 1, upbound, bbcount,
+                                    usecliques, besttour);
+    if (rval) {
+        fprintf (stderr, "CCtsp_easy_dfs_brancher failed\n"); goto CLEANUP;
+    }
+    rval = CCtsp_execute_unbranch (lp, (CClpbasis *) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_execute_unbranch failed\n"); goto CLEANUP;
+    }
+    lp->lowerbound = oldbound;
+
+    CCtsp_free_branchobj (&b[0]);
+    CC_IFFREE (b, CCtsp_branchobj);
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_do_interactive_branch (CCtsp_lp *lp)
+#else
+int CCtsp_do_interactive_branch (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int bend0, bend1, ch0, ch1, tbran, nseg, i;
+    CCtsp_branchobj b;
+    CCtsp_lpclique *c = (CCtsp_lpclique *) NULL;
+    int *slist  = (int *) NULL;
+    int rval = 0;
+
+    CCtsp_init_branchobj (&b);
+
+    printf ("Enter the (integer) id's for the two child nodes: ");
+    fflush (stdout);
+    scanf ("%d %d", &ch0, &ch1);
+
+    printf ("Enter 0 if edge-branch and 1 if clique-branch: ");
+    fflush (stdout);
+    scanf ("%d", &tbran);
+
+    if (!tbran) {
+        printf ("Enter ends of branching edge (use neg if original): ");
+        fflush (stdout);
+        scanf ("%d %d", &bend0, &bend1);
+        if (bend0 < 0) {
+            if (bend1 >= 0) {
+                fprintf (stderr, "both ends must be from the same order\n");
+                rval = 1; goto CLEANUP;
+            }
+            for (i = 0; i < lp->graph.ncount; i++) {
+                if (lp->perm[i] == -bend0) bend0 = i;
+                if (lp->perm[i] == -bend1) bend1 = i;
+            }
+            printf ("Current Names of the Ends: %d %d\n", bend0, bend1);
+            fflush (stdout);
+        }
+        b.ends[0] = bend0;
+        b.ends[1] = bend1;
+        b.rhs     = 1;
+    } else {
+        printf ("Enter the number of segments in clique: ");
+        fflush (stdout);
+        scanf ("%d", &nseg);
+        slist = CC_SAFE_MALLOC (2*nseg, int);
+        if (!slist) {
+            fprintf (stderr, "out of memory\n");
+            rval = 1; goto CLEANUP;
+        }
+        printf ("Enter the ends of the segments: ");
+        fflush (stdout);
+        for (i = 0; i < nseg; i++) {
+            scanf ("%d %d", &slist[2*i], &slist[2*i+1]);
+        }
+        c = CC_SAFE_MALLOC (1, CCtsp_lpclique);
+        if (!c) {
+            fprintf (stderr, "out of memory\n");
+            CC_IFFREE (slist, int);
+            rval = 1; goto CLEANUP;
+        }
+        rval = CCtsp_seglist_to_lpclique (nseg, slist, c);
+        if (rval) {
+            fprintf (stderr, "CCtsp_seglist_to_lpclique failed\n");
+            goto CLEANUP;
+        }
+        CC_IFFREE (slist, int);
+        b.clique = c;
+        b.rhs    = 4;
+        b.sense  = 'G';
+        CCtsp_print_lpclique (b.clique);
+    }
+
+    rval = CCtsp_splitprob (lp, &b, ch0, ch1);
+    if (rval) {
+        fprintf (stderr, "CCtsp_splitprob failed\n");
+        goto CLEANUP;
+    }
+
+    CCtsp_free_branchobj (&b);
+
+CLEANUP:
+
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/TSP/branch.c b/contrib/blossom/concorde97/TSP/branch.c
new file mode 100644
index 0000000000000000000000000000000000000000..0942b0a6f1bece0abf0b167bcb405500a51bdb7f
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/branch.c
@@ -0,0 +1,2170 @@
+/***************************************************************************/
+/*                                                                         */
+/*               ROUTINES TO BUILD EXECUTE BRANCHING                       */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 22, 1997                                                     */
+/*  Modified: June 17, 1997 (bix)                                          */
+/*            June 27, 1997 (bico)                                         */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*                                                                         */
+/*     int CCtsp_find_branch (CCtsp_lp *lp, int nwant, int *ngot,          */
+/*             CCtsp_branchobj **bobj, double *val, int **tour,            */
+/*             int usecliques)                                             */
+/*      FINDS a set of branching edges and cliques.                        */
+/*       -usecliques should be set to 1 to allow branching on cliques      */
+/*       -val returns the length of a tour if one is detected.             */
+/*       -tour returns the tour (it can be NULL)                           */
+/*                                                                         */
+/*    int CCtsp_find_branch_edge (CCtsp_lp *lp, int *n0, int *n1,          */
+/*               double *val, int **tour, int branchtype)                  */
+/*     FINDS a branching edge or detects that solution is integral.        */
+/*      -lp points to an optimized lp.                                     */
+/*      -n0, n1 return the edges of the branching edge; n0 is set to -1    */
+/*           if the current lp solution is a tour                          */
+/*      -val returns the value the tour if n0 is set to -1                 */
+/*      -branchtype determines the strategy for choosing the branching     */
+/*           edge; choices for branchtype are given in tsp.h               */
+/*                                                                         */
+/*    int CCtsp_check_integral (CCtsp_lp *lp, double *val, int **cyc,      */
+/*                int *yesno)                                              */
+/*     TESTS if the current x-vector is a tour.                            */
+/*      -yesno is set to 1 if it is a tour and 0 otherwise.                */
+/*                                                                         */
+/*    int CCtsp_find_branch_cliques (CCtsp_lp *lp, int nwant, int *ngot,   */
+/*            CCtsp_lpclique **bcliques, double *bval)                     */
+/*     FINDS branching cliques (it may return ngot == 0)                   */
+/*     -bval will return the stongbranching function evaluation for        */
+/*      each clique (it can be NULL)                                       */
+/*                                                                         */
+/*    void CCtsp_init_branchobj (CCtsp_branchobj *b)                       */
+/*     INITITALIZES the fields in the CCtsp_branchobj pointed to by b.     */
+/*                                                                         */
+/*    void CCtsp_free_branchobj (CCtsp_branchobj *b)                       */
+/*     FREES the fields in the CCtsp_branchobj pointed to by b.            */
+/*                                                                         */
+/*    void CCtsp_print_branchhistory (CCtsp_lp *lp)                        */
+/*     PRINT to stdout the branch history of the lp                        */
+/*                                                                         */
+/*    int CCtsp_execute_branch (CCtsp_lp *lp, CCtsp_branchobj *b)          */
+/*     SETS the lp to realize the branch described in b                    */
+/*     NOTE: returns 2 if the LP becomes infeasible.                       */
+/*                                                                         */
+/*    int CCtsp_execute_unbranch (CCtsp_lp *lp, CClpbasis *basis)          */
+/*     UNDOS the changes to the lp caused by the most recent branch that   */
+/*      has not yet been unbranched (used in dfs)                          */
+/*      -basis can specify a basis and dual norms to help resolve the LP   */
+/*       (in can be NULL)                                                  */
+/*                                                                         */
+/*    int CCtsp_add_branchhistory_to_lp (CCtsp_lp *lp)                     */
+/*     SETS the lp to realize the branches in branch history               */
+/*                                                                         */
+/*    int CCtsp_splitprob (CCtsp_lp *lp, CCtsp_branchobj *b, int child0,   */
+/*            int child1)                                                  */
+/*     EXECUTES a branch on the lp and writes to two child lps             */
+/*      -b contains the branching information (the rhs side value is set   */
+/*       by this function to give 0 and 1 for edge branches and 2 & 4 for  */
+/*       clique branches; the sense is set by this function for clique     */
+/*       branches to realize <= 2 and >= 4)                                */
+/*      -child0 and child1 are the ids of the children                     */
+/*                                                                         */
+/*    int CCtsp_bb_splitprob (char *probname, int probnum, int ncount,     */
+/*            CCdatagroup *dat, int *ptour, double initial_ub,             */
+/*            CCtsp_lpcuts *pool, CCtsp_branchobj *b, int child0,          */
+/*            int child1, double *val0, double *val1, int *prune0,         */
+/*            int *prune1)                                                 */
+/*     CALLS splitprob after reading the lp file and building an lp; this  */
+/*      function will also price the lp and attempt to verify infeasible   */
+/*      lps.                                                               */
+/*      -val0 and val1 return the (priced) lp-bounds for the children; if  */
+/*       an lp is infeasible then the val is set to CCtsp_LP_MAXDOUBLE and */
+/*       the lp is not written.                                            */
+/*      -prune0 and prune1 will be set to 1 if the child can be pruned     */
+/*       (in which case the lp is not written)                             */
+/*                                                                         */
+/*    int CCtsp_dumptour (int ncount, CCdatagroup *dat, int *perm,         */
+/*            char *probname, int *tour)                                   */
+/*     WRITES the tour file to probname.sol.                               */
+/*      -dat is used to compute the length (it can be NULL)                */
+/*      -perm is a permutation tour                                        */
+/*      -tour gives the tour (perm[tour[i]] with be printed)               */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "macrorus.h"
+#include "tsp.h"
+#include "lp.h"
+#include "cut.h"
+
+
+#define TSP_BRANCH_STRONG_ALL_CHOICES -1
+#define TSP_BRANCH_STRONG_ITERATIONS  100
+#define TSP_BRANCH_STRONG_CHOICES     50  /* SET TO ALL_CHOICES TO TRY ALL */
+
+#define TSP_STRONG_CUT_ITER           100
+#define TSP_STRONG_CUT_CHOICES        50
+#define TSP_STRONG_CUT_CANDIDATES     1000
+
+#define TSP_BRANCH_STRONG_FIRST_VAL(v0,v1)                                 \
+    ((v0) < (v1) ? (10.0 * (v0) + (v1)) : (10.0 * (v1) + (v0)))
+
+#define TSP_BRANCH_STRONG_VAL(v0,v1)                                       \
+    ((v0) < (v1) ? (25.0 * (v0) + (v1)) : (25.0 * (v1) + (v0)))
+
+#define TSP_BRANCH_STRONG_CUT_NORM_VAL(v0,v1)                              \
+    ((v0) < (v1) ? (100.0 * (v0) + (v1)) : (100.0 * (v1) + (v0)))
+
+typedef struct sbitem {
+    int    name;
+    double val;
+} sbitem;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    merge_edge_clique (CCtsp_lp *lp, int nwant, int *ngot,
+            CCtsp_branchobj **bobj,
+            int ecount, int *elist, double *eval,
+            int ccount, CCtsp_lpclique *clist, double *cval),
+    find_strong_branch (CCtsp_lp *lp, int *n0, int *n1),
+    find_strongbranch_edges (CCtsp_lp *lp, int nwant, int *ngot, int **elist,
+            double **eval),
+    find_candidate_edges (CCtsp_lp *lp, int nwant, int *ngot, int **list),
+    find_all_candidate_edges (CCtsp_lp *lp, int *ngot, int **list),
+    find_candidate_cliques (CCtsp_lp *lp, int nwant, int *ngot,
+            CCtsp_lpclique **list, int use_getweight),
+    find_branched_clique (CCtsp_lp *lp, CCtsp_lpclique *c, char sense, int rhs,
+            int *cutnum),
+    branch_side (CCtsp_lp *lp, CCtsp_branchobj *b, int side, int child,
+            double *val, int *prune);
+
+static void
+    print_branchobj (CCtsp_branchobj *b),
+    init_sblist (sbitem *list, int count),
+    insert_sblist (sbitem *list, double val, int name);
+
+#else  /* CC_PROTOTYPE_ANSI */
+
+static int
+    merge_edge_clique (),
+    find_strong_branch (),
+    find_strongbranch_edges (),
+    find_candidate_edges (),
+    find_all_candidate_edges (),
+    find_candidate_cliques (),
+    find_branched_clique (),
+    branch_side ();
+
+static void
+    print_branchobj (),
+    init_sblist (),
+    insert_sblist ();
+
+#endif /* CC_PROTOTYPE_ANSI */
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_init_branchobj (CCtsp_branchobj *b)
+#else
+void CCtsp_init_branchobj (b)
+CCtsp_branchobj *b;
+#endif
+{
+    b->depth     = 0;
+    b->rhs       = 0;
+    b->ends[0]   = -1;
+    b->ends[1]   = -1;
+    b->sense     = 'X';
+    b->clique    = (CCtsp_lpclique *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_branchobj (CCtsp_branchobj *b)
+#else
+void CCtsp_free_branchobj (b)
+CCtsp_branchobj *b;
+#endif
+{
+    if (!b) return;
+
+    b->depth     = 0;
+    b->rhs       = 0;
+    b->ends[0]   = -1;
+    b->ends[1]   = -1;
+    b->sense     = 'X';
+    if (b->clique) {
+        CCtsp_free_lpclique (b->clique);
+        CC_FREE (b->clique, CCtsp_lpclique);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_print_branchhistory (CCtsp_lp *lp)
+#else
+void CCtsp_print_branchhistory (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int j;
+    printf ("Branch History\n"); fflush (stdout);
+    if (lp->branchdepth == 0) {
+        printf ("    Root Node\n");
+    } else {
+        for (j = 0; j < lp->branchdepth; j++) {
+            printf ("    ");
+            print_branchobj (&lp->branchhistory[j]);
+        }
+    }
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void print_branchobj (CCtsp_branchobj *b)
+#else
+static void print_branchobj (b)
+CCtsp_branchobj *b;
+#endif
+{
+    int i;
+
+    printf ("Depth %d:  ", b->depth);
+    if (b->ends[0] != -1) {
+        printf ("Edge (%d,%d) set to %d\n", b->ends[0], b->ends[1], b->rhs);
+    } else {
+        printf ("Clique ");
+        for (i = 0; i < b->clique->segcount; i++) {
+            printf ("%d->%d ", b->clique->nodes[i].lo, b->clique->nodes[i].hi);
+        }
+        if (b->sense == 'L') {
+            printf ("at most %d\n", b->rhs);
+        } else {
+            printf ("at least %d\n", b->rhs);
+        }
+    }
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_find_branch (CCtsp_lp *lp, int nwant, int *ngot,
+        CCtsp_branchobj **bobj, double *val, int **cyc, int usecliques)
+#else
+int CCtsp_find_branch (lp, nwant, ngot, bobj, val, cyc, usecliques)
+CCtsp_lp *lp;
+int nwant;
+int *ngot;
+CCtsp_branchobj **bobj;
+double *val;
+int **cyc;
+int usecliques;
+#endif
+{
+    int rval = 0;
+    int egot = 0;
+    int cgot = 0;
+    int      *elist = (int *) NULL;
+    CCtsp_lpclique *clist = (CCtsp_lpclique *) NULL;
+    double   *eval  = (double *) NULL;
+    double   *cval  = (double *) NULL;
+    int i, n0, n1;
+
+    *ngot = 0;
+    *bobj = (CCtsp_branchobj *) NULL;
+    if (cyc) *cyc = (int *) NULL;
+
+    if (nwant <= 0) {
+        fprintf (stderr, "CCtsp_find_branch called with no nwant\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_find_branch_edge (lp, &n0, &n1, val, cyc, CCtsp_BRANCH_MIDDLE);
+    if (rval) {
+        fprintf (stderr, "CCtsp_find_branch failed\n"); goto CLEANUP;
+    }
+
+    if (n0 == -1 && n1 == -1) {
+        printf ("Integral solution: %f\n", *val); fflush (stdout);
+        goto CLEANUP;
+    }
+
+    rval = find_strongbranch_edges (lp, nwant, &egot, &elist, &eval);
+    if (rval) {
+        fprintf (stderr, "find_strongbranch_edges failed\n"); goto CLEANUP;
+    }
+
+    if (usecliques) {
+        rval = CCtsp_find_branch_cliques (lp, nwant, &cgot, &clist, &cval);
+        if (rval) {
+            fprintf (stderr, "CCtsp_find_branch_cliques failed\n");
+            goto CLEANUP;
+        }
+        printf ("Cliques found:\n"); fflush (stdout);
+        for (i = 0; i < cgot; i++) {
+            CCtsp_print_lpclique (&clist[i]);
+        }
+    }
+
+    if (egot + cgot > 0) {
+        rval = merge_edge_clique (lp, nwant, ngot, bobj, egot, elist, eval,
+                                                         cgot, clist, cval);
+        if (rval) {
+            fprintf (stderr, "merge_edge_clique failed\n"); goto CLEANUP;
+        }
+    } else {
+        CCtsp_branchobj *b;
+        printf ("found no edges or cliques, use the middle branch edge\n");
+        fflush (stdout);
+
+        b = CC_SAFE_MALLOC (1, CCtsp_branchobj);
+        if (!b) {
+            fprintf (stderr, "out of memory in CCtsp_find_branch\n");
+            rval = 1; goto CLEANUP;
+        }
+        CCtsp_init_branchobj (b);
+        b->ends[0] = n0;
+        b->ends[1] = n1;
+        *bobj = b;
+        *ngot = 1;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (elist, int);
+    for (i = 0; i < cgot; i++) {
+        CCtsp_free_lpclique (&clist[i]);
+    }
+    CC_IFFREE (clist, CCtsp_lpclique);
+    CC_IFFREE (cval, double);
+    CC_IFFREE (eval, double);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int merge_edge_clique (CCtsp_lp *lp, int nwant, int *ngot,
+        CCtsp_branchobj **bobj, int ecount, int *elist, double *eval,
+        int ccount, CCtsp_lpclique *clist, double *cval)
+#else
+static int merge_edge_clique (lp, nwant, ngot, bobj, ecount, elist, eval,
+        ccount, clist, cval)
+CCtsp_lp *lp;
+int nwant;
+int *ngot;
+CCtsp_branchobj **bobj;
+int ecount;
+int *elist;
+double *eval;
+int ccount;
+CCtsp_lpclique *clist;
+double *cval;
+#endif
+{
+    int rval = 0;
+    int i, k;
+    sbitem *slist = (sbitem *) NULL;
+    CCtsp_branchobj *b;
+
+    *ngot = 0;
+    *bobj = (CCtsp_branchobj *) NULL;
+
+    if (ecount + ccount == 0) {
+        fprintf (stderr, "no elements in merge_edge_clique\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    slist = CC_SAFE_MALLOC (nwant + 1, sbitem);
+    if (!slist) {
+        fprintf (stderr, "out of memory in merge_edge_clique\n");
+        rval = 1; goto CLEANUP;
+    }
+    init_sblist (slist, nwant);
+
+    for (i = 0; i < ecount; i++) {
+        insert_sblist (slist, eval[i], i);
+    }
+    for (i = 0; i < ccount; i++) {
+        insert_sblist (slist, cval[i], i + ecount);
+    }
+
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            k++;
+        }
+    }
+    if (k == 0) {
+        fprintf (stderr, "nothing appeares in merge_edge_clique\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    *bobj = CC_SAFE_MALLOC (k, CCtsp_branchobj);
+    if (!(*bobj)) {
+        fprintf (stderr, "out of memory in merge_edge_clique\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            b = &((*bobj)[k]);
+            CCtsp_init_branchobj (b);
+            if (slist[i].name < ecount) {
+                b->ends[0] = lp->graph.edges[elist[slist[i].name]].ends[0];
+                b->ends[1] = lp->graph.edges[elist[slist[i].name]].ends[1];
+            } else {
+                b->clique = CC_SAFE_MALLOC (1, CCtsp_lpclique);
+                if (!b->clique) {
+                    fprintf (stderr, "out of memory in merge_edge_clique\n");
+                    rval = 1; goto CLEANUP;
+                } else {
+                    rval = CCtsp_copy_lpclique (&clist[slist[i].name - ecount],
+                                                b->clique);
+                }
+                if (!b->clique || rval) {
+                    fprintf (stderr, "CCtsp_copy_clique failed\n");
+                    for (i = 0; i < k; i++) {
+                        if ((*bobj)[i].clique) {
+                            CCtsp_free_lpclique ((*bobj)[i].clique);
+                            CC_IFFREE ((*bobj)[i].clique, CCtsp_lpclique);
+                        }
+                    }
+                    CC_IFFREE (b->clique, CCtsp_lpclique);
+                    CC_FREE (*bobj, CCtsp_branchobj);
+                    goto CLEANUP;
+                }
+            }
+            k++;
+        }
+    }
+    *ngot = k;
+
+CLEANUP:
+
+    CC_IFFREE (slist, sbitem);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_check_integral (CCtsp_lp *lp, double *val, int **cyc, int *yesno)
+#else
+int CCtsp_check_integral (lp, val, cyc, yesno)
+CCtsp_lp *lp;
+double *val;
+int **cyc;
+int *yesno;
+#endif
+{
+    int rval = 0;
+    double *x = (double *) NULL;
+    double eval = 0.0;
+    int *xlist = (int *) NULL;
+    int xcount;
+    int *comps = (int *) NULL;
+    int *compscount = (int *) NULL;
+    int ncomp;
+    int *elist = (int *) NULL;
+    int ncount = lp->graph.ncount;
+    int i, j, ecount;
+
+    *yesno = 0;
+    *val = 0.0;
+    if (cyc) *cyc = (int *) NULL;
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL, &xcount,
+                          &xlist, &x, (double **) NULL, (double **) NULL,
+                          (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n"); goto CLEANUP;
+    }
+
+    for (i = 0; i < xcount; i++) {
+        if (x[i] > 0.5) {
+            if (1.0 - x[i] > CCtsp_INTTOL) goto CLEANUP;
+        } else {
+            if (x[i] > CCtsp_INTTOL) goto CLEANUP;
+        }
+    }
+
+    elist = CC_SAFE_MALLOC (2*ncount, int);
+    if (!elist) {
+        fprintf (stderr, "out of memory in CCtsp_check_integral\n");
+    }
+    ecount = 0;
+
+    for (i = 0; i < xcount; i++) {
+        if (x[i] > CCtsp_INTTOL) {
+            j = CCtsp_find_edge (&lp->graph, xlist[2*i], xlist[2*i+1]);
+            if (j < 0) {
+                fprintf (stderr, "x edge not in graph\n");
+                rval = 1; goto CLEANUP;
+            }
+            eval += ((double) lp->graph.edges[j].len);
+            elist[2*ecount]   = lp->graph.edges[j].ends[0];
+            elist[2*ecount+1] = lp->graph.edges[j].ends[1];
+            ecount++;
+        }
+    }
+
+    rval = CCcut_connect_components (ncount, xcount, xlist, x,
+                                     &ncomp, &compscount, &comps);
+    if (rval) {
+        fprintf (stderr, "CCcut_connect_components failed\n"); goto CLEANUP;
+    }
+    if (ncomp > 1) {
+        printf ("integral solution not connected\n"); fflush (stdout);
+        goto CLEANUP;
+    }
+    printf ("Integral Solution of Value %.2f\n", *val); fflush (stdout);
+
+    if (cyc) {
+        *cyc = CC_SAFE_MALLOC (ncount, int);
+        if (!(*cyc)) {
+            fprintf (stderr, "out of memory in CCtsp_check_integral\n");
+            rval = 1; goto CLEANUP;
+        }
+        rval = CCutil_edge_to_cycle (ncount, elist, *cyc);
+        if (rval) {
+            fprintf (stderr, "CCutil_edge_to_cycle failed\n");
+            CC_FREE (*cyc, int);
+            goto CLEANUP;
+        }
+    }
+    *yesno = 1;
+    *val = eval;
+
+
+CLEANUP:
+
+    CC_IFFREE (x, double);
+    CC_IFFREE (xlist, int);
+    CC_IFFREE (comps, int);
+    CC_IFFREE (compscount, int);
+    CC_IFFREE (elist, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_find_branch_edge (CCtsp_lp *lp, int *n0, int *n1, double *val,
+        int **cyc, int branchtype)
+#else
+int CCtsp_find_branch_edge (lp, n0, n1, val, cyc, branchtype)
+CCtsp_lp *lp;
+int *n0, *n1;
+double *val;
+int **cyc;
+int branchtype;
+#endif
+{
+    int rval = 0;
+    double *x = (double *) NULL;
+    int *xlist = (int *) NULL;
+    int xcount;
+    double maxdiff = -1.0;
+    int i, test, besti = 0;
+
+    *n0 = -2;
+    *n1 = -2;
+    *val = 0.0;
+    if (cyc) *cyc = (int *) NULL;
+
+    rval = CCtsp_check_integral (lp, val, cyc, &test);
+    if (rval) {
+        fprintf (stderr, "CCtsp_check_integral failed\n");
+        goto CLEANUP;
+    }
+    if (test) {
+        printf ("Integral solution detected in CCtsp_find_branch_edge\n");
+        fflush (stdout);
+        *n0 = -1;
+        *n1 = -1;
+        goto CLEANUP;
+    }
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL, &xcount,
+                          &xlist, &x, (double **) NULL, (double **) NULL,
+                          (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n"); goto CLEANUP;
+    }
+
+    for (i = 0; i < xcount; i++) {
+        if (x[i] > 0.5) {
+            if (1.0 - x[i] > maxdiff) {
+                maxdiff = 1.0 - x[i];
+                besti = i;
+            }
+        } else {
+            if (x[i] > maxdiff) {
+                maxdiff = x[i];
+                besti = i;
+            }
+        }
+    }
+
+    switch (branchtype) {
+    case CCtsp_BRANCH_MIDDLE:
+        *n0 = xlist[2*besti];
+        *n1 = xlist[2*besti+1];
+        break;
+    case CCtsp_BRANCH_STRONG:
+        rval = find_strong_branch (lp, n0, n1);
+        if (rval) {
+            fprintf (stderr, "find_strong_branch failed\n");
+            goto CLEANUP;
+        }
+        if (*n0 == -1) {
+            *n0 = xlist[2*besti];
+            *n1 = xlist[2*besti+1];
+        }
+        break;
+    default:
+        fprintf (stderr, "unknown branchtype\n");
+        rval = 1; goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (x, double);
+    CC_IFFREE (xlist, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_strong_branch (CCtsp_lp *lp, int *n0, int *n1)
+#else
+static int find_strong_branch (lp, n0, n1)
+CCtsp_lp *lp;
+int *n0, *n1;
+#endif
+{
+    int rval = 0;
+    int *elist = (int *) NULL;
+    int ngot;
+
+    *n0 = -1;
+    *n1 = -1;
+
+    rval = find_strongbranch_edges (lp, 1, &ngot, &elist, (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "find_strongbranch_edges failed\n");
+        goto CLEANUP;
+    }
+
+    if (ngot == 0) {
+        printf ("WARNING: nothing came back from find_strongbranch_edges\n");
+        goto CLEANUP;
+    }
+
+    *n0 = lp->graph.edges[elist[0]].ends[0];
+    *n1 = lp->graph.edges[elist[0]].ends[1];
+
+    printf ("STRONG branch edge: %d %d\n", *n0, *n1);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (elist, int);
+    return rval;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_strongbranch_edges (CCtsp_lp *lp, int nwant, int *ngot,
+        int **elist, double **eval)
+#else
+static int find_strongbranch_edges (lp, nwant, ngot, elist, eval)
+CCtsp_lp *lp;
+int nwant;
+int *ngot;
+int **elist;
+double **eval;
+#endif
+{
+    int rval = 0;
+    int *candlist = (int *) NULL;
+    int ncand = 0;
+    int i, k;
+    double *downpen = (double *) NULL;
+    double *uppen   = (double *) NULL;
+    double sval;
+    double szeit;
+    sbitem *slist = (sbitem *) NULL;
+
+    *ngot = 0;
+    *elist = (int *) NULL;
+    if (eval) {
+        *eval = (double *) NULL;
+    }
+
+    rval = find_candidate_edges (lp, TSP_BRANCH_STRONG_CHOICES, &ncand,
+                             &candlist);
+    if (rval) {
+        fprintf (stderr, "find_candidate_edges failed\n");
+        goto CLEANUP;
+    }
+
+    if (ncand == 0) {
+        printf ("WARNING: find_candidate edges did not find anything\n");
+        goto CLEANUP;
+    }
+
+    printf ("Run strongbranch with %d candidate edges\n", ncand);
+    fflush (stdout);
+
+    downpen = CC_SAFE_MALLOC (ncand, double);
+    uppen   = CC_SAFE_MALLOC (ncand, double);
+    if (!downpen || !uppen) {
+        fprintf (stderr, "out of memory in find_strongbranch_edges\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    szeit = CCutil_zeit ();
+    rval = CClp_strongbranch (&lp->lp, candlist, ncand, downpen, uppen,
+                TSP_BRANCH_STRONG_ITERATIONS, &lp->upperbound);
+    if (rval) {
+        fprintf (stderr, "CClp_strongbranch failed\n"); goto CLEANUP;
+    }
+    printf ("Strongbranch used %.2f seconds\n", CCutil_zeit () - szeit);
+
+    slist = CC_SAFE_MALLOC (nwant + 1, sbitem);
+    if (!slist) {
+        fprintf (stderr, "out of memory in find_strongbranch_edges\n");
+        rval = 1; goto CLEANUP;
+    }
+    init_sblist (slist, nwant);
+
+    for (i = 0; i < ncand; i++) {
+        printf ("SB Edge (%d, %d):  %.4f  %.4f\n",
+                    lp->graph.edges[candlist[i]].ends[0],
+                    lp->graph.edges[candlist[i]].ends[1],
+                    downpen[i], uppen[i]);
+        fflush (stdout);
+        sval = TSP_BRANCH_STRONG_VAL (downpen[i], uppen[i]);
+        insert_sblist (slist, sval, candlist[i]);
+    }
+
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            k++;
+        }
+    }
+    if (k == 0) {
+        printf ("WARNING: no edges appeared in strongbranch\n");
+        goto CLEANUP;
+    }
+
+    *elist = CC_SAFE_MALLOC (k, int);
+    if (!(*elist)) {
+        fprintf (stderr, "out of memory in find_strongbranch_edges\n");
+        rval = 1; goto CLEANUP;
+    }
+    if (eval) {
+        *eval = CC_SAFE_MALLOC (k, double);
+        if (!(*eval)) {
+            fprintf (stderr, "out of memory in find_strongbranch_edges\n");
+            CC_IFFREE (*elist, int);
+            rval = 1; goto CLEANUP;
+        }
+    }
+    *ngot = k;
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            (*elist)[k] = slist[i].name;
+            if (eval) {
+                (*eval)[k] = slist[i].val;
+            }
+            k++;
+        }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (slist, sbitem);
+    CC_IFFREE (candlist, int);
+    CC_IFFREE (downpen, double);
+    CC_IFFREE (uppen, double);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_candidate_edges (CCtsp_lp *lp, int nwant, int *ngot, int **list)
+#else
+static int find_candidate_edges (lp, nwant, ngot, list)
+CCtsp_lp *lp;
+int nwant;
+int *ngot;
+int **list;
+#endif
+{
+    int *goodlist     = (int *) NULL;
+    double *downpen = (double *) NULL;
+    double *uppen   = (double *) NULL;
+    double sval;
+    int nrows, ngood;
+    int i, k;
+    sbitem *slist = (sbitem *) NULL;
+    int rval = 0;
+
+    *ngot = 0;
+    *list = (int *) NULL;
+
+    if (nwant == TSP_BRANCH_STRONG_ALL_CHOICES) {
+        rval = find_all_candidate_edges (lp, ngot, list);
+        if (rval) {
+            fprintf (stderr, "find_all_candidate_edges failed\n");
+            goto CLEANUP;
+        }
+        goto CLEANUP;
+    }
+
+    slist = CC_SAFE_MALLOC (nwant + 1, sbitem);
+    if (!slist) {
+        fprintf (stderr, "out of memory in find_strongbranch\n");
+        rval = 1; goto CLEANUP;
+    }
+    init_sblist (slist, nwant);
+
+    nrows     = lp->graph.ncount + lp->cuts.cutcount;
+    goodlist  = CC_SAFE_MALLOC (nrows, int);
+    downpen = CC_SAFE_MALLOC (nrows, double);
+    uppen   = CC_SAFE_MALLOC (nrows, double);
+    if (!goodlist || !downpen || !uppen) {
+        fprintf (stderr, "out of memory in find_strongbranch\n");
+        rval = 1; goto CLEANUP;
+    }
+    rval = CClp_getgoodlist (&lp->lp, goodlist, &ngood, downpen, uppen);
+    if (rval) {
+        fprintf (stderr, "CClp_getgoodlist failed\n"); goto CLEANUP;
+    }
+    printf ("Found %d good edges\n", ngood); fflush (stdout);
+
+    for (i = 0; i < ngood; i++) {
+        if (downpen[i] > lp->upperbound) downpen[i] = lp->upperbound;
+        if (uppen[i] > lp->upperbound) uppen[i] = lp->upperbound;
+        sval = TSP_BRANCH_STRONG_FIRST_VAL (downpen[i], uppen[i]);
+        insert_sblist (slist, sval, goodlist[i]);
+    }
+
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            k++;
+        }
+    }
+    if (k == 0) {
+        printf ("WARNING: CClp_getgoodlist returned no edges\n");
+        goto CLEANUP;
+    }
+
+    *list = CC_SAFE_MALLOC (k, int);
+    if (!(*list)) {
+        fprintf (stderr, "out of memory in find_candidate list\n");
+        rval = 1; goto CLEANUP;
+    }
+    *ngot = k;
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            (*list)[k++] = slist[i].name;
+        }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (goodlist, int);
+    CC_IFFREE (downpen, double);
+    CC_IFFREE (uppen, double);
+    CC_IFFREE (slist, sbitem);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_all_candidate_edges (CCtsp_lp *lp, int *ngot, int **list)
+#else
+static int find_all_candidate_edges (lp, ngot, list)
+CCtsp_lp *lp;
+int *ngot;
+int **list;
+#endif
+{
+    int rval = 0;
+    double *x  = (double *) NULL;
+    int *xlist = (int *) NULL;
+    int i, j, xcount, count;
+
+    *ngot = 0;
+    *list = (int *) NULL;
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL, &xcount,
+                          &xlist, &x, (double **) NULL, (double **) NULL,
+                          (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "get_lp_result failed\n"); goto CLEANUP;
+    }
+
+    count = 0;
+    for (i = 0; i < xcount; i++) {
+        if (x[i] >= CCtsp_INTTOL && x[i] <= 1.0 - CCtsp_INTTOL) {
+            count++;
+        }
+    }
+
+    if (!count) {
+        fprintf (stderr, "WARNING: The solution is integral\n");
+        goto CLEANUP;
+    }
+
+    *list = CC_SAFE_MALLOC (count, int);
+    if (!(*list)) {
+        fprintf (stderr, "out of memory in find_all_candidate_edges\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    count = 0;
+    for (i = 0; i < xcount; i++) {
+        if (x[i] >= CCtsp_INTTOL && x[i] <= 1.0 - CCtsp_INTTOL) {
+            j = CCtsp_find_edge (&lp->graph, xlist[2 * i], xlist[2 * i + 1]);
+            if (j < 0) {
+                fprintf (stderr, "edge not in lp in find_all_candiate_edges\n");
+                CC_IFFREE (*list, int);
+                rval = 1; goto CLEANUP;
+            }
+            (*list)[count++] = j;
+        }
+    }
+    *ngot = count;
+
+CLEANUP:
+
+    CC_IFFREE (x, double);
+    CC_IFFREE (xlist, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void init_sblist (sbitem *list, int count)
+#else
+static void init_sblist (list, count)
+sbitem *list;
+int count;
+#endif
+{
+    int i;
+
+    for (i = 0; i < count; i++) {
+        list[i].val  = -1.0;
+        list[i].name = -1;
+    }
+    list[count].val = CCtsp_LP_MAXDOUBLE;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void insert_sblist (sbitem *list, double val, int name)
+#else
+static void insert_sblist (list, val, name)
+sbitem *list;
+double val;
+int name;
+#endif
+{
+    int k;
+
+    if (list[0].val < val) {
+        for (k = 0; list[k+1].val < val; k++) {
+            list[k].name = list[k + 1].name;
+            list[k].val = list[k + 1].val;
+        }
+        list[k].val = val;
+        list[k].name = name;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_find_branch_cliques (CCtsp_lp *lp, int nwant, int *ngot,
+        CCtsp_lpclique **bcliques, double **bval)
+#else
+int CCtsp_find_branch_cliques (lp, nwant, ngot, bcliques, bval)
+CCtsp_lp *lp;
+int nwant;
+int *ngot;
+CCtsp_lpclique **bcliques;
+double **bval;
+#endif
+{
+    int      ccount   = 0;
+    CCtsp_lpclique *cliques = (CCtsp_lpclique *) NULL;
+    sbitem   *slist   = (sbitem *) NULL;
+    int i, k;
+    int rval = 0;
+    double up, down, sval, szeit;
+    double meanval = 0.0;
+
+    *ngot     = 0;
+    *bcliques = (CCtsp_lpclique *) NULL;
+    if (bval) {
+        *bval = (double *) NULL;
+    }
+
+    rval = find_candidate_cliques (lp, TSP_STRONG_CUT_CHOICES, &ccount,
+                                   &cliques, 1);
+    if (rval) {
+        fprintf (stderr, "find_candidate_cliques failed\n"); goto CLEANUP;
+    }
+    printf ("Found %d candidate cliques\n", ccount); fflush (stdout);
+
+    slist = CC_SAFE_MALLOC (nwant + 1, sbitem);
+    if (!slist) {
+        fprintf (stderr, "out of memory in find_strongbranch_edges\n");
+        rval = 1; goto CLEANUP;
+    }
+    init_sblist (slist, nwant);
+
+
+    for (i = 0; i < ccount; i++) {
+        szeit = CCutil_zeit ();
+        rval = CCtsp_test_cut_branch (lp, &cliques[i], &down, &up);
+        if (rval) {
+            fprintf (stderr, "CCtsp_test_cut_branch failed\n");
+            goto CLEANUP;
+        }
+        printf ("SB CLIQUE %d:  %f  %f  (%.2f seconds)\n",
+                   i, down, up, CCutil_zeit () - szeit);
+        fflush (stdout);
+        sval = TSP_BRANCH_STRONG_VAL (down, up);
+        insert_sblist (slist, sval, i);
+        meanval += sval;
+    }
+
+    if (ccount) {
+        printf ("Average Clique Value: %f\n", meanval / ((double) ccount));
+        fflush (stdout);
+    }
+
+    for (i = nwant - 1; i >= 0; i--) {
+        if (slist[i].name != -1) {
+            printf ("Top Clique: %d  (%f)\n", slist[i].name, slist[i].val);
+            fflush (stdout);
+            break;
+        }
+    }
+
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            k++;
+        }
+    }
+    if (k == 0) {
+        printf ("WARNING: no branching cliques were found\n");
+        goto CLEANUP;
+    }
+
+    *bcliques = CC_SAFE_MALLOC (k, CCtsp_lpclique);
+    if (!(*bcliques)) {
+        fprintf (stderr, "out of memory in CCtsp_find_branch_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+    if (bval) {
+        *bval = CC_SAFE_MALLOC (k, double);
+        if (!(*bval)) {
+            fprintf (stderr, "out of memory in CCtsp_find_branch_cliques\n");
+            CC_IFFREE (*bcliques, CCtsp_lpclique);
+            rval = 1; goto CLEANUP;
+        }
+    }
+    *ngot = k;
+    for (i = 0, k = 0; i < nwant; i++) {
+        if (slist[i].name != -1) {
+            rval = CCtsp_copy_lpclique (&cliques[slist[i].name],
+                                        &(*bcliques)[k]);
+            if (rval) {
+                fprintf (stderr, "CCtsp_copy_clique failed\n");
+                for (i = 0; i < k; i++) {
+                    CC_IFFREE ((*bcliques)[i].nodes, CCtsp_segment);
+                }
+                CC_FREE (*bcliques, CCtsp_lpclique);
+                goto CLEANUP;
+            }
+            if (bval) {
+                (*bval)[k] = slist[i].val;
+            }
+            k++;
+        }
+    }
+    *ngot = k;
+
+
+CLEANUP:
+
+    CC_IFFREE (slist, sbitem);
+    for (i = 0; i < ccount; i++) {
+        CC_IFFREE (cliques[i].nodes, CCtsp_segment);
+    }
+    CC_IFFREE (cliques, CCtsp_lpclique);
+
+    return 0;
+}
+
+#define TSP_STRONG_GETWEIGHT_BATCH 250
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_candidate_cliques (CCtsp_lp *lp, int nwant, int *ngot,
+        CCtsp_lpclique **list, int use_getweight)
+#else
+static int find_candidate_cliques (lp, nwant, ngot, list, use_getweight)
+CCtsp_lp *lp;
+int nwant;
+int *ngot;
+CCtsp_lpclique **list;
+int use_getweight;
+#endif
+{
+    int      xcount   = 0;
+    double   *x       = (double *) NULL;
+    int      *xlist   = (int *) NULL;
+    int      ccount   = 0;
+    double   *cval    = (double *) NULL;
+    CCtsp_lpclique *cliques = (CCtsp_lpclique *) NULL;
+    double   *weights = (double *) NULL;
+    sbitem   *slist   = (sbitem *) NULL;
+    CCtsp_lprow cr;
+    CCtsp_lpcut_in cu;
+    int i, k, j, batch, ntry, nzlist;
+    double down, up, t, sval;
+    int rval = 0;
+
+    CCtsp_init_lprow (&cr);
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL, &xcount,
+                     &xlist, &x, (double **) NULL, (double **) NULL,
+                     (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n"); goto CLEANUP;
+    }
+
+    ntry = (use_getweight ? TSP_STRONG_CUT_CANDIDATES : nwant);
+
+    rval = CCtsp_branch_cutpool_cliques (lp->pool, &cliques, &ccount,
+              lp->graph.ncount, xcount, xlist, x, ntry, &cval);
+    if (rval) {
+        fprintf (stderr, "CCtsp_branch_cutpool_cliques failed\n");
+        goto CLEANUP;
+    }
+    if (ccount == 0) {
+        fprintf (stderr, "WARNING: no cutpool cliques were found\n");
+        goto CLEANUP;
+    }
+
+    if (use_getweight) {
+        cu.handlecount = 0;
+        cu.cliquecount = 1;
+        cu.next = (CCtsp_lpcut_in *) NULL;
+        cu.prev = (CCtsp_lpcut_in *) NULL;
+        cu.rhs  = 2;
+
+        weights = CC_SAFE_MALLOC (TSP_STRONG_GETWEIGHT_BATCH, double);
+        if (!weights) {
+            fprintf (stderr, "out of memory in find_candidate_cliques\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        slist = CC_SAFE_MALLOC (nwant + 1, sbitem);
+        if (!slist) {
+            fprintf (stderr, "out of memory in find_strongbranch_edges\n");
+            rval = 1; goto CLEANUP;
+        }
+        init_sblist (slist, nwant);
+
+        for (i = 0, batch = 0; i < ccount; i++) {
+            cu.cliques = &(cliques[i]);
+            nzlist = CCtsp_lpcut_in_nzlist (&lp->graph, &cu);
+            rval = CCtsp_add_nzlist_to_lp (lp, nzlist, 2, 'G', &cr);
+            if (rval) {
+                fprintf (stderr, "CCtsp_add_nzlist_to_lp failed\n");
+                goto CLEANUP;
+            }
+            if ((i+1) % TSP_STRONG_GETWEIGHT_BATCH == 0 || i == ccount - 1) {
+                rval = CCutil_reallocrus_count ((void **) &(cr.begin),
+                                      cr.rowcnt + 1, sizeof (int));
+                if (rval) {
+                    fprintf (stderr, "out of memory\n");
+                    goto CLEANUP;
+                }
+                cr.begin[cr.rowcnt] = cr.nzcnt;
+                rval = CClp_getweight (&lp->lp, cr.rowcnt, cr.begin,
+                                       cr.indices, cr.entries, weights);
+                if (rval) {
+                    fprintf (stderr, "CClp_getweight failed\n"); goto CLEANUP;
+                }
+
+                for (j = 0; j < cr.rowcnt; j++) {
+                    t = cval[j] - 2.0;
+                    down = (t * t) /  weights[j];
+                    t = 4.0 - cval[j];
+                    up = (t * t) / weights[j];
+                    sval = TSP_BRANCH_STRONG_CUT_NORM_VAL (down, up);
+                    insert_sblist (slist, sval, batch+j);
+                }
+                CCtsp_free_lprow (&cr);
+                batch = i+1;
+            }
+        }
+
+        for (i = 0, k = 0; i < nwant; i++) {
+            if (slist[i].name != -1) {
+                k++;
+            }
+        }
+        if (k == 0) {
+            printf ("WARNING: no candidate branching cliques were found\n");
+            goto CLEANUP;
+        }
+
+        *list = CC_SAFE_MALLOC (k, CCtsp_lpclique);
+        if (!(*list)) {
+            fprintf (stderr, "out of memory in CCtsp_find_branch_cliques\n");
+            rval = 1; goto CLEANUP;
+        }
+        for (i = 0, k = 0; i < nwant; i++) {
+            if (slist[i].name != -1) {
+                rval = CCtsp_copy_lpclique (&cliques[slist[i].name],
+                                            &(*list)[k++]);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_copy_clique failed\n");
+                    for (i = 0; i < k; i++) {
+                        CC_IFFREE ((*list)[i].nodes, CCtsp_segment);
+                    }
+                    CC_FREE (*list, CCtsp_lpclique);
+                    goto CLEANUP;
+                }
+            }
+         }
+        *ngot = k;
+    } else {
+        *list = cliques;
+        *ngot = ccount;
+    }
+
+CLEANUP:
+
+    CCtsp_free_lprow (&cr);
+    CC_IFFREE (slist, sbitem);
+    CC_IFFREE (x, double);
+    CC_IFFREE (xlist, int);
+    CC_IFFREE (cval, double);
+    CC_IFFREE (weights, double);
+    if (use_getweight) {
+        for (i = 0; i < ccount; i++) {
+            CC_IFFREE (cliques[i].nodes, CCtsp_segment);
+        }
+        CC_IFFREE (cliques, CCtsp_lpclique);
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_test_cut_branch (CCtsp_lp *lp, CCtsp_lpclique *c, double *down,
+        double *up)
+#else
+int CCtsp_test_cut_branch (lp, c, down, up)
+CCtsp_lp *lp;
+CCtsp_lpclique *c;
+double *up, *down;
+#endif
+{
+    CCtsp_lprow cr;
+    CCtsp_lpcut_in cu;
+    int nzlist, status;
+    CClpbasis basis;
+    int rval = 0;
+
+    *down = -CCtsp_LP_MAXDOUBLE;
+    *up   = -CCtsp_LP_MAXDOUBLE;
+    CCtsp_init_lprow (&cr);
+
+    cu.handlecount = 0;
+    cu.cliquecount = 1;
+    cu.cliques = c;
+    cu.next = (CCtsp_lpcut_in *) NULL;
+    cu.prev = (CCtsp_lpcut_in *) NULL;
+    cu.rhs  = 2;
+
+    CClp_init_basis (&basis);
+    rval = CClp_get_basis_and_norms (&lp->lp, &basis);
+    if (rval) {
+        fprintf (stderr, "CClp_get_basis_and_norms failed\n"); goto CLEANUP;
+    }
+
+    nzlist = CCtsp_lpcut_in_nzlist (&lp->graph, &cu);
+    rval = CCtsp_add_nzlist_to_lp (lp, nzlist, 2, 'L', &cr);
+    if (rval) {
+        fprintf (stderr, "CCtsp_add_nzlist_to_lp failed\n"); goto CLEANUP;
+    }
+    rval = CCtsp_add_multiple_rows (lp, &cr);
+    if (rval) {
+        fprintf (stderr, "CCtsp_add_multiple_rows failed\n"); goto CLEANUP;
+    }
+    rval = CClp_limited_dualopt (&lp->lp, TSP_STRONG_CUT_ITER,
+                                 &status, &lp->upperbound);
+    if (rval) {
+        fprintf (stderr, "CClp_limited_dualopt failed\n"); goto CLEANUP;
+    }
+    if (status == CClp_INFEASIBLE) {
+        printf ("Down side of cut branch is infeasible\n"); fflush (stdout);
+        *down = lp->upperbound;
+    } else if (status == CClp_UNKNOWN) {
+        printf ("Down side information is not avaiable\n"); fflush (stdout);
+        *down = lp->lowerbound;
+    } else {
+        rval = CClp_objval (&lp->lp, down);
+        if (rval) {
+            fprintf (stderr, "CClp_objval failed\n"); goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_delete_cut (lp, lp->cuts.cutcount);
+    if (rval) {
+        fprintf (stderr, "CCtsp_delete_cut failed\n"); goto CLEANUP;
+    }
+    rval = CClp_load_basis_and_norms (&lp->lp, &basis);
+    if (rval) {
+        fprintf (stderr, "CClp_load_basis_and_norms failed\n"); goto CLEANUP;
+    }
+
+    cr.sense[0] = 'G';
+    cr.rhs[0] = 4.0;
+    rval = CCtsp_add_multiple_rows (lp, &cr);
+    if (rval) {
+        fprintf (stderr, "CCtsp_add_multiple_rows failed\n"); goto CLEANUP;
+    }
+    rval = CClp_limited_dualopt (&lp->lp, TSP_STRONG_CUT_ITER, &status,
+                                 &lp->upperbound);
+    if (rval) {
+        fprintf (stderr, "CClp_limited_dualopt failed\n"); goto CLEANUP;
+    }
+    if (status == CClp_INFEASIBLE) {
+        printf ("Up side of cut branch is infeasible\n"); fflush (stdout);
+        *up = lp->upperbound;
+    } else if (status == CClp_UNKNOWN) {
+        printf ("Up side information is not avaiable\n"); fflush (stdout);
+        *up = lp->lowerbound;
+    } else {
+        rval = CClp_objval (&lp->lp, up);
+        if (rval) {
+            fprintf (stderr, "CClp_objval failed\n"); goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_delete_cut (lp, lp->cuts.cutcount);
+    if (rval) {
+        fprintf (stderr, "CCtsp_delete_cut failed\n"); goto CLEANUP;
+    }
+    rval = CClp_load_basis_and_norms (&lp->lp, &basis);
+    if (rval) {
+        fprintf (stderr, "CClp_load_basis_and_norms failed\n"); goto CLEANUP;
+    }
+    rval = CClp_opt (&lp->lp, CClp_METHOD_DUAL);
+    if (rval) {
+        fprintf (stderr, "CClp_opt failed\n");
+    }
+
+CLEANUP:
+
+    CClp_free_basis (&basis);
+    CCtsp_free_lprow (&cr);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_execute_branch (CCtsp_lp *lp, CCtsp_branchobj *b)
+#else
+int CCtsp_execute_branch (lp, b)
+CCtsp_lp *lp;
+CCtsp_branchobj *b;
+#endif
+{
+    int n0      = -1;
+    int n1      = -1;
+    CCtsp_lpclique *c = (CCtsp_lpclique *) NULL;
+    int rval    = 0;
+    int i, j;
+
+    if (!b) {
+        fprintf (stderr, "CCtsp_execute_branch called without a CCtsp_branchobj\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    if (b->ends[0] != -1) {
+        n0 = b->ends[0];
+        n1 = b->ends[1];
+        printf ("Branch Edge (%d,%d), to value %d\n", n0, n1, b->rhs);
+        fflush (stdout);
+
+        if (n0 >= lp->graph.ncount || n0 < 0 ||
+            n1 >= lp->graph.ncount || n1 < 0) {
+            fprintf (stderr, "CCtsp_execute_branch has invalid nodes\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        if (n0 > n1) {
+            CC_SWAP (n0, n1, j);
+        }
+
+        j = CCtsp_find_edge (&lp->graph, n0, n1);
+        if  (j < 0) {
+            fprintf (stderr, "branching edge is not in the LP edgeset\n");
+            rval = 1; goto CLEANUP;
+        }
+        if (lp->graph.edges[j].fixed) {
+            fprintf (stderr, "branching edge is fixed to 1 in the LP\n");
+            rval = 1; goto CLEANUP;
+        }
+        if (lp->graph.edges[j].branch) {
+            fprintf (stderr, "branching edge has already been branched\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        if (b->rhs) {
+            rval = CClp_setbnd (&lp->lp, j, 'L', 1.0);
+            if (rval) {
+                fprintf (stderr, "CClp_setbnd failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            lp->graph.edges[j].branch = lp->branchdepth + 1;
+        } else {
+            rval = CClp_setbnd (&lp->lp, j, 'U', 0.0);
+            if (rval) {
+                fprintf (stderr, "CClp_setbnd failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            lp->graph.edges[j].branch = -(lp->branchdepth + 1);
+        }
+    } else {
+        CCtsp_lprow cr;
+        CCtsp_lpcut_in d;
+
+        if (!b->clique) {
+            fprintf (stderr, "CCtsp_branchobj has no edge or clique\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        printf ("Branch Clique "); fflush (stdout);
+        for (i = 0; i < b->clique->segcount; i++) {
+            printf ("%d->%d ", b->clique->nodes[i].lo, b->clique->nodes[i].hi);
+            fflush (stdout);
+        }
+        if (b->sense == 'G') {
+            printf ("to at least %d\n", b->rhs);
+        } else {
+            printf ("to at most %d\n", b->rhs);
+        }
+        fflush (stdout);
+
+        c = CC_SAFE_MALLOC (1, CCtsp_lpclique);
+        if (!c) {
+            fprintf (stderr, "out of memory in CCtsp_execute_branch\n");
+            rval = 1; goto CLEANUP;
+        }
+        rval = CCtsp_copy_lpclique (b->clique, c);
+        if (rval) {
+            fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        CCtsp_init_lpcut_in (&d);
+        d.handlecount = 0;
+        d.cliquecount = 1;
+        d.rhs = b->rhs;
+        d.sense = b->sense;
+        d.branch = 1;
+        d.cliques = c;
+
+        CCtsp_init_lprow (&cr);
+        rval = CCtsp_add_cut (lp, &d, &cr);
+        if (rval) {
+            fprintf (stderr, "CCtsp_add_cut failed\n");
+            rval = 1; goto CLEANUP;
+        }
+        rval = CCtsp_add_multiple_rows (lp, &cr);
+        if (rval) {
+            fprintf (stderr, "CCtsp_add_multiple_rows failed\n");
+            rval = 1; goto CLEANUP;
+        }
+        CCtsp_free_lprow (&cr);
+        CCtsp_free_lpcut_in (&d);
+    }
+
+    rval = CClp_dualopt (&lp->lp);
+    if (rval == 2) {
+        rval = CCtsp_infeas_recover (lp);
+        if (rval == 2) {
+            printf ("Problem is really infeasible (CCtsp_execute_branch)\n");
+            goto CLEANUP;
+        } else if (rval) {
+            fprintf (stderr, "CCtsp_infeas_recover failed\n");
+            rval = 1; goto CLEANUP;
+        }
+    } else if (rval) {
+        fprintf (stderr, "CClp_dualopt failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_update_result (lp);
+    if (rval) {
+        fprintf (stderr, "CCtsp_update_result failed\n");
+        rval = 1; goto CLEANUP;
+    }
+    CCtsp_free_bigdual (&lp->exact_dual);
+
+CLEANUP:
+
+    if (rval == 0 || rval == 2) {
+        int sval = 0;
+        sval = CCutil_reallocrus_count ((void **) &(lp->branchhistory),
+                   lp->branchdepth + 1, sizeof (CCtsp_branchobj));
+        if (sval) {
+            fprintf (stderr, "CCutil_reallocrus_count failed\n"); return 1;
+        }
+        CCtsp_init_branchobj (&lp->branchhistory[lp->branchdepth]);
+        lp->branchhistory[lp->branchdepth].depth   = lp->branchdepth + 1;
+        lp->branchhistory[lp->branchdepth].ends[0] = n0;
+        lp->branchhistory[lp->branchdepth].ends[1] = n1;
+        lp->branchhistory[lp->branchdepth].rhs     = b->rhs;
+        if (b->clique) {
+            c = CC_SAFE_MALLOC (1, CCtsp_lpclique);
+            if (!c) {
+                fprintf (stderr, "out of memory in CCtsp_execute_branch\n");
+                return 1;
+            }
+            sval = CCtsp_copy_lpclique (b->clique, c);
+            if (sval) {
+                fprintf (stderr, "CCtsp_copy_lpclique failed\n"); return 1;
+            }
+            lp->branchhistory[lp->branchdepth].clique = c;
+        } else {
+            lp->branchhistory[lp->branchdepth].clique = (CCtsp_lpclique *) NULL;
+        }
+        lp->branchhistory[lp->branchdepth].sense = b->sense;
+        lp->branchdepth++;
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_execute_unbranch (CCtsp_lp *lp, CClpbasis *basis)
+#else
+int CCtsp_execute_unbranch (lp, basis)
+CCtsp_lp *lp;
+CClpbasis *basis;
+#endif
+{
+    int rval = 0;
+    int n0, n1;
+    int num;
+    int depth = lp->branchdepth;
+    CCtsp_branchobj *b;
+    int j;
+
+    if (depth <= 0) {
+        fprintf (stderr, "CCtsp_execute_unbranch called at depth 0\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    if (lp->branchhistory[depth - 1].depth != depth) {
+        fprintf (stderr, "branchhistory is corrupted\n");
+        rval = 1; goto CLEANUP;
+    }
+    b = &lp->branchhistory[depth - 1];
+
+    if (lp->branchhistory[depth - 1].ends[0] != -1) {
+        n0    = b->ends[0];
+        n1    = b->ends[1];
+        printf ("Unbranch Edge (%d,%d), from value %d\n", n0, n1, b->rhs);
+        fflush (stdout);
+
+        if (n0 > n1) {
+            CC_SWAP (n0, n1, j);
+        }
+
+        j = CCtsp_find_edge (&lp->graph, n0, n1);
+        if  (j < 0) {
+            fprintf (stderr, "ERROR: unbranching 1-edge is not in LP\n");
+            rval = 1; goto CLEANUP;
+        }
+        if (b->rhs) {
+            if (lp->graph.edges[j].branch <= 0) {
+                fprintf (stderr, "unbranching 1-edge not branched to 1\n");
+                rval = 1; goto CLEANUP;
+            }
+            rval = CClp_setbnd (&lp->lp, j, 'L', 0.0);
+            if (rval) {
+                fprintf (stderr, "CClp_setbnd failed\n"); goto CLEANUP;
+            }
+        } else {
+            if (lp->graph.edges[j].branch >= 0) {
+                fprintf (stderr, "unbranching 0-edge not branched to 0\n");
+                rval = 1; goto CLEANUP;
+            }
+
+            rval = CClp_setbnd (&lp->lp, j, 'U', 1.0);
+            if (rval) {
+                fprintf (stderr, "CClp_setbnd failed\n"); goto CLEANUP;
+            }
+        }
+        lp->graph.edges[j].branch = 0;
+    } else {
+        if (!b->clique) {
+            fprintf (stderr, "branchhistory has no edge or clique\n");
+            rval = 1; goto CLEANUP;
+        }
+        rval = find_branched_clique (lp, b->clique, b->sense, b->rhs, &num);
+        if (rval) {
+            fprintf (stderr, "find_branched_clique failed\n");
+            goto CLEANUP;
+        }
+        printf ("The unbranching clique is cut %d\n", num); fflush (stdout);
+        if (lp->cuts.cuts[num].branch == 0) {
+            fprintf (stderr, "the unbranching clique is not set to branch\n");
+            rval = 1; goto CLEANUP;
+        }
+
+        {
+            int q;
+            CCtsp_lpcut *cu = &lp->cuts.cuts[num];
+            CCtsp_lpclique *t;
+
+            printf ("Sense: %c  RHS: %d  Cliques: %d  Branch: %d\n",
+                 cu->sense, cu->rhs, cu->cliquecount, cu->branch);
+            t = &lp->cuts.cliques[cu->cliques[0]];
+            printf ("Clique: ");
+            for (q = 0; q < t->segcount; q++) {
+                printf ("%d->%d ", t->nodes[q].lo, t->nodes[q].hi);
+            }
+            printf ("\n"); fflush (stdout);
+        }
+
+        if (!basis) {
+            CClp_pivotin (&lp->lp, lp->graph.ncount + num);
+        }
+        rval = CCtsp_delete_cut (lp, num);
+        if (rval) {
+            fprintf (stderr, "CCtsp_delete_cut failed\n"); goto CLEANUP;
+        }
+        CCtsp_delete_cut_from_cutlist (&lp->cuts, num);
+    }
+
+    if (basis) {
+        rval = CClp_load_basis_and_norms (&lp->lp, basis);
+        if (rval) {
+            fprintf (stderr, "CClp_load_basis_and_norms failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    rval = CClp_dualopt (&lp->lp);
+    if (rval == 2) {
+        fprintf (stderr, "infeasible lp in CCtsp_execute_unbranch\n");
+        goto CLEANUP;
+    } else if (rval) {
+        fprintf (stderr, "CClp_dualopt failed\n"); goto CLEANUP;
+    }
+
+    rval = CCtsp_update_result (lp);
+    if (rval) {
+        fprintf (stderr, "CCtsp_update_result failed\n"); goto CLEANUP;
+    }
+    CCtsp_free_bigdual (&lp->exact_dual);
+
+CLEANUP:
+
+    if (!rval) {
+        CCtsp_free_branchobj (&lp->branchhistory[lp->branchdepth - 1]);
+        lp->branchdepth--;
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_branchhistory_to_lp (CCtsp_lp *lp)
+#else
+int CCtsp_add_branchhistory_to_lp (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int i, k, num;
+    int rval = 0;
+    CCtsp_branchobj *b;
+
+    for (i = 0; i < lp->branchdepth; i++) {
+        b = &lp->branchhistory[i];
+        if (b->ends[0] != -1) {
+            k = CCtsp_find_edge (&lp->graph, b->ends[0], b->ends[1]);
+            if (k == -1) {
+                fprintf (stderr, "edge in branch history is not in LP\n");
+                rval = 1; goto CLEANUP;
+            }
+            if (lp->graph.edges[k].fixed || lp->graph.edges[k].branch) {
+                fprintf (stderr, "edge in branch history is fixed/branched\n");
+                rval = 1; goto CLEANUP;
+            }
+            if (b->rhs) {
+                rval = CClp_setbnd (&lp->lp, k, 'L', 1.0);
+                if (rval) {
+                    fprintf (stderr, "CClp_setbnd failed\n"); goto CLEANUP;
+                }
+                lp->graph.edges[k].branch = b->depth;
+            } else {
+                rval = CClp_setbnd (&lp->lp, k, 'U', 0.0);
+                if (rval) {
+                    fprintf (stderr, "CClp_setbnd failed\n"); goto CLEANUP;
+                }
+                lp->graph.edges[k].branch = -(b->depth);
+            }
+        } else {
+            rval = find_branched_clique (lp, b->clique, b->sense,
+                                             b->rhs, &num);
+            if (rval) {
+                fprintf (stderr, "find_branch_clique failed\n");
+                goto CLEANUP;
+            }
+            lp->cuts.cuts[num].branch = 1;
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_branched_clique (CCtsp_lp *lp, CCtsp_lpclique *c, char sense,
+        int rhs, int *cutnum)
+#else
+static int find_branched_clique (lp, c, sense, rhs, cutnum)
+CCtsp_lp *lp;
+CCtsp_lpclique *c;
+char sense;
+int rhs;
+int *cutnum;
+#endif
+{
+    int i;
+    CCtsp_lpcut *cu;
+    CCtsp_lpcut *cuts       = lp->cuts.cuts;
+    CCtsp_lpclique *cliques = lp->cuts.cliques;
+    int cutcount      = lp->cuts.cutcount;
+    int diff = 0;
+
+    *cutnum = -1;
+
+    for (i = 0; i < cutcount; i++) {
+        cu = &cuts[i];
+        if (cu->cliquecount == 1 &&
+            cu->sense == sense && cu->rhs == rhs) {
+            CCtsp_lpclique_compare (&cliques[cu->cliques[0]], c, &diff);
+            if (!diff) {
+                *cutnum = i; return 0;
+            }
+        }
+    }
+
+    fprintf (stderr, "did not find branched clique\n");
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_bb_find_branch (char *probname, int probnum, int ncount,
+         CCdatagroup *dat, int *ptour, double *upperbound, CCtsp_lpcuts *pool,
+         CCtsp_branchobj **b, int usecliques, int *foundtour, int *besttour)
+#else
+int CCtsp_bb_find_branch (probname, probnum, ncount, dat, ptour, upperbound,
+         pool, b, usecliques, foundtour, besttour)
+char *probname;
+int probnum;
+int ncount;
+CCdatagroup *dat;
+int *ptour;
+double *upperbound;
+CCtsp_lpcuts *pool;
+CCtsp_branchobj **b;
+int usecliques;
+int *foundtour;
+int *besttour;
+#endif
+{
+    int rval = 0;
+    double tval;
+    CCtsp_lp *lp = (CCtsp_lp *) NULL;
+    int *cyc = (int *) NULL;
+    int i, ngot, test;
+
+    *foundtour = 0;
+    *b = (CCtsp_branchobj *) NULL;
+
+    rval = CCtsp_bb_init_lp (&lp, probname, probnum, ncount, dat, ptour,
+               *upperbound, pool);
+    if (rval) {
+        fprintf (stderr, "CCtsp_bb_init_lp failed\n"); goto CLEANUP;
+    }
+
+    rval = CCtsp_find_branch (lp, 1, &ngot, b, &tval, &cyc, usecliques);
+    if (rval) {
+        fprintf (stderr, "CCtsp_find_branch failed\n");
+        goto CLEANUP;
+    }
+
+    if (ngot == 0) {
+        printf ("No branch, found tour of value %.2f\n", tval);
+        fflush (stdout);
+        if (tval < lp->upperbound) lp->upperbound = tval;
+        rval = CCtsp_verify_lp_prune (lp, &test);
+        if (rval) {
+            fprintf (stderr, "CCtsp_verify_lp_prune failed\n");
+            goto CLEANUP;
+        }
+        if (test) {
+            printf ("verified that LP can now be pruned\n"); fflush (stdout);
+            *foundtour = 1;
+            if (tval < *upperbound) {
+                *upperbound = tval;
+                if (besttour) {
+                    for (i = 0; i < ncount; i++) {
+                        besttour[i] = cyc[i];
+                    }
+                }
+            }
+            goto CLEANUP;
+        } else {
+            fprintf (stderr, "new tour did not permit exact pruning\n");
+            rval = 1; goto CLEANUP;
+        }
+    } else {
+        printf ("found branch\n"); fflush (stdout);
+    }
+
+
+CLEANUP:
+
+    if (lp) CCtsp_free_tsp_lp_struct (&lp);
+    CC_IFFREE (cyc, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_bb_splitprob (char *probname, int probnum, int ncount,
+         CCdatagroup *dat, int *ptour, double initial_ub, CCtsp_lpcuts *pool,
+         CCtsp_branchobj *b, int child0, int child1, double *val0, double *val1,
+         int *prune0, int *prune1)
+#else
+int CCtsp_bb_splitprob (probname, probnum, ncount, dat, ptour, initial_ub,
+         pool, b, child0, child1, val0, val1, prune0, prune1)
+char *probname;
+int probnum;
+int ncount;
+CCdatagroup *dat;
+int *ptour;
+double initial_ub;
+CCtsp_lpcuts *pool;
+CCtsp_branchobj *b;
+int child0, child1;
+double *val0, *val1;
+int *prune0, *prune1;
+#endif
+{
+    int rval = 0;
+    CCtsp_lp *lp = (CCtsp_lp *) NULL;
+
+    *val0 = 0.0;
+    *val1 = 0.0;
+    *prune0 = 0;
+    *prune1 = 0;
+
+    rval = CCtsp_bb_init_lp (&lp, probname, probnum, ncount, dat, ptour,
+               initial_ub, pool);
+    if (rval) {
+        fprintf (stderr, "CCtsp_bb_init_lp failed\n"); goto CLEANUP;
+    }
+
+    rval = branch_side (lp, b, 0, child0, val0, prune0);
+    if (rval) {
+        fprintf (stderr, "branch_side failed\n"); goto CLEANUP;
+    }
+
+    CCtsp_free_tsp_lp_struct (&lp);
+    rval = CCtsp_bb_init_lp (&lp, probname, probnum, ncount, dat, ptour,
+               initial_ub, pool);
+    if (rval) {
+        fprintf (stderr, "CCtsp_bb_init_lp failed\n"); goto CLEANUP;
+    }
+
+    rval = branch_side (lp, b, 1, child1, val1, prune1);
+    if (rval) {
+        fprintf (stderr, "branch_side failed\n"); goto CLEANUP;
+    }
+
+
+CLEANUP:
+
+    if (lp) CCtsp_free_tsp_lp_struct (&lp);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int branch_side (CCtsp_lp *lp, CCtsp_branchobj *b, int side, int child,
+        double *val, int *prune)
+#else
+static int branch_side (lp, b, side, child, val, prune)
+CCtsp_lp *lp;
+CCtsp_branchobj *b;
+int side;
+int child;
+double *val;
+int *prune;
+#endif
+{
+    int rval = 0;
+    int oldid       =  lp->id;
+    int oldparent   =  lp->parent_id;
+    double oldbound = lp->lowerbound;
+    double newbound;
+    int test;
+
+    *val = 0.0;
+    *prune = 0;
+
+    if (b->ends[0] != -1) {
+        printf ("Creating child %d of LP %d: Set Edge (%d, %d) to %d\n",
+                         side, lp->id, b->ends[0], b->ends[1], side);
+        if (side == 0) {
+            b->rhs = 0;
+        } else {
+            b->rhs = 1;
+        }
+    } else {
+        if (side == 0) {
+            printf ("Creating child 0 of LP %d: Set Clique <= 2\n", lp->id);
+            b->rhs = 2; b->sense = 'L';
+        } else {
+            printf ("Creating child 1 of LP %d: Set Clique >= 4\n", lp->id);
+            b->rhs = 4; b->sense = 'G';
+        }
+    }
+    fflush (stdout);
+
+    rval = CCtsp_execute_branch (lp, b);
+    if (rval && rval != 2) {
+        fprintf (stderr, "CCtsp_execute_branch failed\n"); goto CLEANUP;
+    } else if (rval == 2) {
+        printf ("Branched-LP is infeasible\n"); fflush (stdout);
+        rval = CCtsp_verify_infeasible_lp (lp, &test);
+        if (rval) {
+            fprintf (stderr, "CCtsp_verify_infeasible_lp failed\n");
+            goto CLEANUP;
+        }
+        if (test) {
+            printf ("Do not creat child node - infeasible\n"); fflush (stdout);
+            /* for proof mode, write the infeasible LP here */
+            *val = CCtsp_LP_MAXDOUBLE;
+            *prune = 1;
+            rval = 0;
+        } else {
+            fprintf (stderr, "did not verify an infeasible LP\n");
+            rval = 1; goto CLEANUP;
+        }
+    } else {
+        rval = CCtsp_pricing_loop (lp, &newbound);
+        if (rval) {
+            fprintf (stderr, "CCtsp_pricing_loop\n"); goto CLEANUP;
+        }
+        *val = newbound;
+        lp->lowerbound = newbound;
+
+        if (lp->lowerbound >= lp->upperbound - 0.9) {
+            rval = CCtsp_verify_lp_prune (lp, &test);
+            if (rval) {
+                fprintf (stderr, "CCtsp_verify_lp_prune failed\n");
+                goto CLEANUP;
+            }
+            if (test) {
+                printf ("verified that child can be pruned\n"); fflush (stdout);
+                *prune = 1;  /* for proof mode, write the lp file here */
+            } else {
+                fprintf (stderr, "exact pricing could not prune child\n");
+                rval = 1; goto CLEANUP;
+            }
+        } else {
+            lp->parent_id = oldid;
+            lp->id = child;
+            rval = CCtsp_write_probfile_id (lp);
+            if (rval) {
+                fprintf (stderr, "CCtsp_write_probfile_id failed\n");
+                goto CLEANUP;
+            }
+            lp->parent_id = oldparent;
+            lp->id = oldid;
+        }
+        lp->lowerbound = oldbound;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_splitprob (CCtsp_lp *lp, CCtsp_branchobj *b, int child0, int child1)
+#else
+int CCtsp_splitprob (lp, b, child0, child1)
+CCtsp_lp *lp;
+CCtsp_branchobj *b;
+int child0, child1;
+#endif
+{
+    int oldid     =  lp->id;
+    int oldparent =  lp->parent_id;
+    CClpbasis basis;
+    int rval = 0;
+
+    CClp_init_basis (&basis);
+    rval = CClp_get_basis_and_norms (&lp->lp, &basis);
+    if (rval) {
+        fprintf (stderr, "CClp_get_basis_and_norms failed\n"); goto CLEANUP;
+    }
+
+    lp->parent_id = lp->id;
+
+    if (b->ends[0] != -1) {
+        b->rhs = 0;
+    } else {
+        b->rhs = 2;
+        b->sense = 'L';
+    }
+
+    lp->id = child0;
+    rval = CCtsp_execute_branch (lp, b);
+    if (rval == 2) {
+        rval = 0;
+        printf ("The down side of the branch was infeasible\n");
+        fflush (stdout);
+    } else if (rval) {
+        fprintf (stderr, "CCtsp_execute_branch failed\n"); goto CLEANUP;
+    }
+    rval = CCtsp_write_probfile_id (lp);
+    if (rval) {
+        fprintf (stderr, "CCtsp_write_probfile_id failed\n"); goto CLEANUP;
+    }
+    rval = CCtsp_execute_unbranch (lp, &basis);
+    if (rval) {
+        fprintf (stderr, "CCtsp_execute_unbranch failed\n"); goto CLEANUP;
+    }
+
+    if (b->ends[0] != -1) {
+        b->rhs = 1;
+    } else {
+        b->rhs = 4;
+        b->sense = 'G';
+    }
+
+    lp->id = child1;
+    rval = CCtsp_execute_branch (lp, b);
+    if (rval == 2) {
+        rval = 0;
+        printf ("The up side of the branch was infeasible\n");
+        fflush (stdout);
+    } else if (rval) {
+        fprintf (stderr, "CCtsp_execute_branch failed\n"); goto CLEANUP;
+    }
+    rval = CCtsp_write_probfile_id (lp);
+    if (rval) {
+        fprintf (stderr, "CCtsp_write_probfile_id failed\n"); goto CLEANUP;
+    }
+    rval = CCtsp_execute_unbranch (lp, &basis);
+    if (rval) {
+        fprintf (stderr, "CCtsp_execute_unbranch failed\n"); goto CLEANUP;
+    }
+
+
+CLEANUP:
+
+    CClp_free_basis (&basis);
+    lp->parent_id = oldparent;
+    lp->id = oldid;
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_dumptour (int ncount, CCdatagroup *dat, int *perm, char *probname,
+        int *tour)
+#else
+int CCtsp_dumptour (ncount, dat, perm, probname, tour)
+int ncount;
+CCdatagroup *dat;
+int *perm;
+char *probname;
+int *tour;
+#endif
+{
+    int rval = 0;
+    int *cyc = (int *) NULL;
+    int i;
+    double len = 0.0;
+    char buf[1024];
+
+    if (!perm || !tour) {
+        fprintf (stderr, "bad input for CCtsp_dumptour\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    sprintf (buf, "%s.sol", probname);
+    cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!cyc) {
+        fprintf (stderr, "out of memory in CCtsp_dumptour\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        cyc[i] = 0;
+    }
+    for (i = 0; i < ncount; i++) {
+        cyc[tour[i]] = 1;
+    }
+    for (i = 0; i < ncount; i++) {
+        if (cyc[i] == 0) {
+            fprintf (stderr, "array is not a tour in CCtsp_dumptour\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+    for (i = 0; i < ncount; i++) {
+        cyc[i] = perm[tour[i]];
+    }
+
+    if (dat) {
+        for (i = 1; i < ncount; i++) {
+            len += (double) CCutil_dat_edgelen (tour[i-1], tour[i], dat);
+        }
+        len += (double) CCutil_dat_edgelen (tour[ncount-1], tour[0], dat);
+        printf ("Write tour of length %.2f to %s\n", len, buf);
+        fflush (stdout);
+    } else {
+        printf ("Write tour to %s\n", buf);
+        fflush (stdout);
+    }
+
+    rval = CCutil_writecycle (ncount, buf, cyc);
+    if (rval) {
+        fprintf (stderr, "writecycle failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (cyc, int);
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/TSP/cliqhash.c b/contrib/blossom/concorde97/TSP/cliqhash.c
new file mode 100644
index 0000000000000000000000000000000000000000..b8172ae6fc0022699955ed6ad2696128e2cfd2e9
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/cliqhash.c
@@ -0,0 +1,207 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  ROUTINES TO HASH CLIQUES                               */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: October 10, 1995                                                 */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_init_cliquehash (CCtsp_lpcuts *cuts, int size)             */
+/*       initializes the clique hash storage in cuts.                      */
+/*       int size is an estimate of the number of cliques                  */
+/*                                                                         */
+/*    int CCtsp_register_clique (CCtsp_lpcuts *cuts, CCtsp_lpclique *c)    */
+/*       returns an integer index for c, adding c to cuts if necessary     */
+/*       -1 ==> failure                                                    */
+/*                                                                         */
+/*    void CCtsp_free_cliquehash (CCtsp_lpcuts *cuts)                      */
+/*       frees the clique hashtable space                                  */
+/*                                                                         */
+/*    void CCtsp_unregister_clique (CCtsp_lpcuts *cuts, int c)             */
+/*       deletes a reference to clique c, and deletes the clique if no     */
+/*       references remain                                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static unsigned int
+    hashclique (CCtsp_lpclique *c);
+
+static int
+    clique_eq (CCtsp_lpclique *c, CCtsp_lpclique *d);
+
+#else
+
+static unsigned int
+    hashclique ();
+
+static int
+    clique_eq ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_init_cliquehash (CCtsp_lpcuts *cuts, int size)
+#else
+int CCtsp_init_cliquehash (cuts, size)
+CCtsp_lpcuts *cuts;
+int size;
+#endif
+{
+    int i;
+
+    cuts->cliquehashsize = (int) CCutil_nextprime ((unsigned int) size);
+    cuts->cliquehash = CC_SAFE_MALLOC (cuts->cliquehashsize, int);
+    if (!cuts->cliquehash) {
+        cuts->cliquehashsize = 0;
+        return 1;
+    }
+    for (i=0; i<cuts->cliquehashsize; i++) {
+        cuts->cliquehash[i] = -1;
+    }
+    cuts->cliquefree = -1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_cliquehash (CCtsp_lpcuts *cuts)
+#else
+void CCtsp_free_cliquehash (cuts)
+CCtsp_lpcuts *cuts;
+#endif
+{
+    CC_IFFREE (cuts->cliquehash, int);
+    cuts->cliquehashsize = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static unsigned int hashclique (CCtsp_lpclique *c)
+#else
+static unsigned int hashclique (c)
+CCtsp_lpclique *c;
+#endif
+{
+    unsigned int x = 0;
+    int i;
+
+    for (i=0; i<c->segcount; i++) {
+        x = x * 65537 + c->nodes[i].lo * 4099 + c->nodes[i].hi;
+    }
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int clique_eq (CCtsp_lpclique *c, CCtsp_lpclique *d)
+#else
+static int clique_eq (c, d)
+CCtsp_lpclique *c;
+CCtsp_lpclique *d;
+#endif
+{
+    int i;
+
+    if (c->segcount != d->segcount) return 0;
+    for (i=0; i<c->segcount; i++) {
+        if (c->nodes[i].lo != d->nodes[i].lo) return 0;
+        if (c->nodes[i].hi != d->nodes[i].hi) return 0;
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_register_clique (CCtsp_lpcuts *cuts, CCtsp_lpclique *c)
+#else
+int CCtsp_register_clique (cuts, c)
+CCtsp_lpcuts *cuts;
+CCtsp_lpclique *c;
+#endif
+{
+    int x = hashclique (c) % cuts->cliquehashsize;
+    int y = cuts->cliquehash[x];
+    CCtsp_segment *new = (CCtsp_segment *) NULL;
+    int i;
+
+    while (y != -1) {
+        if (clique_eq (c, &cuts->cliques[y])) {
+            cuts->cliques[y].refcount++;
+            return y;
+        }
+        y = cuts->cliques[y].hashnext;
+    }
+
+    new = CC_SAFE_MALLOC (c->segcount, CCtsp_segment);
+    if (!new) {
+        fprintf (stderr, "out of memory in register_clique\n");
+        return -1;
+    }
+
+    if (cuts->cliquefree != -1) {
+        y = cuts->cliquefree;
+        cuts->cliquefree = cuts->cliques[y].hashnext;
+    } else {
+        if (cuts->cliqueend >= cuts->cliquespace) {
+            if (CCutil_reallocrus_scale ((void **) &cuts->cliques,
+                          &cuts->cliquespace,
+                          cuts->cliqueend + 1, 1.3, sizeof (CCtsp_lpclique))) {
+                CC_FREE (new, CCtsp_segment);
+                return -1;
+            }
+        }
+        y = cuts->cliqueend++;
+    }
+    cuts->cliques[y].segcount = c->segcount;
+    for (i=0; i<c->segcount; i++) {
+        new[i] = c->nodes[i];
+    }
+    cuts->cliques[y].nodes = new;
+    cuts->cliques[y].refcount = 1;
+    cuts->cliques[y].hashnext = cuts->cliquehash[x];
+    cuts->cliquehash[x] = y;
+
+    return y;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_unregister_clique (CCtsp_lpcuts *cuts, int c)
+#else
+void CCtsp_unregister_clique (cuts, c)
+CCtsp_lpcuts *cuts;
+int c;
+#endif
+{
+    int x, y, yprev;
+
+    cuts->cliques[c].refcount--;
+    if (cuts->cliques[c].refcount) return;
+    x = hashclique (&cuts->cliques[c]) % cuts->cliquehashsize;
+    y = cuts->cliquehash[x];
+    if (y == c) {
+        cuts->cliquehash[x] = cuts->cliques[c].hashnext;
+    } else {
+        yprev = y;
+        y = cuts->cliques[y].hashnext;
+        while (y != c && y != -1) {
+            yprev = y;
+            y = cuts->cliques[y].hashnext;
+        }
+        if (y == -1) {
+            fprintf (stderr, "Couldn't find clique to delete from hash\n");
+            return;
+        }
+        cuts->cliques[yprev].hashnext = cuts->cliques[c].hashnext;
+    }
+    CC_FREE (cuts->cliques[c].nodes, CCtsp_segment);
+    cuts->cliques[c].segcount = -1;
+    cuts->cliques[c].hashnext = cuts->cliquefree;
+    cuts->cliquefree = c;
+}
diff --git a/contrib/blossom/concorde97/TSP/cliqwork.c b/contrib/blossom/concorde97/TSP/cliqwork.c
new file mode 100644
index 0000000000000000000000000000000000000000..cc11935e5c96f9b874d9af36ff2f953b31430c27
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/cliqwork.c
@@ -0,0 +1,273 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  SOME ROUTINES FOR HANDLING CLIQUES                     */
+/*                                                                         */
+/*                              TSP CODE                                   */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: July 15, 1997                                                    */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*                                                                         */
+/*    void CCtsp_mark_clique (CCtsp_lpclique *c, int *marks, int marker)   */
+/*     MARKS the nodes in clique c                                         */
+/*      -marks an array of length at least ncount                          */
+/*      -marker an int that is used to mark the clique entries in marks    */
+/*                                                                         */
+/*    void CCtsp_mark_clique_and_neighbors (CCtsp_lpgraph *g,              */
+/*            CCtsp_lpclique *c, int *marks, int marker)                   */
+/*     MARKS the clique and the neighbors of the clique                    */
+/*                                                                         */
+/*    void CCtsp_mark_clique_and_neighbors_double (CCtsp_lpgraph *g,       */
+/*            CCtsp_lpclique *c, double *marks, double marker)             */
+/*     MARKS the clique and the neighbors of the clique in a double array. */
+/*                                                                         */
+/*    void CCtsp_mark_cut (CCtsp_lpcut_in *c, int *marks, int marker)      */
+/*     MARKS the nodes in the cut.                                         */
+/*                                                                         */
+/*    void CCtsp_mark_cut_and_neighbors (CCtsp_lpgraph *g,                 */
+/*            CCtsp_lpcut_in *c, int *marks, int marker)                   */
+/*     MARKS the nodes in the cut and their neighbors                      */
+/*                                                                         */
+/*    void CCtsp_is_clique_marked (CCtsp_lpclique *c, int *marks,          */
+/*            int marker, int *yes_no)                                     */
+/*     CHECKS if a node in the clique is marked with the value marker.     */
+/*      -yesno returns the result (1 is yes and 0 is no)                   */
+/*                                                                         */
+/*    void CCtsp_clique_count (CCtsp_lpclique *c, int *count)              */
+/*     COUNTS the number of nodes in the clique.                           */
+/*                                                                         */
+/*    int CCtsp_clique_to_array (CCtsp_lpclique *c, int **ar, int *count)  */
+/*     EXPANDS a clique into an array of integers.                         */
+/*                                                                         */
+/*    int CCtsp_clique_delta (CCtsp_lpgraph *g, double *x,                 */
+/*            CCtsp_lpclique *c, double *delta)                            */
+/*     COMPUTES the sum of the x-edges in the coboundary of the clique,    */
+/*      that is, x(delta(c)).                                              */
+/*      -delta returns the sum                                             */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_mark_clique (CCtsp_lpclique *c, int *marks, int marker)
+#else
+void CCtsp_mark_clique (c, marks, marker)
+CCtsp_lpclique *c;
+int *marks;
+int marker;
+#endif
+{
+    int i, j;
+
+    for (i = 0; i < c->segcount; i++) {
+        for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+            marks[j] = marker;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_mark_clique_and_neighbors (CCtsp_lpgraph *g, CCtsp_lpclique *c,
+        int *marks, int marker)
+#else
+void CCtsp_mark_clique_and_neighbors (g, c, marks, marker)
+CCtsp_lpgraph *g;
+CCtsp_lpclique *c;
+int *marks;
+int marker;
+#endif
+{
+    int i, j, k;
+
+    for (i = 0; i < c->segcount; i++) {
+        for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+            marks[j] = marker;
+            for (k = 0; k < g->nodes[j].deg; k++) {
+                marks[g->nodes[j].adj[k].to] = marker;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_mark_cut (CCtsp_lpcut_in *c, int *marks, int marker)
+#else
+void CCtsp_mark_cut (c, marks, marker)
+CCtsp_lpcut_in *c;
+int *marks;
+int marker;
+#endif
+{
+    int i;
+
+    for (i = 0; i < c->cliquecount; i++) {
+        CCtsp_mark_clique (&(c->cliques[i]), marks, marker);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_mark_cut_and_neighbors (CCtsp_lpgraph *g, CCtsp_lpcut_in *c,
+        int *marks, int marker)
+#else
+void CCtsp_mark_cut_and_neighbors (g, c, marks, marker)
+CCtsp_lpgraph *g;
+CCtsp_lpcut_in *c;
+int *marks;
+int marker;
+#endif
+{
+    int i;
+
+    for (i = 0; i < c->cliquecount; i++) {
+        CCtsp_mark_clique_and_neighbors (g, &(c->cliques[i]), marks, marker);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_mark_clique_and_neighbors_double (CCtsp_lpgraph *g,
+        CCtsp_lpclique *c, double *marks, double marker)
+#else
+void CCtsp_mark_clique_and_neighbors_double (g, c, marks, marker)
+CCtsp_lpgraph *g;
+CCtsp_lpclique *c;
+double *marks;
+double marker;
+#endif
+{
+    int i, j, k;
+
+    for (i = 0; i < c->segcount; i++) {
+        for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+            marks[j] = marker;
+            for (k = 0; k < g->nodes[j].deg; k++) {
+                marks[g->nodes[j].adj[k].to] = marker;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_is_clique_marked (CCtsp_lpclique *c, int *marks, int marker,
+        int *yes_no)
+#else
+void CCtsp_is_clique_marked (c, marks, marker, yes_no)
+CCtsp_lpclique *c;
+int *marks;
+int marker;
+int *yes_no;
+#endif
+{
+    int i, j;
+
+    for (i = 0; i < c->segcount; i++) {
+        for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+            if (marks[j] == marker) {
+                *yes_no = 1;
+                return;
+            }
+        }
+    }
+    *yes_no = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_clique_count (CCtsp_lpclique *c, int *count)
+#else
+void CCtsp_clique_count (c, count)
+CCtsp_lpclique *c;
+int *count;
+#endif
+{
+    int i;
+    CCtsp_segment *nodes = c->nodes;
+
+    *count = 0;
+    for (i = 0; i < c->segcount; i++) {
+        (*count) += (nodes[i].hi - nodes[i].lo + 1);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_clique_to_array (CCtsp_lpclique *c, int **ar, int *count)
+#else
+int CCtsp_clique_to_array (c, ar, count)
+CCtsp_lpclique *c;
+int **ar;
+int *count;
+#endif
+{
+    int rval = 0;
+    int i, j;
+    int k = 0;
+
+    *ar = (int *) NULL;
+
+    CCtsp_clique_count (c, count);
+    if (count) {
+        *ar = CC_SAFE_MALLOC (*count, int);
+        if (!(*ar)) {
+            fprintf (stderr, "out of memory in CCtsp_clique_to_array\n");
+            rval = 1; goto CLEANUP;
+        }
+        for (i = 0; i < c->segcount; i++) {
+            for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+                (*ar)[k++] = j;
+            }
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_clique_delta (CCtsp_lpgraph *g, double *x, CCtsp_lpclique *c,
+        double *delta)
+#else
+int CCtsp_clique_delta (g, x, c, delta)
+CCtsp_lpgraph *g;
+double *x;
+CCtsp_lpclique *c;
+double *delta;
+#endif
+{
+    int rval = 0;
+    int i, j, k;
+    int *marks = (int *) NULL;
+    CCtsp_lpnode *n;
+
+    *delta = 0.0;
+
+    marks = CC_SAFE_MALLOC (g->ncount, int);
+    if (!marks) {
+        fprintf (stderr, "out of memory in CCtsp_clique_delta\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    CCtsp_mark_clique_and_neighbors (g, c, marks, 0);
+    CCtsp_mark_clique (c, marks, 1);
+
+    for (i = 0; i < c->segcount; i++) {
+        for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+            n = &g->nodes[j];
+            for (k = 0; k < n->deg; k++) {
+                if (!marks[n->adj[k].to]) {
+                    (*delta) += x[n->adj[k].edge];
+                }
+            }
+        }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (marks, int);
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/TSP/concorde.c b/contrib/blossom/concorde97/TSP/concorde.c
new file mode 100644
index 0000000000000000000000000000000000000000..75a3a4c51608cdda39dc80b80059eb679269c4d4
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/concorde.c
@@ -0,0 +1,970 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  THE MAIN PROGRAM FOR CONCORDE                          */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: September 25, 1995                                               */
+/*                                                                         */
+/*  SEE short decsribtion in usage ().                                     */
+/*                                                                         */
+/*  Link with:                                                             */
+/*    SEE conmake.grs                                                      */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "edgegen.h"
+#include "tsp.h"
+#include "linkern.h"
+#include "bigguy.h"
+#include "macrorus.h"
+
+#define CC_LK_TRY  (1)    /* number of trials to generate initial tour */
+
+static int norm = CC_EUCLIDEAN;
+static char *datfname     = (char *) NULL;
+static char *edgegenfname = (char *) NULL;
+static char *probname     = (char *) NULL;
+static char *probfname    = (char *) NULL;
+static char *edgefname    = (char *) NULL;
+static char *fullfname    = (char *) NULL;
+static char *tourfname    = (char *) NULL;
+static char *masterfname  = (char *) NULL;
+static char *poolfname    = (char *) NULL;
+static char *xfname       = (char *) NULL;
+static int binary_in = 0;
+static int tsplib_in = 0;
+static int nnodes_want = 0;
+static int seed = 0;
+static int just_subtour = 0;
+static int valid_edges = 0;
+static double initial_ub = CCtsp_LP_MAXDOUBLE;
+static int useconsecutiveones = 0;
+static int usenecklace = 0;
+static int usetighten  = 1;
+static int dfs_branching = 0;
+static int bfs_branching = 0;
+static int usebranchcliques = 0;
+static int standalone_branch = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+
+static void
+    usage (char *f);
+
+static int
+    parseargs (int ac, char **av),
+    find_good_tour (int ncount, CCdatagroup *dat, int *perm, double *ub,
+            int trials),
+    getedges (CCdatagroup *dat, CCedgegengroup *plan, int ncount, int *ecount,
+            int **elist, int **elen);
+
+#else
+
+int
+    main ();
+
+static void
+    usage ();
+
+static int
+    parseargs (),
+    find_good_tour (),
+    getedges ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    double szeit;
+    char dummyname[256];
+    int i, ncount;
+    CCdatagroup dat;
+    CCdatagroup *mydat = (CCdatagroup *) NULL;
+    CCtsp_lp *lp = (CCtsp_lp *) NULL;
+    CCbigguy bound;
+    CCtsp_cutselect sel;
+    CCtsp_lpcuts *pool = (CCtsp_lpcuts *) NULL;
+    int *ptour = (int *) NULL;
+    int ecount = 0;
+    int *elist = (int *) NULL;
+    int *elen = (int *) NULL;
+    int excount = 0;
+    int *exlist = (int *) NULL;
+    int *exlen = (int *) NULL;
+    int *besttour = (int *) NULL;
+    int probnum = -1;
+    int rval = 0;
+
+    for (i=0; i<ac; i++) {
+        printf ("%s", av[i]);
+        if (i < ac-1) printf (" ");
+    }
+    printf ("\n");
+    fflush (stdout);
+
+    szeit = CCutil_zeit ();
+    seed = (int) CCutil_real_zeit ();
+    if (parseargs (ac, av))
+        return 0;
+    CCutil_sprand (seed);
+    printf ("Using random seed %d\n", seed); fflush (stdout);
+
+    if (datfname == (char *) NULL && nnodes_want == 0 && probnum == -1 &&
+       probfname == (char *) NULL && edgefname == (char *) NULL &&
+       masterfname == (char *) NULL) {
+        usage (av[0]);
+        return 0;
+    }
+    ncount = nnodes_want;
+
+
+    /****** Get the ncount and the data set ******/
+
+    if (masterfname != (char *) NULL) {
+        if (CCutil_getmaster (masterfname, &ncount, &dat, &ptour)) {
+            fprintf (stderr, "getmaster failed\n");
+            return 1;
+        }
+        if (dat.norm != 0) {
+            mydat = &dat;
+        } else  {
+            mydat = (CCdatagroup *) NULL;
+        }
+    } else {
+        if (tsplib_in && datfname != (char *) NULL) {
+            if (CCutil_gettsplib (datfname, &ncount, &dat)) {
+                fprintf (stderr, "could not read the TSPLIB file\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            norm = dat.norm;
+            mydat = &dat;
+        } else if (datfname != (char *) NULL || edgefname == (char *) NULL) {
+            if (CCutil_getdata (datfname, binary_in, norm, &ncount, &dat)) {
+                fprintf (stderr, "Could not create data set\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            mydat = &dat;
+        } else {
+            /* Look at edge file to get ncount */
+
+            if (CCutil_getedgelist_n (&ncount, edgefname, &ecount, &elist,
+                                      &elen)) {
+                fprintf  (stderr, "Could not read edge set\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            printf ("Number of nodes: %d\n", ncount);
+            fflush (stdout);
+
+            CC_IFFREE (elist, int);
+            CC_IFFREE (elen, int);
+            ecount = 0;
+            mydat = (CCdatagroup *) NULL;
+        }
+    }
+
+    if (ncount < 10) {
+        fprintf (stderr, "Less than 10 nodes.  Who cares.\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+    if (mydat) {
+        if (CCutil_init_dat_edgelen (mydat)) {
+            fprintf (stderr, "CCutil_init_dat_edgelen failed\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+
+    /***** Get the permutation tour and permute the data  *****/
+
+    if (!ptour) {
+        ptour = CC_SAFE_MALLOC (ncount, int);
+        if (!ptour) {
+            fprintf (stderr, "out of memory in main\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+
+        if (tourfname) {
+            rval = CCutil_getcycle (ncount, tourfname, ptour);
+            if (rval) {
+                fprintf (stderr, "getcycle failed\n");
+                goto CLEANUP;
+            }
+        } else if (mydat) {
+            double bnd;
+            if (just_subtour) {
+                rval = find_good_tour (ncount, mydat, ptour, &bnd, -1);
+            } else if (initial_ub == CCtsp_LP_MAXDOUBLE) {
+                rval = find_good_tour (ncount, mydat, ptour, &bnd, CC_LK_TRY);
+            } else {
+                printf ("Initial bnd %f given - use short tour run\n",
+                      initial_ub);
+                fflush (stdout);
+                rval = find_good_tour (ncount, mydat, ptour, &bnd, 0);
+            }
+            if (rval) {
+                fprintf (stderr, "find_good_tour failed\n");
+                goto CLEANUP;
+            }
+        } else {
+            fprintf (stderr, "no way to generate the permutation tour\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+
+        if (mydat) {
+            rval = CCutil_datagroup_perm (ncount, mydat, ptour);
+            if (rval) goto CLEANUP;
+        }
+    }
+    if (mydat) {
+        double bnd;
+
+        bnd = CCutil_dat_edgelen (ncount - 1, 0, mydat);
+        for (i = 1; i < ncount; i++) {
+            bnd += CCutil_dat_edgelen (i-1, i, mydat);
+        }
+        if (bnd < initial_ub) {
+            printf ("Set initial upperbound to %.2f (from tour)\n", bnd);
+            fflush (stdout);
+            initial_ub = bnd;
+        }
+    }
+
+
+    /***** Get the initial edge set *****/
+
+    if (!probfname) {
+        if (edgefname) {
+            int *invperm = (int *) NULL;
+
+            rval = CCutil_getedgelist (ncount, edgefname, &ecount, &elist,
+                                      &elen);
+            if (rval) {
+                fprintf (stderr, "getedgelist failed\n");
+                goto CLEANUP;
+            }
+            printf ("Initial edgeset: %d edges (%d nodes)\n", ecount, ncount);
+            printf ("Rearrange the edges to match the tour order\n");
+            fflush (stdout);
+
+            invperm = CC_SAFE_MALLOC (ncount, int);
+            if (!invperm) {
+                rval = 1;
+                goto CLEANUP;
+            }
+            for (i = 0; i < ncount; i++)
+                invperm[ptour[i]] = i;
+            for (i = 0; i < 2*ecount; i++)
+                elist[i] = invperm[elist[i]];
+            CC_FREE (invperm, int);
+        } else if (mydat) {
+            CCedgegengroup plan;
+
+            if (edgegenfname) {
+                rval = CCedgegen_read (edgegenfname, &plan);
+                if (rval) {
+                    fprintf (stderr, "CCedgegen_read failed\n");
+                    return 1;
+                }
+            } else {
+                CCedgegen_init_edgegengroup (&plan);
+                if (just_subtour) {
+                    plan.tour.greedy = 1;
+                    plan.f2match_nearest.number = 4;
+                } else {
+                    plan.linkern.count = 10;
+                    plan.linkern.quadnearest = 2;
+                    plan.linkern.greedy_start = 0;
+                    plan.linkern.nkicks = (ncount / 100) + 1;
+                }
+            }
+
+            rval = getedges (mydat, &plan, ncount, &ecount, &elist, &elen);
+            if (rval) {
+                fprintf (stderr, "getgraph failed\n");
+                goto CLEANUP;
+            }
+        }
+    }
+
+    /***** Get the problem name *****/
+
+    if (probname == (char *) NULL) {
+        char *p, *q;
+        char buf[1024];
+
+        probname = dummyname;
+
+        if (datfname || masterfname) {
+            if (datfname)
+                sprintf (buf, "%s", datfname);
+            else
+                sprintf (buf, "%s", masterfname);
+            p = CCutil_strrchr (buf, '/');
+            if (!p)
+                p = buf;
+            else
+                p++;
+            q = CCutil_strrchr (p, '.');
+            if (q)
+                *q = '\0';
+            sprintf (probname, "%s",  p);
+        } else {
+            sprintf (probname, "%s", "noname");
+        }
+    }
+
+
+    /***** Write the master file *****/
+
+    if (!masterfname) {
+        char buf[1024];
+
+        sprintf (buf, "%s.mas", probname);
+        rval = CCutil_writemaster (buf, ncount, mydat, ptour);
+        if (rval) {
+            fprintf (stderr, "writemaster failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    /***** Get full edges *****/
+
+    if (fullfname) {
+        int *invperm = (int *) NULL;
+
+        rval = CCutil_getedgelist (ncount, fullfname, &excount, &exlist,
+                                   &exlen);
+        if (rval) {
+            fprintf (stderr, "getedgelist failed\n");
+            goto CLEANUP;
+        }
+
+        invperm = CC_SAFE_MALLOC (ncount, int);
+        if (!invperm) {
+            fprintf (stderr, "out of memory in main\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        for (i = 0; i < ncount; i++)
+            invperm[ptour[i]] = i;
+        for (i = 0; i < 2*excount; i++)
+            exlist[i] = invperm[exlist[i]];
+        CC_FREE (invperm, int);
+    } else {
+        excount = 0;
+    }
+
+    /***** Get the initial cutpool *****/
+
+    rval = CCtsp_init_cutpool (ncount, poolfname, &pool);
+    if  (rval) {
+        fprintf (stderr, "CCtsp_init_cutpool failed\n");
+        goto CLEANUP;
+    }
+
+    /***** Initialize besttour to represent the permutation tour  ****/
+
+    besttour = CC_SAFE_MALLOC (ncount, int);
+    if (!besttour) {
+        fprintf (stderr, "out of memory in allocating best tour\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++) {
+        besttour[i] = i;
+    }
+
+    /***** Get the initial LP *****/
+
+    rval = CCtsp_init_lp (&lp, probname, probnum, probfname, ncount, mydat,
+                    ecount, elist, elen, excount, exlist, exlen, valid_edges,
+                    ptour, initial_ub, pool);
+    if (rval == 2) {
+        printf ("CCtsp_init_lp reports an infeasible LP\n");
+        rval = CCtsp_exact_price (lp, &bound, 1);
+        if (rval) {
+            fprintf (stderr, "CCtsp_exact_price failed\n");
+            goto CLEANUP;
+        }
+        if (CCbigguy_cmp (bound, CCbigguy_ZERO) < 0) {
+            printf ("Problem shown to be infeasible\n");
+            fflush (stdout);
+            lp->infeasible = 1;
+            lp->exact_lowerbound = CCbigguy_MAXBIGGUY;
+            goto DONE;
+        } else {
+            fprintf (stderr, "exact pricing did not verify an infeasible LP\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    } else if (rval) {
+        fprintf (stderr, "CCtsp_init_lp failed\n"); goto CLEANUP;
+    }
+
+    ecount = 0;
+    CC_IFFREE (elist, int);
+    CC_IFFREE (elen, int);
+    excount = 0;
+    CC_IFFREE (exlist, int);
+    CC_IFFREE (exlen, int);
+
+    if (lp->full_edges_valid) {
+        if (CCtsp_inspect_full_edges (lp)) {
+            fprintf (stderr, "full edge set does not contain all LP edges\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    if (xfname) {
+        rval = CCtsp_dump_x (lp, xfname);
+        if (rval) {
+            fprintf (stderr, "CCtsp_dump_x failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (standalone_branch) {
+        rval = CCtsp_do_interactive_branch (lp);
+        if (rval) {
+            fprintf (stderr, "CCtsp_do_interactive_branch failed\n");
+            goto CLEANUP;
+        } else {
+            printf ("completed interative branch\n");
+            printf ("Total Running Time: %.2f (seconds)\n",
+                               CCutil_zeit () - szeit);
+            goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_init_cutselect (lp, &sel);
+    if (rval) {
+        fprintf (stderr, "CCtsp_init_cutselect failed\n");
+        goto CLEANUP;
+    }
+    if (useconsecutiveones) sel.consecutiveones = 1;
+    if (usenecklace)        sel.necklace = 1;
+    sel.usetighten = usetighten;
+
+    if (just_subtour) {
+        rval = CCtsp_subtour_loop (lp);
+        if (rval) {
+            fprintf (stderr, "CCtsp_subtour_loop failed\n");
+            goto CLEANUP;
+        }
+        printf ("Bound: %f\n", lp->lowerbound); fflush (stdout);
+        goto DONE;
+    } else {
+        rval = CCtsp_cutting_loop (lp, &sel, 1);
+        if (rval == 2) {
+            printf ("CCtsp_cutting_loop reports an infeasible LP\n");
+            rval = CCtsp_exact_price (lp, &bound, 1);
+            if (rval) {
+                fprintf (stderr, "CCtsp_exact_price failed\n");
+                goto CLEANUP;
+            }
+            if (CCbigguy_cmp (bound, CCbigguy_ZERO) < 0) {
+                printf ("Problem shown to be infeasible\n");
+                fflush (stdout);
+                lp->infeasible = 1;
+                lp->exact_lowerbound = CCbigguy_MAXBIGGUY;
+                goto DONE;
+            } else {
+                fprintf (stderr, "pricing did not verify an infeasible LP\n");
+                rval = 1; goto CLEANUP;
+            }
+        } else if (rval) {
+            fprintf (stderr, "cutting_loop failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (mydat) {
+        double tourval;
+        rval = CCtsp_call_x_heuristic (lp, &tourval, besttour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_call_x_heuristic failed\n");
+            goto CLEANUP;
+        }
+        if (tourval < lp->upperbound) {
+            printf ("New upperbound from x-heuristic: %.2f\n", tourval);
+            lp->upperbound = tourval;
+            rval = CCtsp_dumptour (ncount, mydat, ptour, probname, besttour);
+            if (rval) {
+                fprintf (stderr, "CCtsp_dumptour failed\n"); goto CLEANUP;
+            }
+        }
+    }
+
+    printf ("Final lower bound %f, upper bound %f\n", lp->lowerbound,
+                                                      lp->upperbound);
+    fflush (stdout);
+
+    if (lp->graph.ncount < 100000) {
+        CCbigguy bupper;
+        rval = CCtsp_exact_price (lp, &bound, 0);
+        if (rval) {
+            fprintf (stderr, "CCtsp_exact_price failed\n");
+            goto CLEANUP;
+        }
+        lp->exact_lowerbound = bound;
+        printf ("Exact lower bound: %.6f\n", CCbigguy_bigguytod (bound));
+        printf ("DIFF: %f\n", lp->lowerbound - CCbigguy_bigguytod (bound));
+        fflush (stdout);
+
+        bupper = CCbigguy_dtobigguy (lp->upperbound);
+        CCbigguy_sub (&bupper, CCbigguy_ONE);
+
+        if (CCbigguy_cmp (lp->exact_lowerbound, bupper) > 0) {
+            printf ("Optimal Solution: %.2f\n", lp->upperbound);
+            if (dfs_branching || bfs_branching) {
+                printf ("Number of bbnodes: %d\n", 0);
+            }
+            fflush (stdout);
+            goto DONE;
+        }
+
+        rval = CCtsp_eliminate_variables (lp);
+        if (rval) {
+            fprintf (stderr, "CCtsp_eliminate_variables failed\n");
+            goto CLEANUP;
+        }
+    } else {
+        printf ("During testing, do not exact price large problems\n");
+        fflush (stdout);
+        goto DONE;
+    }
+
+    if (dfs_branching) {
+        double upbound = lp->upperbound;
+        int bbcount = 0;
+
+        rval = CCtsp_easy_dfs_brancher (lp, &sel, 0, &upbound, &bbcount,
+                                        usebranchcliques, besttour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_easy_dfs_brancher failed\n");
+            goto CLEANUP;
+        }
+        printf ("Optimal Solution: %.2f\n", upbound);
+        printf ("Number of bbnodes: %d\n", bbcount);
+        fflush (stdout);
+        rval = CCtsp_dumptour (ncount, mydat, ptour, probname, besttour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_dumptour failed\n"); goto CLEANUP;
+        }
+    } else if (bfs_branching) {
+        double upbound  = lp->upperbound;
+        double lowbound = lp->lowerbound;
+        int id          = lp->id;
+        int bbcount = 0;
+
+        rval = CCtsp_write_probfile_id (lp);
+        if (rval) {
+            fprintf (stderr, "CCtsp_write_probfile_id failed\n");
+            goto CLEANUP;
+        }
+        CCtsp_free_tsp_lp_struct (&lp);
+
+        rval = CCtsp_bfs_brancher (probname, id, lowbound, &sel, &upbound,
+                                   &bbcount, usebranchcliques, mydat, ptour,
+                                   pool, ncount, besttour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_bfs_brancher failed\n"); goto CLEANUP;
+        }
+
+        printf ("Optimal Solution: %.2f\n", upbound);
+        printf ("Number of bbnodes: %d\n", bbcount);
+        fflush (stdout);
+        rval = CCtsp_dumptour (ncount, mydat, ptour, probname, besttour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_dumptour failed\n"); goto CLEANUP;
+        }
+    }
+
+DONE:
+
+    printf ("Total Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    if (!dfs_branching && !bfs_branching) {
+        CCtsp_print_tighten_info (&lp->tighten_stats);
+        CClp_nonzeros (&lp->lp);
+
+        rval = CCtsp_write_probfile_sav (lp);
+        if (rval) {
+            fprintf (stderr, "CCtsp_write_probfile_sav failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (pool && pool->cutcount) {
+        char buf[1024];
+        printf ("Final Pool: %d cuts\n", pool->cutcount);
+        fflush (stdout);
+
+        sprintf (buf, "%s.pul", probname);
+        rval = CCtsp_write_cutpool (ncount, buf, pool);
+        if (rval) {
+            fprintf (stderr, "CCtsp_write_cutpool failed\n");
+            goto CLEANUP;
+        }
+    }
+    rval = 0;
+
+CLEANUP:
+
+    CCtsp_free_tsp_lp_struct (&lp);
+
+    if (pool) {
+        CCtsp_free_cutpool (&pool);
+    }
+
+    CC_IFFREE (elist, int);
+    CC_IFFREE (elen, int);
+    CC_IFFREE (exlist, int);
+    CC_IFFREE (exlen, int);
+    CC_IFFREE (ptour, int);
+    CC_IFFREE (besttour, int);
+    if (mydat)
+        CCutil_freedatagroup (ncount, mydat);
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: CCutil_bigchunk_free_world failed\n");
+        return 1;
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_good_tour (int ncount, CCdatagroup *dat, int *perm, double *ub,
+                           int trials)
+#else
+static int find_good_tour (ncount, dat, perm, ub, trials)
+int ncount;
+CCdatagroup *dat;
+int *perm;
+double *ub;
+int trials;
+#endif
+{
+    int rval = 0;
+    CCedgegengroup plan;
+    int ecount;
+    int *elist = (int *) NULL;
+    int tcount;
+    int *tlist = (int *) NULL;
+    int *bestcyc = (int *) NULL;
+    int *cyc     = (int *) NULL;
+    int *tmp;
+    double val, bestval, szeit;
+    int kicks;
+    int i;
+
+    szeit = CCutil_zeit ();
+    bestval = CCtsp_LP_MAXDOUBLE;
+
+    if (trials == -1) {
+        kicks = (ncount > 400 ? 100 : ncount/4);
+    } else {
+        kicks = (ncount > 1000 ? 500 : ncount/2);
+    }
+
+    printf ("Finding a good tour for compression: %d\n", trials);
+    fflush (stdout);
+
+    cyc     = CC_SAFE_MALLOC (ncount, int);
+    bestcyc = CC_SAFE_MALLOC (ncount, int);
+    if (!cyc || !bestcyc) {
+        fprintf (stderr, "out of memory in find_good_tour\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    CCedgegen_init_edgegengroup (&plan);
+    plan.quadnearest = 2;
+    rval = CCedgegen_edges (&plan, ncount, dat, (double *) NULL, &ecount,
+                            &elist);
+    if (rval) {
+        fprintf (stderr, "CCedgegen_edges failed\n"); goto CLEANUP;
+    }
+    plan.quadnearest = 0;
+
+
+    plan.tour.greedy = 1;
+    rval = CCedgegen_edges (&plan, ncount, dat, (double *) NULL, &tcount,
+                            &tlist);
+    if (rval) {
+        fprintf (stderr, "CCedgegen_edges failed\n"); goto CLEANUP;
+    }
+
+    if (tcount != ncount) {
+        fprintf (stderr, "wrong edgeset from edgegen\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCutil_edge_to_cycle (ncount, tlist, cyc);
+    if (rval) {
+        fprintf (stderr, "CCutil_edge_to_cycle failed\n");
+        rval = 1; goto CLEANUP;
+    }
+    CC_FREE (tlist, int);
+
+    rval = CClinkern_tour (ncount, dat, ecount, elist, ncount, kicks,
+                    cyc, bestcyc, &bestval, 0, 0.0, 0.0, (char *) NULL);
+    if (rval) {
+        fprintf (stderr, "CClinkern_tour failed\n"); goto CLEANUP;
+    }
+
+    for (i = 0; i < trials; i++) {
+        rval = CClinkern_tour (ncount, dat, ecount, elist, ncount, kicks,
+                        (int *) NULL, cyc, &val, 0, 0.0, 0.0, (char *) NULL);
+        if (rval) {
+            fprintf (stderr, "CClinkern_tour failed\n"); goto CLEANUP;
+        }
+        if (val < bestval) {
+            CC_SWAP (cyc, bestcyc, tmp);
+            bestval = val;
+        }
+    }
+
+    if (trials > 0) {
+        rval = CClinkern_tour (ncount, dat, ecount, elist, ncount, 2 * kicks,
+                        bestcyc, perm, ub, 0, 0.0, 0.0, (char *) NULL);
+        if (rval) {
+            fprintf (stderr, "CClinkern_tour failed\n"); goto CLEANUP;
+        }
+    } else {
+        for (i = 0; i < ncount; i++) {
+            perm[i] = bestcyc[i];
+        }
+    }
+
+    printf ("Time to find compression tour: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (cyc, int);
+    CC_IFFREE (bestcyc, int);
+    CC_IFFREE (elist, int);
+    CC_IFFREE (tlist, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int getedges (CCdatagroup *dat, CCedgegengroup *plan, int ncount,
+                     int *ecount, int **elist, int **elen)
+#else
+static int getedges (dat, plan, ncount, ecount, elist, elen)
+CCdatagroup *dat;
+CCedgegengroup *plan;
+int ncount, *ecount, **elist, **elen;
+#endif
+{
+    int i;
+
+    *elist = (int *) NULL;
+    *elen = (int *) NULL;
+
+    if (dat == (CCdatagroup *) NULL || plan == (CCedgegengroup *) NULL) {
+        fprintf (stderr, "getedges needs CCdatagroup and CCedgegenplan\n");
+        return 1;
+    }
+
+    if (CCedgegen_edges (plan, ncount, dat, (double *) NULL, ecount, elist)) {
+        fprintf (stderr, "CCedgegen_edges failed\n");
+        return 1;
+    }
+    *elen = CC_SAFE_MALLOC(*ecount, int);
+    if (!(*elen)) {
+        CC_FREE (*elist, int);
+        return 1;
+    }
+    for (i = 0; i < *ecount; i++) {
+        (*elen)[i] =
+             CCutil_dat_edgelen ((*elist)[2*i], (*elist)[(2*i) + 1], dat);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "bBcdD:e:E:fk:lM:n:N:P:s:STt:u:vUX:Y0123456789")) != EOF)
+        switch (c) {
+        case 'b':
+            binary_in = 1;
+            break;
+        case 'B':
+            bfs_branching = 1;
+            break;
+        case 'c':
+            useconsecutiveones = 1;
+            break;
+        case 'd':
+            dfs_branching = 1;
+            break;
+        case 'D':
+            edgegenfname = CCutil_bix_optarg;
+            break;
+        case 'e':
+            edgefname = CCutil_bix_optarg;
+            break;
+        case 'E':
+            fullfname = CCutil_bix_optarg;
+            break;
+        case 'f':
+            usetighten = 0;
+            break;
+        case 'k':
+            nnodes_want = atoi (CCutil_bix_optarg);
+            break;
+        case 'l':
+            usenecklace = 1;
+            break;
+        case 'n':
+            probname = CCutil_bix_optarg;
+            break;
+        case 'M':
+            masterfname = CCutil_bix_optarg;
+            break;
+        case 'N':
+            probfname = CCutil_bix_optarg;
+            break;
+        case 'P':
+            poolfname = CCutil_bix_optarg;
+            break;
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 'S':
+            just_subtour = 1;
+            break;
+        case 'T':
+            tsplib_in = 1;
+            break;
+        case 't':
+            tourfname =  CCutil_bix_optarg;
+            break;
+        case 'u':
+            initial_ub = atof (CCutil_bix_optarg);
+            break;
+        case 'v':
+            valid_edges = 1;
+            break;
+        case 'U':
+            usebranchcliques = 1;
+            break;
+        case 'X':
+            xfname = CCutil_bix_optarg;
+            break;
+        case 'Y':
+            standalone_branch = 1;
+            break;
+        case '0':
+            norm = CC_MAXNORM;
+            break;
+        case '1':
+            norm = CC_EUCLIDEAN_CEIL;
+            break;
+        case '2':
+            norm = CC_EUCLIDEAN;
+            break;
+        case '3':
+            norm = CC_EUCLIDEAN_3D;
+            break;
+        case '4':
+            norm = CC_IBM;
+            break;
+        case '5':
+            norm = CC_ATT;
+            break;
+        case '6':
+            norm = CC_GEOGRAPHIC;
+            break;
+        case '7':
+            norm = CC_MATRIXNORM;
+            break;
+        case '8':
+            norm = CC_DSJRANDNORM;
+            break;
+        case '9':
+            norm = CC_CRYSTAL;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+        default:
+            usage (av[0]);
+            return 1;
+        }
+    if (CCutil_bix_optind < ac) {
+        datfname = av[CCutil_bix_optind++];
+    }
+
+    if (CCutil_bix_optind != ac) {
+        usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "Usage: %s [-see below-] [dat_file]\n", f);
+    fprintf (stderr, "   -b    datfile in integer binary format\n");
+    fprintf (stderr, "   -B    run best-bound branching\n");
+    fprintf (stderr, "   -c    use consecutive ones cuts\n");
+    fprintf (stderr, "   -d    dfs search\n");
+    fprintf (stderr, "   -D f  edgegen file for initial edge set\n");
+    fprintf (stderr, "   -e f  initial edge file\n");
+    fprintf (stderr, "   -E f  full edge file\n");
+    fprintf (stderr, "   -f    don't call tighten for each cut\n");
+    fprintf (stderr, "   -k #  number of nodes for random problem\n");
+    fprintf (stderr, "   -l    use necklace cuts\n");
+    fprintf (stderr, "   -M f  master file\n");
+    fprintf (stderr, "   -n s  problem name (just a name, not a file name)\n");
+    fprintf (stderr, "   -N f  prob file\n");
+    fprintf (stderr, "   -P f  cutpool file\n");
+    fprintf (stderr, "   -s #  random seed\n");
+    fprintf (stderr, "   -S    just solve the subtour polytope\n");
+    fprintf (stderr, "   -T    the dat file is a TSPLIB file\n");
+    fprintf (stderr, "   -t f  tour file (in node node node format)\n");
+    fprintf (stderr, "   -u v  initial upperbound\n");
+    fprintf (stderr, "   -U    permit branching on subtour inequalities\n");
+    fprintf (stderr, "   -v    full list valid (must contain initial list)\n");
+    fprintf (stderr, "   -(0 1 2 3) price out using (MAX JOHNSON L2 3D)  norm\n");
+    fprintf (stderr, "   -(4 5 6 7 8 9) IBM ATT GEO MATRIX DSJRAND CRYSTAL norm\n");
+}
diff --git a/contrib/blossom/concorde97/TSP/control.c b/contrib/blossom/concorde97/TSP/control.c
new file mode 100644
index 0000000000000000000000000000000000000000..5819de24940a9b8ab6339b8f403890aa25abfd63
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/control.c
@@ -0,0 +1,1175 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  THE CONTROLLER FOR CUTTING PLANES                      */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: June 27, 1997                                                    */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_init_cutselect (CCtsp_lp *lp, CCtsp_cutselect *s)          */
+/*     INITIALIZES the cut selctions                                       */
+/*     Note: The lp should be solved before this call.                     */
+/*                                                                         */
+/*    int CCtsp_cutting_loop (CCtsp_lp *lp, CCtsp_cutselect *sel,          */
+/*            int savelp)                                                  */
+/*     CALLS the cutting plane and pricing routines.                       */
+/*      -sel should be set with the desired cut selection.                 */
+/*      -savelp should be set to a nonzero value to write the lps to after */
+/*       rounds of cuts                                                    */
+/*     Note: It returns a 2 if the lp becomes infeasible                   */
+/*                                                                         */
+/*    int CCtsp_subtour_loop (CCtsp_lp *lp)                                */
+/*     CALLS the cutting and pricing to optimize over the subtour polytope.*/
+/*                                                                         */
+/*    int CCtsp_pricing_loop (CCtsp_lp *lp, double *bnd)                   */
+/*     ADDS negative reduced costs edges to lp and returns the current     */
+/*      lowerbound.                                                        */
+/*      -bnd can be NULL                                                   */
+/*     NOTE: The LP must have full_edges_valid.                            */
+/*                                                                         */
+/*    int CCtsp_call_x_heuristic (CCtsp_lp *lp, double *val, int *outcyc ) */
+/*     CALLS the x-greedy LK heuristic with the current LP solution.       */
+/*      -val returns the length of the tour.                               */
+/*      -outcyc will return the tour in node-node-node format if the       */
+/*       length of the tour is less than lp->upperbound; the array should  */
+/*       at least of length ncount (it can be NULL)                        */
+/*                                                                         */
+/*    int CCtsp_bb_cutting (char *probname, int probnum, int ncount,       */
+/*            CCdatagroup *dat, int *ptour, double initial_ub,             */
+/*            CCtsp_lpcuts *pool, CCtsp_cutselect *sel, double *val,       */
+/*            int *prune, int *foundtour, int *besttour)                   */
+/*     CALLS the cutting loop after reading the lp; writes the result to   */
+/*      the same prob file; using exact price to verify pruned runs        */
+/*      -upbound should be passed in as the current bound; if a better     */
+/*       tour is found then upbound will be updated                        */
+/*      -val returns the lp bound; it is CCtsp_LP_MAXDOUBLE if infeasible  */
+/*      -prune is set to 1 if bbnode can be pruned                         */
+/*      -foundtour is set to 1 if a better tour is found.                  */
+/*      -besttour (if not NULL) will return a better tour if one is found. */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+#include "Xstuff.h"
+#include "bigguy.h"
+#include "cut.h"
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    call_add_cuts (CCtsp_lp *lp, CCtsp_lpcut_in **cuts, int *cut_added,
+        int *xcount, int **xlist, double **x, double *val, int tighten),
+    lp_value (CCtsp_lp *lp, double *val),
+    lp_x (CCtsp_lp *lp, int *xcount, int **xlist, double **x),
+    full_edge_check (CCtsp_lp *lp, int *nadded),
+    sparse_edge_check (CCtsp_lp *lp, CCtsp_edgegenerator *eg, int *nadded,
+        double *bnd),
+    bb_cutting_work (CCtsp_lp **lp, char *probname, int probnum,
+        int ncount, CCdatagroup *dat, int *ptour, double upbound,
+        CCtsp_lpcuts *pool, CCtsp_cutselect *sel, double *val);
+
+#else
+
+static int
+    call_add_cuts (),
+    lp_value (),
+    lp_x (),
+    full_edge_check (),
+    sparse_edge_check (),
+    bb_cutting_work ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_init_cutselect (CCtsp_lp *lp, CCtsp_cutselect *s)
+#else
+int CCtsp_init_cutselect (lp, s)
+CCtsp_lp *lp;
+CCtsp_cutselect *s;
+#endif
+{
+    double ub;
+    int rval = 0;
+
+    s->cutpool          = 1;
+    s->connect          = 1;
+    s->segments         = 1;
+    s->exactsubtour     = 1;
+    s->tighten_lp       = 1;
+    s->decker_lp        = 0;
+    s->teething_lp      = 1;
+    s->tighten_pool     = 1;
+    s->decker_pool      = 0;
+    s->teething_pool    = 0;
+    s->maxchunksize     = 0;
+    s->Xfastcuts        = 1;
+    s->Xexactsubtours   = 0;
+    s->Xslowcuts        = 1;
+    s->consecutiveones  = 0;
+    s->necklace         = 0;
+    s->usetighten       = 1;
+    s->extra_connect    = 0;
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, &ub, (int *) NULL,
+              (int **) NULL, (double **) NULL, (double **) NULL,
+              (double **) NULL, (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n"); goto CLEANUP;
+    }
+
+    s->nexttol  = CCtsp_CUTS_NEXT_TOL * ub;
+    s->roundtol = CCtsp_CUTS_NEXT_ROUND * ub;
+
+CLEANUP:
+
+    return rval;
+}
+
+#define LOOP_FULL (25)      /* to force a full price after 25 inner loops */
+#define CC_NO_NEAREST (20)  /* the initial sparse graph for pricing       */
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_cutting_loop (CCtsp_lp *lp, CCtsp_cutselect *sel, int savelp)
+#else
+int CCtsp_cutting_loop (lp, sel, savelp)
+CCtsp_lp *lp;
+CCtsp_cutselect *sel;
+int savelp;
+#endif
+{
+    int xcount, cutcount, cutcount_connect, cut_added, edge_added;
+    int *xlist = (int *) NULL;
+    int outside = 0;
+    double newval, oldval, ub;
+    double *x = (double *) NULL;
+    CCtsp_lpcut_in *cuts = (CCtsp_lpcut_in *) NULL;
+    CCtsp_edgegenerator eginside;
+    int rval = 0;
+    int loopcount = 0;
+    double szeit = CCutil_zeit ();
+
+    eginside.ncount = 0;
+    if (lp->fulladj) {
+        rval = CCtsp_init_edgegenerator (&eginside, lp->graph.ncount, lp->dat,
+                                   lp->fulladj, 0);
+        if (rval) {
+            fprintf (stderr, "CCtsp_init_edgegenerator (sparse) failed\n");
+            rval = 1; goto CLEANUP;
+        }
+    } else if (lp->dat) {
+        rval = CCtsp_init_edgegenerator (&eginside, lp->graph.ncount, lp->dat,
+                                   (CCtsp_genadj *) NULL, CC_NO_NEAREST);
+        if (rval) {
+            fprintf (stderr, "CCtsp_init_edgegenerator (sparse) failed\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, &ub, (int *) NULL,
+              (int **) NULL, (double **) NULL, (double **) NULL,
+              (double **) NULL, (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    do {
+        loopcount = 0;
+        cutcount_connect = 0;
+        do {
+            cut_added = 0;
+            rval = lp_value (lp, &oldval);
+            if (rval) {rval = 1; goto CLEANUP;}
+
+            newval = oldval;
+
+            rval = lp_x (lp, &xcount, &xlist, &x);
+            if (rval) {rval = 1; goto CLEANUP;}
+
+            if (sel->cutpool) {
+                rval = CCtsp_search_cutpool (lp->pool, &cuts, &cutcount,
+                           lp->graph.ncount, xcount, xlist, x);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_search_cutpool failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount)  {
+                    printf ("Found %d cutpool cuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->connect) {
+                rval = CCtsp_connect_cuts (&cuts, &cutcount, lp->graph.ncount,
+                                           xcount, xlist, x);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_connect_cuts failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d connect cuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->segments) {
+                rval = CCtsp_segment_cuts (&cuts, &cutcount, lp->graph.ncount,
+                               xcount, xlist, x);
+                if (rval) {
+                    fprintf (stderr,  "CCtsp_segment_cuts failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d segment cuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->Xfastcuts) {
+                rval = Xfastcuts (&cuts, &cutcount, lp->graph.ncount, xcount,
+                                  xlist, x);
+                if (rval) {
+                    fprintf (stderr, "Xfastcuts failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d Xfastcuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->exactsubtour) {
+                rval = CCtsp_exact_subtours (&cuts, &cutcount, lp->graph.ncount,
+                                           xcount, xlist, x);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_exact_subtours failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d exact subtours\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->tighten_lp) {
+                rval = CCtsp_tighten_lp (&lp->cuts, &lp->tighten_stats, &cuts,
+                        &cutcount, lp->graph.ncount, xcount, xlist, x,
+                        1.0, 500);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_tighten_lp failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d tighten_lp cuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->teething_lp) {
+                rval = CCtsp_teething_lp (&lp->cuts, &lp->tighten_stats,
+                        &cuts, &cutcount, lp->graph.ncount, xcount, xlist, x,
+                        10.0, 500);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_teething_lp failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d teethed combs\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->Xexactsubtours) {
+                rval = Xexactsubtours (&cuts, &cutcount, lp->graph.ncount,
+                                  xcount, xlist, x);
+                if (rval) {
+                    fprintf (stderr, "Xexactsubtours failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d Xexactsubtours\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->Xslowcuts && newval < oldval + sel->nexttol) {
+                rval = Xslowcuts (&cuts, &cutcount, lp->graph.ncount,
+                                  xcount, xlist, x);
+                if (rval) {
+                    fprintf (stderr, "Xslowcuts failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d Xslowcuts\n", cutcount); fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->tighten_pool && newval < oldval + sel->nexttol) {
+                rval = CCtsp_tighten_lp (lp->pool, &lp->tighten_stats, &cuts,
+                         &cutcount, lp->graph.ncount, xcount, xlist, x, 0.1,
+                         1000);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_tighten_lp failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d tighten pool cuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->teething_pool && newval < oldval + sel->nexttol) {
+                rval = CCtsp_teething_lp (lp->pool, &lp->tighten_stats,
+                         &cuts, &cutcount, lp->graph.ncount, xcount, xlist, x,
+                         0.5, 1000);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_teething_lp failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d pool teething combs\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            if (sel->consecutiveones && newval < oldval + sel->nexttol) {
+                rval = Xconsecutiveones (&cuts, &cutcount, lp->graph.ncount,
+                                  xcount, xlist, x, lp->pool);
+                if (rval) {
+                    fprintf (stderr, "Xconsecutiveones failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d Xconsecutiveones cuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+            if (sel->necklace && newval < oldval + sel->nexttol) {
+                rval = Xnecklacecuts (&cuts, &cutcount, lp->graph.ncount,
+                                  xcount, xlist, x, lp->pool);
+                if (rval) {
+                    fprintf (stderr, "Xnecklacecuts failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d Xnecklace cuts\n", cutcount);
+                    fflush (stdout);
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, sel->usetighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                }
+            }
+
+            CC_FREE (xlist, int);
+            CC_FREE (x, double);
+
+            rval = sparse_edge_check (lp, &eginside, &edge_added,
+                                      (double *) NULL);
+            if (rval) {
+                fprintf (stderr, "sparse_edge_check failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            if (savelp) {
+                rval = CCtsp_write_probfile_sav (lp);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_write_probfile_sav failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+            }
+            if (lp->pool) {
+                char buf[1024];
+                printf ("Write Pool: %d cuts\n", lp->pool->cutcount);
+                fflush (stdout);
+                sprintf (buf, "%s.pul", lp->name);
+                rval = CCtsp_write_cutpool (lp->graph.ncount, buf, lp->pool);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_write_cutpool failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+            }
+            if (lp->lowerbound >= lp->upperbound - 0.9) {
+                printf ("Stop cutting, lp bound is within 0.9 of upperbound\n");
+                fflush (stdout);
+                goto CLEANUP;
+            }
+            loopcount++;
+        } while ((newval > oldval + sel->roundtol || edge_added)
+                  && loopcount < LOOP_FULL);
+
+        rval = full_edge_check (lp, &edge_added);
+        if (rval) {
+            fprintf (stderr, "full_edge_check failed\n");
+            rval = 1; goto CLEANUP;
+        }
+        if (savelp) {
+            rval = CCtsp_write_probfile_sav (lp);
+            if (rval) {
+                fprintf (stderr, "CCtsp_write_probfile_sav failed\n");
+                rval = 1; goto CLEANUP;
+            }
+        }
+
+        if (sel->extra_connect && (!edge_added || loopcount != LOOP_FULL)) {
+            printf ("Check connectivity before exiting cutting_loop\n");
+            fflush (stdout);
+
+            rval = lp_x (lp, &xcount, &xlist, &x);
+            if (rval) {rval = 1; goto CLEANUP;}
+
+            rval = CCtsp_connect_cuts (&cuts, &cutcount_connect, 
+                                       lp->graph.ncount,
+                                       xcount, xlist, x);
+            if (rval) {
+                fprintf (stderr, "CCtsp_connect_cuts failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            if (cutcount_connect) {
+                printf ("Found %d connect cuts\n", cutcount);
+                fflush (stdout);
+                rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                           &xlist, &x, &newval, sel->usetighten);
+                if (rval) {
+                    fprintf (stderr, "call_add_cuts failed\n");
+                    goto CLEANUP;
+                }
+            }
+            CC_FREE (xlist, int);
+            CC_FREE (x, double);
+        }
+        outside++;
+    } while (edge_added || loopcount == LOOP_FULL || cutcount_connect);
+
+CLEANUP:
+
+    if (rval == 2) {
+        printf ("LP is infeasible in cutting_loop\n");
+        fflush (stdout);
+    } else if (rval) {
+        fprintf (stderr, "failure in cutting_loop\n");
+    }
+    printf ("Time in cutting routine: %.2f\n", CCutil_zeit () - szeit);
+    printf ("Number of outside rounds: %d\n", outside);
+    fflush (stdout);
+
+    if (eginside.ncount)
+        CCtsp_free_edgegenerator (&eginside);
+    CC_IFFREE (xlist, int);
+    CC_IFFREE (x, double);
+
+    return rval;
+}
+
+#define CC_NO_NEAREST_SUBTOUR 50
+#define CC_SUBTOUR_ROUNDS     5
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_subtour_loop (CCtsp_lp *lp)
+#else
+int CCtsp_subtour_loop (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int rval = 0;
+    int xcount, cutcount, cut_added, edge_added;
+    int outside = 0;
+    int inside = 0;
+    int tighten = 0;
+    double newval;
+    int *xlist = (int *) NULL;
+    double *x = (double *) NULL;
+    CCtsp_lpcut_in *cuts = (CCtsp_lpcut_in *) NULL;
+    CCtsp_edgegenerator eginside;
+    double szeit = CCutil_zeit ();
+    double connect_zeit = 0.0;
+    double linsub_zeit  = 0.0;
+    double exact_zeit   = 0.0;
+    double tzeit;
+
+    eginside.ncount = 0;
+    if (lp->fulladj) {
+        rval = CCtsp_init_edgegenerator (&eginside, lp->graph.ncount, lp->dat,
+                             lp->fulladj, 0);
+        if (rval) {
+            fprintf (stderr, "CCtsp_init_edgegenerator (sparse) failed\n");
+            rval = 1; goto CLEANUP;
+        }
+    } else if (lp->dat) {
+        rval = CCtsp_init_edgegenerator (&eginside, lp->graph.ncount, lp->dat,
+                             (CCtsp_genadj *) NULL, CC_NO_NEAREST_SUBTOUR);
+        if (rval) {
+            fprintf (stderr, "CCtsp_init_edgegenerator (sparse) failed\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL,
+              (int *) NULL, (int **) NULL, (double **) NULL, (double **) NULL,
+              (double **) NULL, (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    do {
+        do {
+            cut_added = 0;
+
+            rval = lp_x (lp, &xcount, &xlist, &x);
+            if (rval) {rval = 1; goto CLEANUP;}
+
+
+            /**** Connect Cuts ****/
+
+
+            tzeit = CCutil_zeit ();
+            rval = CCtsp_connect_cuts (&cuts, &cutcount, lp->graph.ncount,
+                                       xcount, xlist, x);
+            connect_zeit += (CCutil_zeit () - tzeit);
+            if (rval) {
+                fprintf (stderr, "CCtsp_connect_cuts failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            if (cutcount) {
+                printf ("Found %d connect cuts\n", cutcount);
+                fflush (stdout);
+                rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                           &xlist, &x, &newval, tighten);
+                if (rval) {
+                    fprintf (stderr, "call_add_cuts failed\n"); goto CLEANUP;
+                }
+            }
+
+
+            /**** Linear Cuts ****/
+
+
+            tzeit = CCutil_zeit ();
+            rval = CCtsp_segment_cuts (&cuts, &cutcount, lp->graph.ncount,
+                           xcount, xlist, x);
+            if (rval) {
+                fprintf (stderr,  "CCtsp_segment_cuts failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            linsub_zeit += (CCutil_zeit () - tzeit);
+            if (rval) {
+                fprintf (stderr,  "CCtsp_segment_cuts failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            if (cutcount) {
+                printf ("Found %d segment cuts\n", cutcount);
+                fflush (stdout);
+                rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                           &xlist, &x, &newval, tighten);
+                if (rval) {
+                    fprintf (stderr, "call_add_cuts failed\n"); goto CLEANUP;
+                }
+            }
+
+
+            /**** Exact Cuts ****/
+
+
+            tzeit = CCutil_zeit ();
+            rval = CCtsp_exact_subtours (&cuts, &cutcount, lp->graph.ncount,
+                                         xcount, xlist, x);
+            exact_zeit += (CCutil_zeit () - tzeit);
+            if (rval) {
+                fprintf (stderr, "CCtsp_exact_subtours failed\n");
+                rval = 1; goto CLEANUP;
+            }
+            if (cutcount) {
+                printf ("Found %d exact subtours\n", cutcount);
+                fflush (stdout);
+                rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                           &xlist, &x, &newval, tighten);
+                if (rval) {
+                    fprintf (stderr, "call_add_cuts failed\n"); goto CLEANUP;
+                }
+            }
+
+#if 0
+  - this is just to check that the code is finding all cuts
+
+            /**** Old Exact Cuts ****/
+
+
+            if (!cut_added) {
+                rval = Xexactsubtours (&cuts, &cutcount, lp->graph.ncount,
+                                       xcount, xlist, x);
+                if (rval) {
+                    fprintf (stderr, "Xexactsubtours failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+                if (cutcount) {
+                    printf ("Found %d Xexactsubtours\n", cutcount);
+                    fflush (stdout);
+
+                    rval = CCtsp_dump_x (lp, "should.x");
+                    if (rval) {
+                        fprintf (stderr, "CCtsp_dump_x failed\n");
+                        goto CLEANUP;
+                    }
+
+                    rval = call_add_cuts (lp, &cuts, &cut_added, &xcount,
+                               &xlist, &x, &newval, tighten);
+                    if (rval) {
+                        fprintf (stderr, "call_add_cuts failed\n");
+                        goto CLEANUP;
+                    }
+                    fprintf (stderr, "SHOULD NOT FIND XEXACTSUBTOURS\n");
+                    rval = 1; goto CLEANUP;
+                }
+            }
+#endif
+
+            CC_FREE (xlist, int);
+            CC_FREE (x, double);
+
+            if (!cut_added || (inside % CC_SUBTOUR_ROUNDS) == 0) {
+                rval = sparse_edge_check (lp, &eginside, &edge_added,
+                                          (double *) NULL);
+                if (rval) {
+                    fprintf (stderr, "sparse_edge_check failed\n");
+                    rval = 1; goto CLEANUP;
+                }
+            }
+            inside++;
+        } while (edge_added || cut_added);
+
+        rval = full_edge_check (lp, &edge_added);
+        if (rval) {
+            fprintf (stderr, "full_edge_check failed\n");
+            rval = 1; goto CLEANUP;
+        }
+        outside++;
+
+    } while (edge_added);
+
+CLEANUP:
+
+    if (rval == 2) {
+        printf ("LP is infeasible in subtour_loop\n");
+        fflush (stdout);
+    } else if (rval) {
+        fprintf (stderr, "failure in subtour_loop\n");
+    }
+    printf ("Time in cutting routine: %.2f\n", CCutil_zeit () - szeit);
+    printf ("   Connect cuts: %.2f\n", connect_zeit);
+    printf ("   Linear cuts:  %.2f\n", linsub_zeit);
+    printf ("   Exact cuts:   %.2f\n", exact_zeit);
+
+
+    printf ("Number of outside rounds: %d (%d inside)\n", outside, inside);
+    fflush (stdout);
+
+    if (eginside.ncount)
+        CCtsp_free_edgegenerator (&eginside);
+    CC_IFFREE (xlist, int);
+    CC_IFFREE (x, double);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int call_add_cuts (CCtsp_lp *lp, CCtsp_lpcut_in **cuts, int *cut_added,
+        int *xcount, int **xlist, double **x, double *val, int tighten)
+#else
+static int call_add_cuts (lp, cuts, cut_added, xcount, xlist, x, val, tighten)
+CCtsp_lp *lp;
+CCtsp_lpcut_in **cuts;
+int *cut_added;
+int *xcount;
+int **xlist;
+double **x;
+double *val;
+int tighten;
+#endif
+{
+    int rval = 0;
+
+    CC_IFFREE (*xlist, int);
+    CC_IFFREE (*x, double);
+
+    CCtsp_add_cuts_to_queue (lp, cuts);
+    rval = CCtsp_process_cuts (lp, cut_added, tighten);
+    if (rval) {
+        fprintf (stderr, "process_cuts failed\n"); goto CLEANUP;
+    }
+    printf ("Added %d cuts (Total %d)\n", *cut_added, lp->cuts.cutcount);
+    fflush (stdout);
+
+    rval = lp_value (lp, val);
+    if (rval) {
+        fprintf (stderr, "lp_value failed\n"); rval = 1; goto CLEANUP;
+    }
+    printf ("LP Value: %f\n", *val); fflush (stdout);
+
+    rval = lp_x (lp, xcount, xlist, x);
+    if (rval) {
+        fprintf (stderr, "lp_x failed\n"); rval = 1; goto CLEANUP;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lp_value (CCtsp_lp *lp, double *val)
+#else
+static int lp_value (lp, val)
+CCtsp_lp *lp;
+double *val;
+#endif
+{
+    int rval;
+
+    rval = CCtsp_get_lp_result (lp, val, (double *) NULL, (int *) NULL,
+                 (int **) NULL, (double **) NULL, (double **) NULL,
+                 (double **) NULL, (double **) NULL);
+    if (rval) fprintf (stderr, "CCtsp_get_lp_result failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lp_x (CCtsp_lp *lp, int *xcount, int **xlist, double **x)
+#else
+static int lp_x (lp, xcount, xlist, x)
+CCtsp_lp *lp;
+int *xcount;
+int **xlist;
+double **x;
+#endif
+{
+    int rval;
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL, xcount,
+                     xlist, x, (double **) NULL, (double **) NULL,
+                     (double **) NULL);
+    if (rval) fprintf (stderr, "CCtsp_get_lp_result failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_pricing_loop (CCtsp_lp *lp, double *bnd)
+#else
+int CCtsp_pricing_loop (lp, bnd)
+CCtsp_lp *lp;
+double *bnd;
+#endif
+{
+    CCtsp_edgegenerator eg;
+    int nadded;
+    int rval = 0;
+
+    eg.ncount = 0;
+    if (!lp->full_edges_valid) {
+        fprintf (stderr, "CCtsp_pricing_loop called without valid edges\n");
+        rval = 1; goto CLEANUP;
+    }
+
+
+    rval = CCtsp_init_edgegenerator (&eg, lp->graph.ncount, lp->dat,
+                                     lp->fulladj, 0);
+    if (rval) {
+        fprintf (stderr, "CCtsp_init_edgegenerator failed\n"); goto CLEANUP;
+    }
+    rval = sparse_edge_check (lp, &eg, &nadded, bnd);
+    if (rval) {
+        fprintf (stderr, "sparse_edge_check failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    if (eg.ncount) {
+        CCtsp_free_edgegenerator (&eg);
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int full_edge_check (CCtsp_lp *lp, int *nadded)
+#else
+static int full_edge_check (lp, nadded)
+CCtsp_lp *lp;
+int *nadded;
+#endif
+{
+    int rval;
+    CCtsp_edgegenerator eg;
+    double val, penalty;
+
+    if (lp->dat && (!lp->full_edges_valid)) {
+        rval = CCtsp_init_edgegenerator (&eg, lp->graph.ncount, lp->dat,
+                       (CCtsp_genadj *) NULL, CCtsp_PRICE_COMPLETE_GRAPH);
+        if (rval) {
+            fprintf (stderr, "CCtsp_init_edgegenerator failed\n"); return rval;
+        }
+
+        rval = CCtsp_addbad_variables (lp, &eg, &penalty, nadded,
+                  CCtsp_PRICE_RCTHRESH, CCtsp_PRICE_MAXPENALTY, 0, (int *) NULL);
+        if (rval) {
+            fprintf (stderr, "CCtsp_addbad_variables failed\n");
+            CCtsp_free_edgegenerator (&eg);
+            return rval;
+        }
+        CCtsp_free_edgegenerator (&eg);
+        printf ("%d edges added, penalty %f\n", *nadded, penalty);
+        fflush (stdout);
+
+        rval = lp_value (lp, &val);
+        if (rval) return rval;
+
+        if (val + penalty > lp->lowerbound) {
+            printf ("New lower bound: %f\n", val+ penalty);
+            fflush (stdout);
+            lp->lowerbound = val + penalty;
+        }
+    } else {
+        *nadded = 0;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int sparse_edge_check (CCtsp_lp *lp, CCtsp_edgegenerator *eg,
+        int *nadded, double *bnd)
+#else
+static int sparse_edge_check (lp, eg, nadded, bnd)
+CCtsp_lp *lp;
+CCtsp_edgegenerator *eg;
+int *nadded;
+double *bnd;
+#endif
+{
+    double val, penalty;
+    int rval;
+
+    if (bnd) *bnd = -CCtsp_LP_MAXDOUBLE;
+
+    if (eg->ncount > 0) {
+        rval = CCtsp_addbad_variables (lp, eg, &penalty, nadded,
+                CCtsp_PRICE_RCTHRESH, CCtsp_PRICE_MAXPENALTY, 0, (int *) NULL);
+        if (rval) {
+            fprintf (stderr, "CCtsp_addbad_variables failed\n"); return rval;
+        }
+
+        rval = lp_value (lp, &val);
+        if (rval) { fprintf (stderr, "lp_value failed\n"); return rval; }
+
+        printf ("(SPARSE) %d edges added, penalty %f, val %f\n",
+                  *nadded, penalty, val);
+        fflush (stdout);
+
+        if (lp->full_edges_valid) {
+            if (val + penalty > lp->lowerbound) {
+                printf ("New lower bound: %f\n", val + penalty);
+                fflush (stdout);
+                lp->lowerbound = val + penalty;
+            }
+            if (bnd) *bnd = val + penalty;
+        }
+    } else {
+        *nadded = 0;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_bb_cutting (char *probname, int probnum, int ncount, CCdatagroup *dat,
+        int *ptour, double *upbound, CCtsp_lpcuts *pool, CCtsp_cutselect *sel,
+        double *val, int *prune, int *foundtour, int *besttour)
+#else
+int CCtsp_bb_cutting (probname, probnum, ncount, dat, ptour, upbound, pool,
+        sel, val, prune, foundtour, besttour)
+char *probname;
+int probnum;
+int ncount;
+CCdatagroup *dat;
+int *ptour;
+double *upbound;
+CCtsp_lpcuts *pool;
+CCtsp_cutselect *sel;
+double *val;
+int *prune;
+int *foundtour;
+int *besttour;
+#endif
+{
+    int rval = 0;
+    CCtsp_lp *lp = (CCtsp_lp *) NULL;
+    double cval, tourval;
+    int test;
+
+    *val = 0.0;
+    *prune = 0;
+    *foundtour = 0;
+
+    rval = bb_cutting_work (&lp, probname, probnum, ncount, dat, ptour,
+                            *upbound, pool, sel, &cval);
+    if (rval) {
+        fprintf (stderr, "bb_cutting_work failed\n"); fflush (stdout);
+    }
+
+    if (cval == CCtsp_LP_MAXDOUBLE) {
+        rval = CCtsp_verify_infeasible_lp (lp, &test);
+        if (rval) {
+            fprintf (stderr, "CCtsp_verify_infeasible_lp failed\n");
+            goto CLEANUP;
+        }
+        if (test) {
+            printf ("verified infeasible LP\n"); fflush (stdout);
+            *val = CCtsp_LP_MAXDOUBLE;
+            *prune = 1;
+            /* for proof mode, write the lp file here */
+            rval = 0;
+        } else {
+            fprintf (stderr, "did not verify an infeasible LP\n");
+            rval = 1; goto CLEANUP;
+        }
+    } else {
+        rval = CCtsp_pricing_loop (lp, val);
+        if (rval) {
+            fprintf (stderr, "CCtsp_pricing_loop failed\n");
+            rval = 1; goto CLEANUP;
+        }
+        lp->lowerbound = *val;
+        if (lp->upperbound < *upbound) *upbound = lp->upperbound;
+
+        if (lp->lowerbound < lp->upperbound - 0.9) {
+            rval = CCtsp_call_x_heuristic (lp, &tourval, besttour);
+            if (rval) {
+                fprintf (stderr, "CCtsp_call_x_heuristic failed\n");
+                goto CLEANUP;
+            }
+            if (tourval < lp->upperbound) {
+                printf ("New upperbound from x-heuristic: %.2f\n", tourval);
+                lp->upperbound = tourval;
+                *upbound = tourval;
+                *foundtour = 1;
+            }
+        }
+
+        if (lp->lowerbound >= lp->upperbound - 0.9) {
+            rval = CCtsp_verify_lp_prune (lp, &test);
+            if (rval) {
+                fprintf (stderr, "CCtsp_verify_lp_prune failed\n");
+                goto CLEANUP;
+            }
+            if (test) {
+                printf ("verified that LP can be pruned\n"); fflush (stdout);
+                *prune = 1;
+                /* for proof mode, write the lp file here */
+            } else {
+                fprintf (stderr, "exact pricing could not prune the search\n");
+                rval = 1; goto CLEANUP;
+            }
+        } else {
+            rval = CCtsp_write_probfile_id (lp);
+            if (rval) {
+                fprintf (stderr, "CCtsp_write_probfile_id failed\n");
+                goto CLEANUP;
+            }
+        }
+    }
+
+CLEANUP:
+
+    if (lp) CCtsp_free_tsp_lp_struct (&lp);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_call_x_heuristic (CCtsp_lp *lp, double *val, int *outcyc)
+#else
+int CCtsp_call_x_heuristic (lp, val, outcyc)
+CCtsp_lp *lp;
+double *val;
+int *outcyc;
+#endif
+{
+    int rval = 0;
+    int *cyc   = (int *) NULL;
+    int *xlist = (int *) NULL;
+    double *x   = (double *) NULL;
+    int ncount = lp->graph.ncount;
+    int xcount, i;
+
+    *val = CCtsp_LP_MAXDOUBLE;
+
+    if (!lp->dat) goto CLEANUP;
+
+    cyc = CC_SAFE_MALLOC (ncount, int);
+    if (!cyc) {
+        fprintf (stderr, "out of memory for cycle\n");
+        rval = 1; goto CLEANUP;
+    }
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL,
+         &xcount, &xlist, &x, (double **) NULL, (double **) NULL,
+         (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n");
+        goto CLEANUP;
+    }
+
+    rval = CCtsp_x_greedy_tour_lk (lp->dat, ncount, xcount, xlist, x,
+                   cyc, val);
+    if (rval) {
+        fprintf (stderr, "CCtsp_x_greedy_tour_lk failed\n"); goto CLEANUP;
+    }
+    printf ("x-heuristic lk  gives: %.2f\n", *val);
+    if (*val < lp->upperbound) {
+        if (outcyc) {
+            for (i = 0; i < ncount; i++) {
+                outcyc[i] = cyc[i];
+            }
+        }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (cyc, int);
+    CC_IFFREE (xlist, int);
+    CC_IFFREE (x, double);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int bb_cutting_work (CCtsp_lp **lp, char *probname, int probnum,
+        int ncount, CCdatagroup *dat, int *ptour, double initial_ub,
+        CCtsp_lpcuts *pool, CCtsp_cutselect *sel, double *val)
+#else
+static int bb_cutting_work (lp, probname, probnum, ncount, dat, ptour,
+        initial_ub, pool, sel, val)
+CCtsp_lp **lp;
+char *probname;
+int probnum;
+int ncount;
+CCdatagroup *dat;
+int *ptour;
+double initial_ub;
+CCtsp_lpcuts *pool;
+CCtsp_cutselect *sel;
+double *val;
+#endif
+{
+    int rval = 0;
+
+    *lp = (CCtsp_lp *) NULL;
+    *val = 0.0;
+
+    rval = CCtsp_bb_init_lp (lp, probname, probnum, ncount, dat, ptour,
+               initial_ub, pool);
+    if (rval == 2) {
+        printf ("LP is reported to be infeasible\n"); fflush (stdout);
+        *val = CCtsp_LP_MAXDOUBLE;
+        rval = 0; goto CLEANUP;
+    } else if (rval) {
+        fprintf (stderr, "CCtsp_init_lp failed\n"); goto CLEANUP;
+    }
+
+    if ((*lp)->lowerbound >= (*lp)->upperbound - 0.9) {
+        printf ("Do not cut, the lp is within 1.0 of the upperbound\n");
+        fflush (stdout);
+        *val = (*lp)->lowerbound;
+        goto CLEANUP;
+    } else {
+        rval = CCtsp_cutting_loop (*lp, sel, 0);
+        if (rval == 2) {
+            printf ("Cut LP is reported to be infeasible\n"); fflush (stdout);
+        } else if (rval) {
+            fprintf (stderr, "CCtsp_cutting_loop failed\n"); goto CLEANUP;
+        } else {
+            *val = (*lp)->lowerbound;
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/TSP/cutcall.c b/contrib/blossom/concorde97/TSP/cutcall.c
new file mode 100644
index 0000000000000000000000000000000000000000..63f8b25f8a21bdda7f597fd3bd82b238e275d576
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/cutcall.c
@@ -0,0 +1,1890 @@
+/***************************************************************************/
+/*                                                                         */
+/*                    Interface to the Cutters                             */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 17, 1997                                                */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_connect_cuts (CCtsp_lpcut_in **cuts, int *cutcount,        */
+/*            int ncount, int ecount, int *elist, double *x)               */
+/*     FINDS violated subtour inequalities via connectivity.               */
+/*      -cuts will return any new cuts found (they will be added to the    */
+/*       head of the linked list)                                          */
+/*      -cutcount will return the number of new cuts added                 */
+/*      -ncount is the number of nodes                                     */
+/*      -ecount is the number of edges                                     */
+/*      -elist contains the LP edges in node node format                   */
+/*      -x is an LP solution                                               */
+/*                                                                         */
+/*    int CCtsp_segment_cuts (CCtsp_lpcut_in **cuts, int *cutcount,        */
+/*            int ncount, int ecount, int *elist, double *x)               */
+/*     FINDS violated subtour inequalities via linsub.                     */
+/*                                                                         */
+/*    int CCtsp_exact_subtours (CCtsp_lpcut_in **cuts, int *cutcount,      */
+/*            int ncount, int ecount, int *elist, double *x)               */
+/*     FINDS violated subtour inequalities via a mincut algorithm.         */
+/*                                                                         */
+/*    int CCtsp_tighten_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats, */
+/*            CCtsp_lpcut_in **cutsout, int *cutcount, int ncount,         */
+/*            int ecount,  int *elist, double *x, double testtol,          */
+/*            int maxcuts)                                                 */
+/*     CALLS tighten for each cut in the cuts.                             */
+/*      -stats contains some running statistics of tighten                 */
+/*      -cutsout returns the tightened cuts that are violated (they are    */
+/*       added to the head of the linked list)                             */
+/*      -cutcount is the number of cuts in cutsout                         */
+/*      -testtol is a tolerance for calling tighten (call only when the    */
+/*       cut has slack value within testtol)                               */
+/*      -maxcuts is a bound on the number of cuts to be returned           */
+/*                                                                         */
+/*    void CCtsp_init_lpcut_in (CCtsp_lpcut_in *c)                         */
+/*     INITIALIZE the fields of the CCtsp_lpcut_in structure               */
+/*                                                                         */
+/*    int CCtsp_segment_to_subtour (CCtsp_lpcut_in **cut, int a, int b)    */
+/*     BUILDS a subtour CCtsp_lpcut_in from an the segment.                */
+/*      -cut will return the subtour (it will be allocated).               */
+/*                                                                         */
+/*    int CCtsp_array_to_subtour (CCtsp_lpcut_in **cut, int *ar,           */
+/*            int acount)                                                  */
+/*     BUILDS a subtour CCtsp_lpcut_in from an array.                      */
+/*      -cut will return the subtour (it will be allocated).               */
+/*                                                                         */
+/*    void CCtsp_init_lpclique (CCtsp_lpclique *c)                         */
+/*     INITIALIZE the fields of the CCtsp_lpclique structure               */
+/*                                                                         */
+/*    int CCtsp_array_to_lpclique (int *ar, int acount,                    */
+/*            CCtsp_lpclique *cliq)                                        */
+/*     BUILDS an CCtsp_lpclique represented the nodes in an array.         */
+/*      -ar is an array of node numbers                                    */
+/*      -acount is the length of ar                                        */
+/*      -cliq's segcount and nodes will be filled with the compressed      */
+/*       version of the nodes in ar                                        */
+/*                                                                         */
+/*    int CCtsp_seglist_to_lpclique (int nseg, int *list,                  */
+/*            CCtsp_lpclique *cliq)                                        */
+/*     BUILDS the CCtsp_lpclique represented by a list of CCtsp_segments   */
+/*     (it will sort the CCtsp_segments before it puts them into the       */
+/*     CCtsp_segment structures)                                           */
+/*      -list is an array of CCtsp_segments in lo-hi-lo-hi format          */
+/*      -clig's segcount and nodes will be filled in (nodes will be        */
+/*       allocated)                                                        */
+/*                                                                         */
+/*    int CCtsp_add_node_to_lpclique (CCtsp_lpclique *cin,                 */
+/*            CCtsp_lpclique *cout, int n)                                 */
+/*     ADDS node n to clique cin, and returns the new clique in cout       */
+/*                                                                         */
+/*    int CCtsp_delete_node_from_lpclique (CCtsp_lpclique *cin,      */
+/*            CCtsp_lpclique *cout, int n)                                 */
+/*     DELETES node n from clique cin, and returns the new clique in cout  */
+/*                                                                         */
+/*    void CCtsp_print_lpcut_in (CCtsp_lpcut_in *c)                  */
+/*     PRINTS the CCtsp_lpcut_in                                           */
+/*                                                                         */
+/*    void CCtsp_print_lpclique (CCtsp_lpclique *c)                  */
+/*     PRINTS the CCtsp_segments in the clique to stdout.                  */
+/*                                                                         */
+/*    int CCtsp_copy_lpcut_in (CCtsp_lpcut_in *c,                    */
+/*            CCtsp_lpcut_in *new)                                         */
+/*     COPIES an CCtsp_lpcut_in                                            */
+/*      -c is a pointer to an CCtsp_lpcut_in                               */
+/*      -new returns the copied CCtsp_lpcut                                */
+/*                                                                         */
+/*    int CCtsp_lpcut_to_lpcut_in (CCtsp_lpcuts *cuts,                     */
+/*            CCtsp_lpcut *c, CCtsp_lpcut_in *new)                         */
+/*     COPIES an CCtsp_lpcut to an CCtsp_lpcut_in                          */
+/*      -cuts is a pointer to the structure holding the set of cuts        */
+/*      -c is the cut to be copied                                         */
+/*      -new returns the copied cut                                        */
+/*                                                                         */
+/*    void CCtsp_lpclique_compare (CCtsp_lpclique *a,                      */
+/*            CCtsp_lpclique *b, int *diff)                                */
+/*     COMPARES two CCtsp_lpcliques.                                       */
+/*      -diff is set to 1 if they differ and 0 if they are the same        */
+/*       Note: Assumes CCtsp_segments are ordered.                         */
+/*                                                                         */
+/*    int CCtsp_copy_lpclique (CCtsp_lpclique *c,                    */
+/*            CCtsp_lpclique *new)                                         */
+/*     COPIES an CCtsp_lpclique                                            */
+/*      -c is a pointer to an CCtsp_lpclique                               */
+/*      -new returns the copied clique                                     */
+/*                                                                         */
+/*    int CCtsp_file_cuts (char *cutfile, CCtsp_lpcut_in **cuts,           */
+/*            int *cutcount, int ncount, int *tour)                        */
+/*     READS a set of cuts from a file; the format of the cuts can be      */
+/*      found by examining the code                                        */
+/*      -cutfile is an asci file with a list of cuts                       */
+/*      -cuts will return any new cuts found (they will be added to the    */
+/*       head of the linked list)                                          */
+/*      -cutcount with return the number of new cuts added                 */
+/*      -ncount is the number of nodes                                     */
+/*      -tour the permutation tour (used to map the incoming nodes)        */
+/*                                                                         */
+/*    int CCtsp_file_cuts_write (char *cutfile, CCtsp_lpcuts *cuts,        */
+/*            int *tour)                                                   */
+/*     WRITES a set of cuts in a text file that can be read by             */
+/*      tsp_file_cuts                                                      */
+/*      -cutfile is the name of the file to be written                     */
+/*      -cuts is the set of cuts to be written                             */
+/*      -tour is a permutation tour (used to map the outgoing nodes)       */
+/*                                                                         */
+/*    int CCtsp_test_pure_comb (int ncount, CCtsp_lpcut_in *c, int *yes_no,*/
+/*           int *handle)                                                  */
+/*     TEST if the cut is a comb (without flipped teeth or intersections)  */
+/*      -ncount is the number of nodes in the TSP                          */
+/*      -yes_no will be set to either 0 or 1, with 1 meaning yes           */
+/*      -handle with return the index of the handle if the cut is a comb   */
+/*       (handle can be NULL)                                              */
+/*                                                                         */
+/*    int CCtsp_test_pseudocomb (int ncount, CCtsp_lpcut_in *c, int handle,*/
+/*           int *yes_no)                                                  */
+/*     TEST if the cut is a pseudocomb.                                    */
+/*      -handle gives the index of the handle of the pseudocomb            */
+/*                                                                         */
+/*    int CCtsp_test_teeth_disjoint (int ncount, CCtsp_lpcut_in *c,        */
+/*       int handle, int *yes_no)                                          */
+/*     TEST if the cliques other than handle are pairwise disjoint.        */
+/*      -yes_no is 1 if disjoint and 0 otherwise.                          */
+/*                                                                         */
+/*    int CCtsp_find_pure_handle (int ncount, CCtsp_lpcut_in *c,           */
+/*            int *handle)                                                 */
+/*     FINDS a clique that is c's handle if c is a comb; the search        */
+/*      assumes that the teeth are disjoint, so if the comb has            */
+/*      extra intersections then a tooth may be returned.                  */
+/*      -handle returns the potential handle (it will return -1 if no      */
+/*       clique is a potential handle)                                     */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "macrorus.h"
+#include "util.h"
+#include "tsp.h"
+#include "cut.h"
+
+#define X_FLUFF (1e-10)
+#undef  DUMP_BUILDCUT
+
+typedef struct exactsub_param {
+    int cutcount;
+    CCtsp_lpcut_in *cuts;
+} exactsub_param;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    add_segment (double val, int a, int b, void *pass_param),
+    add_exact (double val, int count, int *cutarray, void *pass_param),
+    work_on_combs_in_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+        CCtsp_lpcut_in **cutsout,
+        int *cutcount, int ncount, int ecount, int *elist, double *x,
+        double testtol, int maxcuts,
+        int (*doit_fn) (CCtsp_lpgraph *, double *, CCtsp_lpcut_in *,
+        CCtsp_lpcut_in **)),
+    grab_nonzero_x (int ecount, int *elist, double *x, int *new_ecount,
+        int **new_elist, double **new_x, double tol);
+
+#else
+
+static int
+    add_segment (),
+    add_exact (),
+    work_on_combs_in_lp (),
+    grab_nonzero_x ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_connect_cuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+         int ecount, int *elist, double *x)
+#else
+int CCtsp_connect_cuts (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount, ecount;
+int *elist;
+double *x;
+#endif
+{
+    int rval;
+    int i, k, ncomp;
+    CCtsp_lpcut_in *c     = (CCtsp_lpcut_in *) NULL;
+    int *comps      = (int *) NULL;
+    int *compscount = (int *) NULL;
+
+    *cutcount = 0;
+    rval = CCcut_connect_components (ncount, ecount, elist, x, &ncomp,
+                                   &compscount, &comps);
+    if (rval) {
+        fprintf (stderr, "CCcut_connect_components failed\n"); goto CLEANUP;
+    }
+
+    for (i = 0, k = 0; i < ncomp - 1; k += compscount[i], i++) {
+        rval = CCtsp_array_to_subtour (&c, comps + k, compscount[i]);
+        if (rval) {
+            fprintf (stderr, "CCtsp_array_to_subtour failed\n");
+            rval = 1; goto CLEANUP;
+        }
+        c->next = *cuts;
+        *cuts = c;
+        (*cutcount)++;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (comps, int);
+    CC_IFFREE (compscount, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_segment_cuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+        int ecount, int *elist, double *x)
+#else
+int CCtsp_segment_cuts (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount, ecount;
+int *elist;
+double *x;
+#endif
+{
+    int rval = 0;
+    exactsub_param p;
+    double szeit = CCutil_zeit ();
+
+    *cutcount = 0;
+
+    p.cutcount = 0;
+    p.cuts = *cuts;
+
+    rval = CCcut_linsub (ncount, ecount, elist, x, 2.0 - 0.0001,
+                         add_segment, (void *) &p);
+    if (rval) {
+        fprintf (stderr, "CCcut_linsub failed\n"); goto CLEANUP;
+    }
+
+    *cutcount = p.cutcount;
+    *cuts = p.cuts;
+
+    printf ("DONE (found %d segment cuts in %.2f seconds)\n", *cutcount,
+                                                 CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    return rval;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_exact_subtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+        int ecount, int *elist, double *x)
+#else
+int CCtsp_exact_subtours (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount, ecount;
+int *elist;
+double *x;
+#endif
+{
+    int rval = 0;
+    exactsub_param p;
+    double szeit = CCutil_zeit ();
+
+
+    printf ("exact_subtours ... \n"); fflush (stdout);
+    *cutcount = 0;
+    rval = CCtsp_connect_cuts (cuts, cutcount, ncount, ecount, elist, x);
+    if (rval) {
+        fprintf (stderr, "CCtsp_connect_cuts failed\n"); goto CLEANUP;
+    }
+
+    if (*cutcount > 0) {
+        fprintf (stderr, "found connect cuts, do not call exact cut routine\n");
+        rval = 0; goto CLEANUP;
+    }
+
+    p.cutcount = 0;
+    p.cuts = *cuts;
+
+    rval = CCcut_violated_cuts (ncount, ecount, elist, x, 2.0 - 0.0001,
+                       add_exact, (void *) &p);
+    if (rval) {
+        fprintf (stderr, "CCcut_violated_cuts failed\n"); goto CLEANUP;
+    }
+
+    *cutcount = p.cutcount;
+    *cuts = p.cuts;
+
+    printf ("DONE (found %d cuts in %.2f seconds)\n", *cutcount,
+                                                   CCutil_zeit () - szeit);
+    fflush (stdout);
+
+#if 0
+  - this is just to check the values of the exact cuts
+    if (*cutcount) {
+        CCtsp_lpgraph lg;
+        CCtsp_lpcut_in *c;
+        double t;
+
+        CCtsp_init_lpgraph_struct (&lg);
+
+        rval = CCtsp_build_lpgraph (&lg, ncount, ecount, elist, (int *) NULL);
+        if (rval) {
+            fprintf (stderr, "CCtsp_build_lpgraph failed\n"); goto CLEANUP;
+        }
+        rval = CCtsp_build_lpadj (&lg, 0, ecount);
+        if (rval) {
+            CCtsp_free_lpgraph (&lg);
+            fprintf (stderr, "CCtsp_build_lpadj failed\n"); goto CLEANUP;
+        }
+        for (c = p.cuts; c; c = c->next) {
+            t = CCtsp_cutprice (&lg, c, x);
+            printf ("[%f] ", 2.0 + t); fflush (stdout);
+        }
+        printf ("\n"); fflush (stdout);
+        CCtsp_free_lpgraph (&lg);
+    }
+#endif
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_segment (double val, int a, int b, void *pass_param)
+#else
+static int add_segment (val, a, b, pass_param)
+double val;
+int a, b;
+void *pass_param;
+#endif
+{
+    int rval = 0;
+    exactsub_param *p = (exactsub_param *) pass_param;
+    CCtsp_lpcut_in *c = (CCtsp_lpcut_in *) NULL;
+
+    if (val > 2.0) {
+        printf ("Warning: Cut of value %f in add_segment\n", val);
+        fflush (stdout);
+        goto CLEANUP;
+    }
+
+    rval = CCtsp_segment_to_subtour (&c, a, b);
+    if (rval) {
+        fprintf (stderr, "CCtsp_array_to_subtour failed\n");
+        rval = 1; goto CLEANUP;
+    }
+    c->next = p->cuts;
+    p->cuts = c;
+    p->cutcount++;
+
+CLEANUP:
+
+    return rval;
+}
+#ifdef CC_PROTOTYPE_ANSI
+static int add_exact (double val, int count, int *cutarray, void *pass_param)
+#else
+static int add_exact (val, count, cutarray, pass_param)
+double val;
+int count;
+int *cutarray;
+void *pass_param;
+#endif
+{
+    int rval = 0;
+    exactsub_param *p = (exactsub_param *) pass_param;
+    CCtsp_lpcut_in *c = (CCtsp_lpcut_in *) NULL;
+
+    if (val > 2.0) {
+        printf ("Warning: Cut of value %f in add_exact\n", val);
+        fflush (stdout);
+        goto CLEANUP;
+    }
+
+    rval = CCtsp_array_to_subtour (&c, cutarray, count);
+    if (rval) {
+        fprintf (stderr, "CCtsp_array_to_subtour failed\n");
+        rval = 1; goto CLEANUP;
+    }
+    c->next = p->cuts;
+    p->cuts = c;
+    p->cutcount++;
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_tighten_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+        CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+        int *elist, double *x, double testtol, int maxcuts)
+#else
+int CCtsp_tighten_lp (cuts, stats, cutsout, cutcount, ncount, ecount, elist, x,
+        testtol, maxcuts)
+CCtsp_lpcuts *cuts;
+CCtsp_tighten_info *stats;
+CCtsp_lpcut_in **cutsout;
+int *cutcount;
+int ncount, ecount;
+int *elist;
+double *x;
+double testtol;
+int maxcuts;
+#endif
+{
+    CCtsp_lpcut_in new, old;
+    CCtsp_lpcut_in *c;
+    int i;
+    int rval = 0;
+    double improve;
+    CCtsp_lpgraph lg;
+    double *newx = (double *) NULL;
+    int *newelist = (int *) NULL;
+    int newecount;
+    CCtsp_lpcut_in **clist = (CCtsp_lpcut_in **) NULL;
+    double *vlist = (double *) NULL;
+    double maxviol = 0.0;
+    int clistsize = 0, vlistsize = 0;
+    int count = 0;
+    int *perm = (int *) NULL;
+    double szeit = CCutil_zeit ();
+    double *cutval = (double *) NULL;
+
+    *cutcount = 0;
+    if (!cuts || !cuts->cutcount) return 0;
+
+
+    rval = grab_nonzero_x (ecount, elist, x, &newecount, &newelist, &newx,
+                           X_FLUFF);
+    if (rval) {
+        fprintf (stderr, "grab_nonzero_x failed\n"); goto CLEANUP;
+    }
+
+    cutval = CC_SAFE_MALLOC (cuts->cutcount, double);
+    if (!cutval) {
+        fprintf (stderr, "out of memory in CCtsp_tighten_lp\n");
+        rval = 1; goto CLEANUP;
+    }
+    rval = CCtsp_price_cuts (cuts, ncount, newecount, newelist, newx, cutval);
+    if (rval) {
+        fprintf (stderr, "CCtsp_price_cuts failed\n"); goto CLEANUP;
+    }
+
+    CCtsp_init_lpgraph_struct (&lg);
+
+    rval = CCtsp_build_lpgraph (&lg, ncount, newecount, newelist, (int *) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_build_lpgraph failed\n"); goto CLEANUP;
+    }
+    CC_FREE (newelist, int);
+    rval = CCtsp_build_lpadj (&lg, 0, newecount);
+    if (rval) {
+        fprintf (stderr, "CCtsp_build_lpadj failed\n"); goto CLEANUP;
+    }
+
+    for (i = 0; i < cuts->cutcount; i++) {
+        if (cutval[i] < testtol && !cuts->cuts[i].branch) {
+            rval = CCtsp_lpcut_to_lpcut_in (cuts, &(cuts->cuts[i]), &old);
+            if (rval) {
+                fprintf (stderr, "CCtsp_lpcut_to_lpcut_in failed\n");
+                goto CLEANUP;
+            }
+            rval = CCtsp_tighten_lpcut_in (&lg, &old, newx, &new, stats,
+                                           &improve);
+            if (rval) {
+                fprintf (stderr, "CCtsp_tighten_lpcut failed\n");
+                goto CLEANUP;
+            }
+            CCtsp_free_lpcut_in (&old);
+
+            if (improve - cutval[i] > CCtsp_MIN_VIOL) {
+                c = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+                if (!c) {
+                    fprintf (stderr, "out of memory in CCtsp_tighten_lp\n");
+                    rval = 1; goto CLEANUP;
+                }
+                *c = new;
+                if (count >= clistsize) {
+                    rval = CCutil_reallocrus_scale ((void **) &clist,
+                                    &clistsize,
+                                    count + 1, 1.3, sizeof (CCtsp_lpcut_in *));
+                    if (rval) {
+                        fprintf (stderr, "CCutil_reallocrus_scale failed\n");
+                        rval = 1; goto CLEANUP;
+                    }
+                }
+                if (count >= vlistsize) {
+                    rval = CCutil_reallocrus_scale ((void **) &vlist,
+                                    &vlistsize,
+                                    count + 1, 1.3, sizeof (double));
+                    if (rval) {
+                        fprintf (stderr, "CCutil_reallocrus_scale failed\n");
+                        rval = 1; goto CLEANUP;
+                    }
+                }
+                clist[count] = c;
+                vlist[count] = cutval[i] - improve;
+                count++;
+            } else {
+                CCtsp_free_lpcut_in (&new);
+            }
+        }
+    }
+
+    if (count) {
+        perm = CC_SAFE_MALLOC (count, int);
+        if (!perm) {
+            fprintf (stderr, "out of memory in CCtsp_tighten_lp\n");
+            rval = 1; goto CLEANUP;
+        }
+        for (i = 0; i < count; i++) {
+            perm[i] = i;
+        }
+        if (count > maxcuts) {
+            CCutil_rselect (perm, 0, count - 1, maxcuts, vlist);
+            for (i = maxcuts; i < count; i++) {
+                CCtsp_free_lpcut_in (clist[perm[i]]);
+            }
+            count = maxcuts;
+        }
+        for (i = 0; i < count; i++) {
+            if (vlist[perm[i]] < maxviol)
+                maxviol = vlist[perm[i]];
+            clist[perm[i]]->next = *cutsout;
+            *cutsout = clist[perm[i]];
+        }
+    }
+
+    *cutcount = count;
+    printf ("%d tighten cuts, %.5f max violation (%.2f seconds)\n",
+                  count, -maxviol, CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (newelist, int);
+    CC_IFFREE (newx, double);
+    CC_IFFREE (clist, CCtsp_lpcut_in *);
+    CC_IFFREE (vlist, double);
+    CC_IFFREE (perm, int);
+    CC_IFFREE (cutval, double);
+    CCtsp_free_lpgraph (&lg);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_teething_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+        CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+        int *elist, double *x, double testtol, int maxcuts)
+#else
+int CCtsp_teething_lp (cuts, stats, cutsout, cutcount, ncount, ecount,
+        elist, x, testtol, maxcuts)
+CCtsp_lpcuts *cuts;
+CCtsp_tighten_info *stats;
+CCtsp_lpcut_in **cutsout;
+int *cutcount;
+int ncount, ecount;
+int *elist;
+double *x;
+double testtol;
+int maxcuts;
+#endif
+{
+    int rval = 0;
+
+    rval = work_on_combs_in_lp (cuts, stats, cutsout, cutcount, ncount, ecount,
+                                elist, x, testtol, maxcuts,
+                                CCtsp_teething);
+    if (rval) {
+        fprintf (stderr, "work_on_combs_in_lp failed\n");
+        goto CLEANUP;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int work_on_combs_in_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+        CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+        int *elist, double *x, double testtol, int maxcuts,
+        int (*doit_fn) (CCtsp_lpgraph *, double *, CCtsp_lpcut_in *,
+        CCtsp_lpcut_in **))
+#else
+static int work_on_combs_in_lp (cuts, stats, cutsout, cutcount, ncount, ecount,
+        elist, x, testtol, maxcuts, doit_fn)
+CCtsp_lpcuts *cuts;
+CCtsp_tighten_info *stats;
+CCtsp_lpcut_in **cutsout;
+int *cutcount;
+int ncount, ecount;
+int *elist;
+double *x;
+double testtol;
+int maxcuts;
+int (*doit_fn) ();
+#endif
+{
+    CCtsp_lpcut_in new, old;
+    CCtsp_lpcut_in *c  = (CCtsp_lpcut_in *) NULL;
+    CCtsp_lpcut_in *dd = (CCtsp_lpcut_in *) NULL;
+    int i, test;
+    int rval = 0;
+    double improve, newslack;
+    CCtsp_lpgraph lg;
+    double *newx = (double *) NULL;
+    int *newelist = (int *) NULL;
+    int newecount;
+    CCtsp_lpcut_in **clist = (CCtsp_lpcut_in **) NULL;
+    double *vlist = (double *) NULL;
+    double maxviol = 0.0;
+    int clistsize = 0, vlistsize = 0;
+    int count = 0;
+    int *perm = (int *) NULL;
+    double *cutval = (double *) NULL;
+    double szeit = CCutil_zeit ();
+
+    *cutcount = 0;
+    if (!cuts || !cuts->cutcount) return 0;
+
+    rval = grab_nonzero_x (ecount, elist, x, &newecount, &newelist, &newx,
+                           X_FLUFF);
+    if (rval) {
+        fprintf (stderr, "grab_nonzero_x failed\n"); goto CLEANUP;
+    }
+
+    cutval = CC_SAFE_MALLOC (cuts->cutcount, double);
+    if (!cutval) {
+        fprintf (stderr, "out of memory in CCtsp_tighten_lp\n");
+        rval = 1; goto CLEANUP;
+    }
+    rval = CCtsp_price_cuts (cuts, ncount, newecount, newelist, newx, cutval);
+    if (rval) {
+        fprintf (stderr, "CCtsp_price_cuts failed\n"); goto CLEANUP;
+    }
+
+    CCtsp_init_lpgraph_struct (&lg);
+    rval = CCtsp_build_lpgraph (&lg, ncount, newecount, newelist, (int *) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_build_lpgraph failed\n"); goto CLEANUP;
+    }
+    CC_FREE (newelist, int);
+    rval = CCtsp_build_lpadj (&lg, 0, newecount);
+    if (rval) {
+        fprintf (stderr, "CCtsp_build_lpadj failed\n"); goto CLEANUP;
+    }
+
+    for (i = 0; i < cuts->cutcount; i++) {
+        if (cuts->cuts[i].branch || cuts->cuts[i].cliquecount % 2 ||
+            cuts->cuts[i].cliquecount < 4 || cutval[i] >= testtol) {
+            continue;
+        }
+        rval = CCtsp_lpcut_to_lpcut_in (cuts, &(cuts->cuts[i]), &old);
+        if (rval) {
+            fprintf (stderr, "CCtsp_lpcut_to_lpcut_in failed\n"); goto CLEANUP;
+        }
+        rval = CCtsp_test_pure_comb (ncount, &old, &test, (int *) NULL);
+        if (rval) {
+            fprintf (stderr, "CCtsp_test_pure_comb failed\n");
+            CCtsp_free_lpcut_in (&old);
+            goto CLEANUP;
+        }
+        if (test == 1) {
+            rval = doit_fn (&lg, newx, &old, &dd);
+            if (rval) {
+                fprintf (stderr, "doit_fn failed\n"); goto CLEANUP;
+            }
+            CCtsp_free_lpcut_in (&old);
+            if (dd) {
+                rval = CCtsp_tighten_lpcut_in (&lg, dd, newx, &new,
+                                               stats, &improve);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_tighten_lpcut failed\n");
+                    goto CLEANUP;
+                }
+                CCtsp_free_lpcut_in (dd);
+                CC_FREE (dd, CCtsp_lpcut_in);
+
+                newslack = CCtsp_cutprice (&lg, &new, newx);
+                if (-newslack > CCtsp_MIN_VIOL) {
+                    c = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+                    if (!c) {
+                        fprintf (stderr,
+                           "out of memory in work_on_combs_in_lp\n");
+                        CCtsp_free_lpcut_in (&new);
+                        rval = 1; goto CLEANUP;
+                    }
+                    *c = new;
+                    if (count >= clistsize) {
+                        rval = CCutil_reallocrus_scale ((void **) &clist,
+                                &clistsize, count + 1, 1.3,
+                                sizeof (CCtsp_lpcut_in *));
+                        if (rval) {
+                            fprintf (stderr,
+                                  "CCutil_reallocrus_scale failed\n");
+                            rval = 1; goto CLEANUP;
+                        }
+                    }
+                    if (count >= vlistsize) {
+                        rval = CCutil_reallocrus_scale ((void **) &vlist,
+                                 &vlistsize, count + 1, 1.3,
+                                 sizeof (double));
+                        if (rval) {
+                            fprintf (stderr,
+                                  "CCutil_reallocrus_scale failed\n");
+                            rval = 1; goto CLEANUP;
+                        }
+                    }
+                    clist[count] = c;
+                    vlist[count] = newslack;
+                    count++;
+                } else {
+                    CCtsp_free_lpcut_in (&new);
+                }
+            }
+        } else {
+            CCtsp_free_lpcut_in (&old);
+        }
+    }
+
+    if (count) {
+        perm = CC_SAFE_MALLOC (count, int);
+        if (!perm) {
+            fprintf (stderr, "out of memory in work_on_combs_in_lp\n");
+            rval = 1; goto CLEANUP;
+        }
+        for (i = 0; i < count; i++) {
+            perm[i] = i;
+        }
+        if (count > maxcuts) {
+            CCutil_rselect (perm, 0, count - 1, maxcuts, vlist);
+            for (i = maxcuts; i < count; i++) {
+                CCtsp_free_lpcut_in (clist[perm[i]]);
+            }
+            count = maxcuts;
+        }
+        for (i = 0; i < count; i++) {
+            if (vlist[perm[i]] < maxviol)
+                maxviol = vlist[perm[i]];
+            clist[perm[i]]->next = *cutsout;
+            *cutsout = clist[perm[i]];
+        }
+    }
+
+    *cutcount = count;
+    printf ("%d cuts, %.5f max violation (%.2f seconds)\n", count, -maxviol,
+                         CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (newelist, int);
+    CC_IFFREE (newx, double);
+    CC_IFFREE (clist, CCtsp_lpcut_in *);
+    CC_IFFREE (vlist, double);
+    CC_IFFREE (perm, int);
+    CC_IFFREE (cutval, double);
+    CCtsp_free_lpgraph (&lg);
+    if (dd) {
+        CCtsp_free_lpcut_in (dd);
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_init_lpcut_in (CCtsp_lpcut_in *c)
+#else
+void CCtsp_init_lpcut_in (c)
+CCtsp_lpcut_in *c;
+#endif
+{
+    if (c) {
+        c->handlecount = 0;
+        c->cliquecount = 0;
+        c->rhs         = 0;
+        c->sense       = 'X';
+        c->branch      = 0;
+        c->cliques     = (CCtsp_lpclique *) NULL;
+        c->next        = (CCtsp_lpcut_in *) NULL;
+        c->prev        = (CCtsp_lpcut_in *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_copy_lpcut_in (CCtsp_lpcut_in *c, CCtsp_lpcut_in *new)
+#else
+int CCtsp_copy_lpcut_in (c, new)
+CCtsp_lpcut_in *c;
+CCtsp_lpcut_in *new;
+#endif
+{
+    int rval = 0;
+    int i;
+
+    CCtsp_init_lpcut_in (new);
+
+    new->handlecount = c->handlecount;
+    new->cliquecount = c->cliquecount;
+    new->rhs         = c->rhs;
+    new->sense       = c->sense;
+
+    if (c->cliquecount) {
+        new->cliques = CC_SAFE_MALLOC (c->cliquecount, CCtsp_lpclique);
+        if (!new->cliques) {
+            fprintf (stderr, "out of memory in CCtsp_copy_lpcut_in\n");
+            rval = 1; goto CLEANUP;
+        }
+        for (i = 0; i < c->cliquecount; i++) {
+            rval = CCtsp_copy_lpclique (&c->cliques[i], &new->cliques[i]);
+            if (rval) {
+                fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+                goto CLEANUP;
+            }
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_segment_to_subtour (CCtsp_lpcut_in **cut, int a, int b)
+#else
+int CCtsp_segment_to_subtour (cut, a, b)
+CCtsp_lpcut_in **cut;
+int a, b;
+#endif
+{
+    int rval = 0;
+    int list[2];
+    int t;
+    CCtsp_lpcut_in *c = (CCtsp_lpcut_in *) NULL;
+
+    *cut = (CCtsp_lpcut_in *) NULL;
+    if (a > b) CC_SWAP (a, b, t);
+
+    c = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+    if (!c) {
+        fprintf (stderr, "out of memory in CCtsp_segment_to_subtour\n");
+        rval = 1; goto CLEANUP;
+    }
+    CCtsp_init_lpcut_in (c);
+
+    c->cliquecount = 1;
+    c->handlecount = 0;
+    c->cliques = CC_SAFE_MALLOC (1, CCtsp_lpclique);
+    if (!c->cliques) {
+        fprintf (stderr, "out of memory in CCtsp_segment_to_subtour\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    list[0] = a;
+    list[1] = b;
+    rval = CCtsp_seglist_to_lpclique (1, list, &(c->cliques[0]));
+    if (rval) {
+        goto CLEANUP;
+    }
+    c->rhs = CCtsp_CUTRHS(c);
+    c->sense = 'G';
+    c->branch = 0;
+
+    *cut = c;
+
+CLEANUP:
+
+    if (rval) {
+        if (c) {
+            CCtsp_free_lpcut_in (c);
+            CC_FREE (c, CCtsp_lpcut_in);
+        }
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_array_to_subtour (CCtsp_lpcut_in **cut, int *ar, int acount)
+#else
+int CCtsp_array_to_subtour (cut, ar, acount)
+CCtsp_lpcut_in **cut;
+int *ar;
+int acount;
+#endif
+{
+    int rval = 0;
+    CCtsp_lpcut_in *c = (CCtsp_lpcut_in *) NULL;
+
+    *cut = (CCtsp_lpcut_in *) NULL;
+
+    c = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+    if (!c) {
+        fprintf (stderr, "out of memory in CCtsp_array_to_subtour\n");
+        rval = 1; goto CLEANUP;
+    }
+    CCtsp_init_lpcut_in (c);
+
+    c->cliquecount = 1;
+    c->handlecount = 0;
+    c->cliques = CC_SAFE_MALLOC (1, CCtsp_lpclique);
+    if (!c->cliques) {
+        fprintf (stderr, "out of memory in CCtsp_array_to_subtour\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_array_to_lpclique (ar, acount, &(c->cliques[0]));
+    if (rval) {
+        goto CLEANUP;
+    }
+    c->rhs = CCtsp_CUTRHS(c);
+    c->sense = 'G';
+    c->branch = 0;
+
+    *cut = c;
+
+CLEANUP:
+
+    if (rval) {
+        if (c) {
+            CCtsp_free_lpcut_in (c);
+            CC_FREE (c, CCtsp_lpcut_in);
+        }
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_init_lpclique (CCtsp_lpclique *c)
+#else
+void CCtsp_init_lpclique (c)
+CCtsp_lpclique *c;
+#endif
+{
+    if (c) {
+        c->segcount = 0;
+        c->nodes = (CCtsp_segment *) NULL;
+        c->hashnext = 0;
+        c->refcount = 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_array_to_lpclique (int *ar, int acount, CCtsp_lpclique *cliq)
+#else
+int CCtsp_array_to_lpclique (ar, acount, cliq)
+int *ar;
+int acount;
+CCtsp_lpclique *cliq;
+#endif
+{
+    int i, nseg;
+
+    /* Function will alter the order on the array */
+
+    CCutil_int_array_quicksort (ar, acount);
+    nseg = 0;
+    i = 0;
+    while (i < acount) {
+        while (i < (acount - 1) && ar[i + 1] == (ar[i] + 1))
+            i++;
+        i++;
+        nseg++;
+    }
+
+    cliq->nodes = CC_SAFE_MALLOC (nseg, CCtsp_segment);
+    if (!cliq->nodes) {
+        fprintf (stderr, "out of memory in CCtsp_array_to_lpclique\n");
+        return 1;
+    }
+    cliq->segcount = nseg;
+
+    nseg = 0;
+    i = 0;
+    while (i < acount) {
+        cliq->nodes[nseg].lo = ar[i];
+        while (i < (acount - 1) && ar[i + 1] == (ar[i] + 1))
+            i++;
+        cliq->nodes[nseg].hi = ar[i++];
+        nseg++;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_seglist_to_lpclique (int nseg, int *list, CCtsp_lpclique *cliq)
+#else
+int CCtsp_seglist_to_lpclique (nseg, list, cliq)
+int nseg;
+int *list;
+CCtsp_lpclique *cliq;
+#endif
+{
+    int i;
+    int *perm = (int *) NULL;
+    int *len  = (int *) NULL;
+    int rval = 0;
+
+    perm = CC_SAFE_MALLOC (nseg, int);
+    len  = CC_SAFE_MALLOC (nseg, int);
+    if (!perm || !len) {
+        fprintf (stderr, "out of memory in CCtsp_seglist_to_lpclique\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < nseg; i++) {
+        perm[i] = i;
+        len[i] = list[2*i];
+    }
+    CCutil_int_perm_quicksort (perm, len, nseg);
+
+    cliq->nodes = CC_SAFE_MALLOC (nseg, CCtsp_segment);
+    if (!cliq->nodes) {
+        fprintf (stderr, "out of memory in CCtsp_seglist_to_lpclique\n");
+        rval = 1; goto CLEANUP;
+    }
+    cliq->segcount = nseg;
+
+    for (i = 0; i < nseg; i++) {
+        cliq->nodes[i].lo = list[2*perm[i]];
+        cliq->nodes[i].hi = list[2*perm[i]+1];
+    }
+
+    nseg = 0;
+
+CLEANUP:
+
+    CC_IFFREE (perm, int);
+    CC_IFFREE (len, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_node_to_lpclique (CCtsp_lpclique *cin, CCtsp_lpclique *cout,
+        int n)
+#else
+int CCtsp_add_node_to_lpclique (cin, cout, n)
+CCtsp_lpclique *cin;
+CCtsp_lpclique *cout;
+int n;
+#endif
+{
+    int count = 0;
+    int rval  = 0;
+    int *ar   = (int *) NULL;
+    int i, j;
+
+    CCtsp_init_lpclique (cout);
+
+    for (i = 0; i < cin->segcount; i++) {
+        count += (cin->nodes[i].hi - cin->nodes[i].lo + 1);
+        if (cin->nodes[i].lo <= n && n <= cin->nodes[i].hi) {
+            fprintf (stderr, "node already in clique\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    ar = CC_SAFE_MALLOC (count + 1, int);
+    if (!ar) {
+        fprintf (stderr, "out of memory in CCtsp_add_node_to_lpclique\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    count = 0;
+    for (i = 0; i < cin->segcount; i++) {
+        for (j = cin->nodes[i].lo; j <= cin->nodes[i].hi; j++) {
+            ar[count++] = j;
+        }
+    }
+    ar[count++] = n;
+    rval = CCtsp_array_to_lpclique (ar, count, cout);
+    if (rval) {
+        fprintf (stderr, "CCtsp_array_to_lpclique failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (ar, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_delete_node_from_lpclique (CCtsp_lpclique *cin,
+        CCtsp_lpclique *cout, int n)
+#else
+int CCtsp_delete_node_from_lpclique (cin, cout, n)
+CCtsp_lpclique *cin;
+CCtsp_lpclique *cout;
+int n;
+#endif
+{
+    int count = 0;
+    int rval  = 0;
+    int *ar   = (int *) NULL;
+    int i, j, hit = 0;
+
+    CCtsp_init_lpclique (cout);
+
+    for (i = 0; i < cin->segcount; i++) {
+        count += (cin->nodes[i].hi - cin->nodes[i].lo + 1);
+        if (cin->nodes[i].lo <= n && n <= cin->nodes[i].hi) {
+            hit++;
+        }
+    }
+    if (!hit) {
+        fprintf (stderr, "node is not in clique\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    ar = CC_SAFE_MALLOC (count, int);
+    if (!ar) {
+        fprintf (stderr, "out of memory in CCtsp_delete_node_from_lpclique\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    count = 0;
+    for (i = 0; i < cin->segcount; i++) {
+        for (j = cin->nodes[i].lo; j <= cin->nodes[i].hi; j++) {
+            if (j != n) {
+                ar[count++] = j;
+            }
+        }
+    }
+    rval = CCtsp_array_to_lpclique (ar, count, cout);
+    if (rval) {
+        fprintf (stderr, "CCtsp_array_to_lpclique failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (ar, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_print_lpcut_in (CCtsp_lpcut_in *c)
+#else
+void CCtsp_print_lpcut_in (c)
+CCtsp_lpcut_in *c;
+#endif
+{
+    int i;
+
+    if (c->cliquecount == 1) {
+        printf ("Subtour\n");
+        printf ("      ");
+        CCtsp_print_lpclique (&(c->cliques[0]));
+    } else {
+        if (c->handlecount == 1) {
+            printf ("Comb\n");
+            printf ("  Handle\n");
+        } else {
+            printf ("Clique Tree or Wild Thing\n");
+            printf ("  Handles:\n");
+        }
+        for (i = 0; i < c->handlecount; i++) {
+            printf ("      ");
+            CCtsp_print_lpclique (&(c->cliques[i]));
+        }
+        if (c->cliquecount > c->handlecount) {
+            printf ("  Teeth\n");
+            for (; i < c->cliquecount; i++) {
+                printf ("      ");
+                CCtsp_print_lpclique (&(c->cliques[i]));
+            }
+        }
+    }
+    printf ("\n"); fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_print_lpclique (CCtsp_lpclique *c)
+#else
+void CCtsp_print_lpclique (c)
+CCtsp_lpclique *c;
+#endif
+{
+    int i;
+
+    if (c->segcount == 0) {
+        printf ("Empty Clique\n"); fflush (stdout);
+    } else {
+        for (i = 0; i < c->segcount; i++) {
+            printf ("%d->%d ", c->nodes[i].lo, c->nodes[i].hi);
+        }
+        printf ("\n"); fflush (stdout);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_lpcut_to_lpcut_in (CCtsp_lpcuts *cuts, CCtsp_lpcut *c,
+        CCtsp_lpcut_in *new)
+#else
+int CCtsp_lpcut_to_lpcut_in (cuts, c, new)
+CCtsp_lpcuts *cuts;
+CCtsp_lpcut *c;
+CCtsp_lpcut_in *new;
+#endif
+{
+    int i, k;
+    CCtsp_lpclique *cl;
+    int rval = 0;
+
+    new->handlecount = c->handlecount;
+    new->cliquecount = c->cliquecount;
+    new->rhs = c->rhs;
+    new->sense = c->sense;
+    new->branch = c->branch;
+    new->next =  (CCtsp_lpcut_in *) NULL;
+    new->prev = (CCtsp_lpcut_in *) NULL;
+
+    new->cliques = CC_SAFE_MALLOC (c->cliquecount, CCtsp_lpclique);
+    if (!new->cliques) {
+        fprintf (stderr, "out of memory in CCtsp_lpcut_to_lpcut_in\n");
+        return 1;
+    }
+
+    for (i = 0; i < c->cliquecount; i++) {
+        cl = &(cuts->cliques[c->cliques[i]]);
+        rval = CCtsp_copy_lpclique (cl, &new->cliques[i]);
+        if (rval) {
+            fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+            for (k = 0; k < i; k++) {
+                CC_FREE (new->cliques[k].nodes, CCtsp_segment);
+            }
+            CC_FREE (new->cliques, CCtsp_lpclique);
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_copy_lpclique (CCtsp_lpclique *c, CCtsp_lpclique *new)
+#else
+int CCtsp_copy_lpclique (c, new)
+CCtsp_lpclique *c;
+CCtsp_lpclique *new;
+#endif
+{
+    int k;
+    CCtsp_segment *s = (CCtsp_segment *) NULL;
+
+    CCtsp_init_lpclique (new);
+    if (c->segcount) {
+        s = CC_SAFE_MALLOC (c->segcount, CCtsp_segment);
+        if (!s) {
+            fprintf (stderr, "out of memory in copy_lpclique\n");
+            return 1;
+        }
+        for (k = 0; k < c->segcount; k++) {
+            s[k].lo = c->nodes[k].lo;
+            s[k].hi = c->nodes[k].hi;
+        }
+    }
+    new->segcount = c->segcount;
+    new->nodes = s;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_lpclique_compare (CCtsp_lpclique *a, CCtsp_lpclique *b, int *diff)
+#else
+void CCtsp_lpclique_compare (a, b, diff)
+CCtsp_lpclique *a, *b;
+int *diff;
+#endif
+{
+    int i;
+
+    if (a->segcount != b->segcount) {
+        *diff = 1; return;
+    } else {
+        for (i = 0; i < a->segcount; i++) {
+            if (a->nodes[i].lo != b->nodes[i].lo) {
+                *diff = 1; return;
+            }
+            if (a->nodes[i].hi != b->nodes[i].hi) {
+                *diff = 1; return;
+            }
+        }
+    }
+    *diff = 0; return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_file_cuts (char *cutfile, CCtsp_lpcut_in **cuts, int *cutcount,
+        int ncount, int *tour)
+#else
+int CCtsp_file_cuts (cutfile, cuts, cutcount, ncount, tour)
+char *cutfile;
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int *tour;
+#endif
+{
+    FILE *in = (FILE *) NULL;
+    int *inv = (int *) NULL;
+    CCtsp_lpcut_in *c;
+    int i, j, k;
+    int ncliques, nhandles, size;
+    int *icliq = (int *) NULL;
+    int rval = 0;
+
+    *cutcount = 0;
+
+    in = fopen (cutfile, "r");
+    if  (in == (FILE *) NULL) {
+        fprintf (stderr, "unable to open %s for reading\n", cutfile);
+        return 0;
+    }
+
+    inv = CC_SAFE_MALLOC (ncount, int);
+    if (!inv) {
+        fprintf (stderr, "out of memory in CCtsp_file_cuts\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++) {
+        inv[tour[i]] = i;
+    }
+
+    while (fscanf (in, "%d", &ncliques) != EOF) {
+        c = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+        if (!c) {
+            fprintf (stderr, "out of memory in CCtsp_file_cuts\n");
+            rval = 1; goto CLEANUP;
+        }
+        c->cliquecount = ncliques;
+        c->cliques = CC_SAFE_MALLOC (ncliques, CCtsp_lpclique);
+        if (!c->cliques) {
+            fprintf (stderr, "out of memory in CCtsp_file_cuts\n");
+            rval = 1; goto CLEANUP;
+        }
+        fscanf (in, "%d", &nhandles);
+        c->handlecount = nhandles;
+        for (i = 0; i < ncliques; i++) {
+            fscanf (in, "%d", &size);
+            icliq = CC_SAFE_MALLOC (size, int);
+            if (!icliq) {
+                fprintf (stderr, "out of memory in CCtsp_file_cuts\n");
+                rval = 1; goto CLEANUP;
+            }
+            for (j = 0; j < size; j++) {
+                fscanf (in, "%d", &k);
+                icliq[j] = inv[k];
+            }
+            rval = CCtsp_array_to_lpclique (icliq, size, &(c->cliques[i]));
+            if (rval) {
+                fprintf (stderr, "CCtsp_array_to_lpclique failed\n");
+                goto CLEANUP;
+            }
+            CC_FREE (icliq, int);
+        }
+        fscanf (in, "%d", &(c->rhs));
+        c->sense = 'G';
+        c->branch = 0;
+        c->next = *cuts;
+        *cuts = c;
+        (*cutcount)++;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (inv, int);
+    fclose (in);
+    return  rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_file_cuts_write (char *cutfile, CCtsp_lpcuts *cuts, int *tour)
+#else
+int CCtsp_file_cuts_write (cutfile, cuts, tour)
+char *cutfile;
+CCtsp_lpcuts *cuts;
+int *tour;
+#endif
+{
+    FILE *out = (FILE *) NULL;
+    int i, j, k, p;
+    int cutcount = cuts->cutcount;
+    CCtsp_lpcut *c;
+    CCtsp_lpclique *cl;
+    int isize;
+
+    out = fopen (cutfile, "w");
+    if  (out == (FILE *) NULL) {
+        fprintf (stderr, "unable to open %s for writing\n", cutfile);
+        return 1;
+    }
+
+    for (i = 0; i < cutcount; i++) {
+        c = &cuts->cuts[i];
+        if (!c->branch) {
+            fprintf (out, "%d %d\n", c->cliquecount, c->handlecount);
+            for (j = 0; j < c->cliquecount; j++) {
+                cl = &cuts->cliques[c->cliques[j]];
+                for (k = 0, isize = 0; k < cl->segcount; k++) {
+                    isize += (cl->nodes[k].hi - cl->nodes[k].lo + 1);
+                }
+                fprintf (out, "%d  ", isize);
+                for (k = 0; k < cl->segcount; k++) {
+                    for (p = cl->nodes[k].lo; p <= cl->nodes[k].hi; p++) {
+                        fprintf (out, "%d ", tour[p]);
+                    }
+                }
+                fprintf (out, "\n");
+            }
+            fprintf (out, "%d\n", c->rhs);
+        }
+    }
+
+    fclose (out);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_buildcut_begin (cutinfo *cuts, int init_cliquecount)
+#else
+int CCtsp_buildcut_begin (cuts, init_cliquecount)
+cutinfo *cuts;
+int init_cliquecount;
+#endif
+{
+    cuts->current = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+    if (!cuts->current) return -1;
+    cuts->current->cliquecount = 0;
+    cuts->current->handlecount = 0;
+    cuts->current->rhs = 0;
+    cuts->current->sense = 'G';
+    cuts->current->branch = 0;
+    cuts->current->cliques = CC_SAFE_MALLOC (init_cliquecount, CCtsp_lpclique);
+    if (!cuts->current->cliques) {
+        CC_FREE (cuts->current, CCtsp_lpcut_in);
+        return -1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_buildcut_addclique (cutinfo *cuts, int *arr, int size, int handle)
+#else
+int CCtsp_buildcut_addclique (cuts, arr, size, handle)
+cutinfo *cuts;
+int *arr;
+int size;
+int handle;
+#endif
+{
+    int i;
+    int *newarr = (int *) NULL;
+    int newsize;
+    int rval;
+    CCtsp_lpcut_in *c = cuts->current;
+
+    if (!c) {
+        fprintf (stderr, "Trying to add to nonexistent clique\n");
+        return -1;
+    }
+
+    rval = CCcut_SRK_expand (&cuts->expand, arr, size, &newarr, &newsize);
+    if (rval) {
+        fprintf (stderr, "CCcut_SRK_expand failed\n");
+        CCtsp_buildcut_abort (cuts);
+        return rval;
+    }
+
+    rval = CCutil_reallocrus_count ((void **) &(c->cliques), c->cliquecount+1,
+                             sizeof (c->cliques[0]));
+    if (rval) {
+        fprintf (stderr, "couldn't realloc cliques\n");
+        CC_IFFREE (newarr, int);
+        CCtsp_buildcut_abort (cuts);
+        return rval;
+    }
+
+    if (handle) {
+        for (i=c->cliquecount; i>c->handlecount; i--) {
+            c->cliques[i] = c->cliques[i-1];
+        }
+        i = c->handlecount;
+        c->handlecount++;
+    } else {
+        i = c->cliquecount;
+    }
+
+    rval = CCtsp_array_to_lpclique (newarr, newsize, &(c->cliques[i]));
+    if (rval) {
+        fprintf (stderr, "CCtsp_array_to_lpclique failed\n");
+        CC_IFFREE (newarr, int);
+        CCtsp_buildcut_abort (cuts);
+        return rval;
+    }
+    c->cliquecount++;
+    CC_IFFREE (newarr, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_buildcut_abort (cutinfo *cuts)
+#else
+void CCtsp_buildcut_abort (cuts)
+cutinfo *cuts;
+#endif
+{
+    int i;
+    CCtsp_lpcut_in *c = cuts->current;
+
+    if (c) {
+        for (i=0; i<c->cliquecount; i++) {
+            CC_FREE (c->cliques[i].nodes, CCtsp_segment);
+        }
+        CC_FREE (c->cliques, CCtsp_lpclique);
+        CC_FREE (cuts->current, CCtsp_lpcut_in);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_buildcut_finish (cutinfo *cuts, int rhs)
+#else
+void CCtsp_buildcut_finish (cuts, rhs)
+cutinfo *cuts;
+int rhs;
+#endif
+{
+    CCtsp_lpcut_in *c = cuts->current;
+
+#ifdef DUMP_BUILDCUT
+    {
+        int i, j, k;
+        printf ("new buildcut (%d %d):", c->cliquecount, c->handlecount);
+        for (i=0; i<c->cliquecount; i++) {
+            printf (" (");
+            for (j=0; j<c->cliques[i].segcount; j++) {
+                for (k=c->cliques[i].nodes[j].lo; k<=c->cliques[i].nodes[j].hi;
+                     k++) {
+                    printf ("%d ",k);
+                }
+            }
+            printf (")");
+        }
+        printf (" >= %d\n", rhs);
+        fflush (stdout);
+    }
+#endif
+
+    c->rhs = rhs;
+    c->next = *cuts->clist;
+    (*cuts->clist) = c;
+    cuts->current = (CCtsp_lpcut_in *) NULL;
+    (*cuts->cutcount)++;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grab_nonzero_x (int ecount, int *elist, double *x,
+        int *new_ecount, int **new_elist, double **new_x, double tol)
+#else
+static int grab_nonzero_x (ecount, elist, x, new_ecount, new_elist, new_x, tol)
+int ecount;
+int *elist;
+double *x;
+int *new_ecount;
+int **new_elist;
+double **new_x;
+double tol;
+#endif
+{
+    int i;
+    int count;
+
+    *new_ecount = 0;
+    *new_elist = (int *) NULL;
+    *new_x = (double *) NULL;
+
+    for (i = 0, count = 0; i < ecount; i++) {
+        if (x[i] > tol) {
+            count++;
+        }
+    }
+
+    *new_elist = CC_SAFE_MALLOC (2*count, int);
+    *new_x = CC_SAFE_MALLOC (count, double);
+    if (!(*new_elist) || !(*new_x)) {
+        fprintf (stderr, "out of memory in grab_nonzero_x\n");
+        CC_IFFREE (*new_elist, int);
+        CC_IFFREE (*new_x, double);
+        return 1;
+    }
+
+    for (i = 0, count = 0; i < ecount; i++) {
+        if (x[i] > tol) {
+            (*new_elist)[2*count] = elist[2*i];
+            (*new_elist)[2*count+1] = elist[2*i+1];
+            (*new_x)[count] = x[i];
+            count++;
+        }
+    }
+    *new_ecount = count;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_test_pure_comb (int ncount, CCtsp_lpcut_in *c, int *yes_no,
+        int *handle)
+#else
+int CCtsp_test_pure_comb (ncount, c, yes_no, handle)
+int ncount;
+CCtsp_lpcut_in *c;
+int *yes_no;
+int *handle;
+#endif
+{
+    int rval = 0;
+    int i, marked, ihandle;
+    int *marks = (int *) NULL;
+
+    *yes_no = 0;
+    if (handle) *handle = -1;
+
+    if (c->cliquecount < 4 || c->cliquecount % 2 ||
+        c->sense != 'G') {
+        goto CLEANUP;
+    }
+
+    rval = CCtsp_find_pure_handle (ncount, c, &ihandle);
+    if (rval) {
+        fprintf (stderr, "CCtsp_find_pure_handle failed\n");
+        goto CLEANUP;
+    }
+    if (ihandle == -1) goto CLEANUP;
+
+    marks = CC_SAFE_MALLOC (ncount, int);
+    if (!marks) {
+        fprintf (stderr, "out of memory in CCtsp_test_pure_comb\n");
+        rval = 1; goto CLEANUP;
+    }
+    CCtsp_mark_cut (c, marks, 0);
+
+    CCtsp_mark_clique (&c->cliques[ihandle], marks, 1);
+    for (i = 0; i < c->cliquecount; i++) {
+        if (i != ihandle) {
+            CCtsp_is_clique_marked (&c->cliques[i], marks, 1, &marked);
+            if (!marked) goto CLEANUP;
+            CCtsp_is_clique_marked (&c->cliques[i], marks, 0, &marked);
+            if (!marked) goto CLEANUP;
+        }
+    }
+    CCtsp_mark_clique (&c->cliques[ihandle], marks, 0);
+
+    for (i = 0; i < c->cliquecount; i++) {
+        if (i != ihandle) {
+            CCtsp_is_clique_marked (&c->cliques[i], marks, 1, &marked);
+            if (marked) goto CLEANUP;
+            CCtsp_mark_clique (&c->cliques[i], marks, 1);
+        }
+    }
+
+    *yes_no = 1;
+    if (handle) *handle = ihandle;
+
+CLEANUP:
+
+    CC_IFFREE (marks, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_test_pseudocomb (int ncount, CCtsp_lpcut_in *c, int handle,
+        int *yes_no)
+#else
+int CCtsp_test_pseudocomb (ncount, c, handle, yes_no)
+int ncount;
+CCtsp_lpcut_in *c;
+int handle;
+int *yes_no;
+#endif
+{
+    int rval = 0;
+    int i, k, marked;
+    int *ends = (int *) NULL;
+    int *marks = (int *) NULL;
+
+    *yes_no = 0;
+    if (c->cliquecount <= 1 || c->cliquecount % 2 || c->sense != 'G') {
+        printf ("bad cliquecount or sense in pseudocomb\n"); fflush (stdout);
+        goto CLEANUP;
+    }
+
+    marks = CC_SAFE_MALLOC (ncount, int);
+    if (!marks) {
+        fprintf (stderr, "out of memory in CCtsp_test_pseudocomb\n");
+        rval = 1; goto CLEANUP;
+    }
+    CCtsp_mark_cut (c, marks, 0);
+
+    /* Teeth intersect H and are not contained in H */
+
+    CCtsp_mark_clique (&c->cliques[handle], marks, 1);
+    for (i = 0; i < c->cliquecount; i++) {
+        if (i != handle) {
+            CCtsp_is_clique_marked (&c->cliques[i], marks, 1, &marked);
+            if (!marked) goto CLEANUP;
+            CCtsp_is_clique_marked (&c->cliques[i], marks, 0, &marked);
+            if (!marked) goto CLEANUP;
+        }
+    }
+    CCtsp_mark_clique (&c->cliques[0], marks, 0);
+
+    /* Big teeth are pairwise disjoint */
+
+    for (i = 0; i < c->cliquecount; i++) {
+        if (i != handle) {
+            CCtsp_clique_count (&c->cliques[i], &k);
+            if (k >= 3) {
+                CCtsp_is_clique_marked (&c->cliques[i], marks, 1, &marked);
+                if (marked) goto CLEANUP;
+                CCtsp_mark_clique (&c->cliques[i], marks, 1);
+            }
+        }
+    }
+    for (i = 1; i < c->cliquecount; i++) {
+        CCtsp_mark_clique (&c->cliques[i], marks, 0);
+    }
+
+    /* No small tooth is contained in a big tooth */
+
+    for (i = 0; i < c->cliquecount; i++) {
+        if (i != handle) {
+            CCtsp_clique_count (&c->cliques[i], &k);
+            if (k >= 3) {
+                CCtsp_mark_clique (&c->cliques[i], marks, i + 1);
+            }
+        }
+    }
+    for (i = 0; i < c->cliquecount; i++) {
+        if (i != handle) {
+            CCtsp_clique_count (&c->cliques[i], &k);
+            if (k < 3) {
+                rval = CCtsp_clique_to_array (&c->cliques[i], &ends, &k);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_clique_to_array failed\n");
+                    goto CLEANUP;
+                }
+                if (ends[0] != 0 && ends[0] == ends[1]) goto CLEANUP;
+                CC_IFFREE (ends, int);
+            }
+        }
+    }
+
+
+    *yes_no = 1;
+
+
+CLEANUP:
+
+    CC_IFFREE (marks, int);
+    CC_IFFREE (ends, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_test_teeth_disjoint (int ncount, CCtsp_lpcut_in *c, int handle,
+       int *yes_no)
+#else
+int CCtsp_test_teeth_disjoint (ncount, c, handle, yes_no)
+int ncount;
+CCtsp_lpcut_in *c;
+int handle;
+int *yes_no;
+#endif
+{
+    int rval = 0;
+    int i, marked;
+    int *marks = (int *) NULL;
+
+    *yes_no = 0;
+
+    marks = CC_SAFE_MALLOC (ncount, int);
+    if (!marks) {
+        fprintf (stderr, "out of memory in CCtsp_teeth_disjoint\n");
+        rval = 1; goto CLEANUP;
+    }
+    CCtsp_mark_cut (c, marks, 0);
+
+    for (i = 0; i < c->cliquecount; i++) {
+        if (i != handle) {
+            CCtsp_is_clique_marked (&c->cliques[i], marks, 1, &marked);
+            if (marked) goto CLEANUP;
+            CCtsp_mark_clique (&c->cliques[i], marks, 1);
+        }
+    }
+
+    *yes_no = 1;
+
+CLEANUP:
+
+    CC_IFFREE (marks, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_find_pure_handle (int ncount, CCtsp_lpcut_in *c, int *handle)
+#else
+int CCtsp_find_pure_handle (ncount, c, handle)
+int ncount;
+CCtsp_lpcut_in *c;
+int *handle;
+#endif
+{
+    int rval = 0;
+    int *marks = (int *) NULL;
+    int i, test;
+
+    *handle = -1;
+    if (c->cliquecount % 2 || c->cliquecount < 4) goto CLEANUP;
+
+    marks = CC_SAFE_MALLOC (ncount, int);
+    if (!marks) {
+        fprintf (stderr, "out of memory in CCtsp_pure_find_handle\n");
+        rval = 1; goto CLEANUP;
+    }
+    CCtsp_mark_cut (c, marks, 0);
+
+    CCtsp_mark_clique (&c->cliques[0], marks, 1);
+    CCtsp_is_clique_marked (&c->cliques[1], marks, 1, &test);
+    if (test) {
+        CCtsp_is_clique_marked (&c->cliques[2], marks, 1, &test);
+        if (test) {
+            *handle = 0; goto CLEANUP;
+        } else {
+            *handle = 1; goto CLEANUP;
+        }
+    } else {
+        for (i = 2; i < c->cliquecount; i++) {
+            CCtsp_is_clique_marked (&c->cliques[i], marks, 1, &test);
+            if (test) {
+                *handle = i;
+                goto CLEANUP;
+            }
+        }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (marks, int);
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/TSP/cutpool.c b/contrib/blossom/concorde97/TSP/cutpool.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e47ab45626857522270c936c46ed4cc2f06bf46
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/cutpool.c
@@ -0,0 +1,1055 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  STORING AND SEARCHING THE CUTPOOL                      */
+/*                                                                         */
+/*                            TSP CODE                                     */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 19, 1997                                                   */
+/*        May 27, 1997 (bico)                                              */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_init_cutpool (int ncount, char *poolfilename,              */
+/*            CCtsp_lpcuts **pool)                                         */
+/*      -ncount is the number of nodes in the problem                      */
+/*      -poolfilename is a file containing an cutpool (it can be NULL)     */
+/*      -CCtsp_lpcuts will return the pool                                 */
+/*                                                                         */
+/*    int CCtsp_search_cutpool_cliques (CCtsp_lpcuts *pool,                */
+/*            CCtsp_lpclique **cliques, int *cliquecount, int ncount,      */
+/*            int ecount, int *elist, double *x, double maxdelta,          */
+/*            int maxcliques, double **cliquevals)                         */
+/*     RETURNS an array of cliques having x(delta(C)) < maxdelta           */
+/*      -pool points to a cutpool (or cuts of an lp)                       */
+/*      -cliques will return the array of cliques                          */
+/*      -cliquecount with return the length of the array                   */
+/*      -ncount is the number of nodes in the problem                      */
+/*      -ecount is the number of edges in elist                            */
+/*      -elist is a list of edges in end end format                        */
+/*      -x is an ecount-long array of weights                              */
+/*      -maxdelta is a bound on x(delta(C))                                */
+/*      -maxcliques is an upperbound on the number of cliques that should  */
+/*       be returned                                                       */
+/*      -cliquevals will return the values of x(delta(C)) for the cliques  */
+/*       (this parameter can be NULL)                                      */
+/*                                                                         */
+/*    void CCtsp_free_cutpool (CCtsp_lpcuts **pool)                        */
+/*     FREES the pool of cuts.                                             */
+/*                                                                         */
+/*    int CCtsp_write_cutpool (int ncount, char *poolfilename,             */
+/*         CCtsp_lpcuts *pool)                                             */
+/*     WRITES pool to poolfilename.                                        */
+/*                                                                         */
+/*    int CCtsp_branch_cutpool_cliques (CCtsp_lpcuts *pool,                */
+/*            CCtsp_lpclique **cliques, int *cliquecount, int ncount,      */
+/*            int ecount, int *elist, double *x, int nwant,                */
+/*            double **cliquevals)                                         */
+/*     RETURNS an array of cliques having x(delta(C)) as close to 3.0 as   */
+/*      possible.                                                          */
+/*      -the parmeters are like those used by search_cutpool_cliques,      */
+/*       where nwant is the number of cliques we would like to have in     */
+/*       the array.                                                        */
+/*                                                                         */
+/*    int CCtsp_price_cuts (CCtsp_lpcuts *pool, int ncount, int ecount,    */
+/*            int *elist, double *x, double *cutval)                       */
+/*     COMPUTES the slack on each cut in the pool                          */
+/*      -ecount, elist, and x give an x-vector                             */
+/*      -cutval returns the array of slack values (it should be passed in  */
+/*       as an array of length at least pool->cutcount)                    */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      This version does not use the compressed set references.  Notes    */
+/*  on the representation are given in "Chapter 4: The Linear              */
+/*  Programming Problems".                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "macrorus.h"
+#include "tsp.h"
+
+#define ZERO_EPSILON 0.0000000001
+#define POOL_MAXCUTS 500
+#define POOL_MINVIOL 0.001
+
+typedef struct pooledge {
+    double x;
+    int to;
+} pooledge;
+
+typedef struct poolnode {
+    struct pooledge *adj;
+    int mark;
+    int deg;
+} poolnode;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    init_empty_cutpool (int ncount, CCtsp_lpcuts *pool),
+    cut_eq (void *v_cut1, void *v_cut2, void *u_data),
+    read_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts *pool),
+    register_lpcuts (CCtsp_lpcuts *pool),
+    price_cliques (CCtsp_lpcuts *pool, int ncount, int ecount, int *elist,
+            double *x, double *cval);
+
+static unsigned int
+    cut_hash (void *v_cut, void *u_data);
+
+static void
+    sort_cliques (CCtsp_lpcut *c);
+
+static double
+    price_clique (poolnode *nlist, CCtsp_lpclique *c, int marker);
+
+#else
+
+static int
+    init_empty_cutpool (),
+    cut_eq (),
+    read_cutpool (),
+    register_lpcuts (),
+    price_cliques ();
+
+static unsigned int
+    cut_hash ();
+
+static void
+    sort_cliques ();
+
+static double
+    price_clique ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_init_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts **pool)
+#else
+int CCtsp_init_cutpool (ncount, poolfilename, pool)
+int ncount;
+char *poolfilename;
+CCtsp_lpcuts **pool;
+#endif
+{
+    int rval = 0;
+    CCtsp_lpcuts *p = (CCtsp_lpcuts *) NULL;
+
+    p = CC_SAFE_MALLOC (1, CCtsp_lpcuts);
+    if (!p) {
+        fprintf (stderr, "out of memory in CCtsp_init_cutpool\n");
+        return 1;
+    }
+    *pool = p;
+
+    p->cutcount = 0;
+    p->cuts = (CCtsp_lpcut *) NULL;
+    p->cutspace = 0;
+    p->cliqueend = 0;
+    p->cliques = (CCtsp_lpclique *) NULL;
+    p->cliquespace = 0;
+    p->cliquehash = (int *) NULL;
+    p->cuthash = (CCgenhash *) NULL;
+
+    rval = init_empty_cutpool (ncount, p);
+    if (rval) {
+        fprintf (stderr, "init_empty_cutpool failed\n"); goto CLEANUP;
+    }
+
+    if (poolfilename) {
+        rval = read_cutpool (ncount, poolfilename, p);
+        if (rval) {
+            fprintf (stderr, "read_cutpool failed\n"); goto CLEANUP;
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_cutpool (CCtsp_lpcuts **pool)
+#else
+void CCtsp_free_cutpool (pool)
+CCtsp_lpcuts **pool;
+#endif
+{
+    int i;
+
+    if (*pool) {
+        if ((*pool)->cuts) {
+            for (i = 0; i < (*pool)->cutcount; i++) {
+                CC_IFFREE ((*pool)->cuts[i].cliques, int);
+            }
+            CC_FREE ((*pool)->cuts, CCtsp_lpcut);
+        }
+        if ((*pool)->cliques) {
+            for (i=0; i < (*pool)->cliqueend; i++) {
+                CC_IFFREE ((*pool)->cliques[i].nodes, CCtsp_segment);
+            }
+            CC_FREE ((*pool)->cliques, CCtsp_lpclique);
+        }
+
+        CCtsp_free_cliquehash (*pool);
+
+        if ((*pool)->cuthash) {
+            CCutil_genhash_free ((*pool)->cuthash, NULL);
+            CC_FREE ((*pool)->cuthash, CCgenhash);
+        }
+        CC_FREE (*pool, CCtsp_lpcuts);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int init_empty_cutpool (int ncount, CCtsp_lpcuts *pool)
+#else
+static int init_empty_cutpool (ncount, pool)
+int ncount;
+CCtsp_lpcuts *pool;
+#endif
+{
+    int rval = 0;
+
+    rval = CCtsp_init_cliquehash (pool, 10 * ncount);
+    if (rval) {
+        fprintf (stderr, "CCtsp_init_cliqhash failed\n");
+        return rval;
+    }
+
+    pool->cuthash = CC_SAFE_MALLOC (1, CCgenhash);
+    if (pool->cuthash == (CCgenhash *) NULL) {
+        fprintf (stderr, "Out of memory in init_empty_cutpool\n");
+        return -1;
+    }
+
+    rval = CCutil_genhash_init (pool->cuthash, 10 * ncount, cut_eq,
+                         cut_hash, (void *) pool, 1.0, 0.6);
+    if (rval) {
+        fprintf (stderr, "CCgenhash_init failed\n");
+        return rval;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cut_eq (void *v_cut1, void *v_cut2, void *u_data)
+#else
+static int cut_eq (v_cut1, v_cut2, u_data)
+void *v_cut1;
+void *v_cut2;
+void *u_data;
+#endif
+{
+    CCtsp_lpcuts *pool = (CCtsp_lpcuts *) u_data;
+    CCtsp_lpcut *cut1 = pool->cuts + (long) v_cut1;
+    CCtsp_lpcut *cut2 = pool->cuts + (long) v_cut2;
+    int i;
+
+    if (cut1->cliquecount != cut2->cliquecount) return 1;
+    if (cut1->rhs != cut2->rhs) return 1;
+    if (cut1->sense != cut2->sense) return 1;
+    for (i=0; i<cut1->cliquecount; i++) {
+        if (cut1->cliques[i] != cut2->cliques[i]) return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static unsigned int cut_hash (void *v_cut, void *u_data)
+#else
+static unsigned int cut_hash (v_cut, u_data)
+void *v_cut;
+void *u_data;
+#endif
+{
+    CCtsp_lpcuts *pool = (CCtsp_lpcuts *) u_data;
+    CCtsp_lpcut *cut = pool->cuts + (long) v_cut;
+    unsigned int x = ((unsigned int) cut->rhs) * 257 +
+                     ((unsigned int) cut->sense);
+    int i;
+
+    for (i=0; i<cut->cliquecount; i++) {
+        x = x * 4099 + cut->cliques[i];
+    }
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int read_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts *pool)
+#else
+static int read_cutpool (ncount, poolfilename, pool)
+int ncount;
+char *poolfilename;
+CCtsp_lpcuts *pool;
+#endif
+{
+    CC_SFILE *in;
+    int n;
+    int rval = 0;
+
+    if (!poolfilename) {
+        fprintf (stderr, "pool file name is not set\n");
+        return 1;
+    }
+
+    in = CCutil_sopen (poolfilename, "r");
+    if (!in) {
+        fprintf (stderr, "sopen failed\n");
+        return 1;
+    }
+    if (CCutil_sread_int (in, (unsigned int *) &n)) {
+        fprintf (stderr, "CCutil_sread_int failed\n");
+        CCutil_sclose (in);
+        return 1;
+    }
+    if (n != ncount) {
+        fprintf (stderr, "cutpool %s does not have the correct ncount\n",
+                            poolfilename);
+        CCutil_sclose (in);
+        return 1;
+    }
+
+    rval = CCtsp_prob_getcuts ((CCtsp_PROB_FILE *) NULL, in, pool);
+    if (rval < 0) {
+        fprintf (stderr, "CCtsp_prob_getcuts failed\n");
+        CCutil_sclose (in);
+        return rval;
+    }
+
+    rval = register_lpcuts (pool);
+    if (rval) {
+        fprintf (stderr, "register_lpcuts failed\n");
+        CCutil_sclose (in);
+        return rval;
+    }
+
+    CCutil_sclose (in);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_write_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts *pool)
+#else
+int CCtsp_write_cutpool (ncount, poolfilename, pool)
+int ncount;
+char *poolfilename;
+CCtsp_lpcuts *pool;
+#endif
+{
+    CC_SFILE *out;
+    int rval = 0;
+
+    if (!poolfilename) {
+        fprintf (stderr, "pool file name not set\n");
+        return 1;
+    }
+
+    out = CCutil_sopen (poolfilename, "w");
+    if (!out) {
+        fprintf (stderr, "sopen failed\n");
+        return 1;
+    }
+    if (CCutil_swrite_int (out, (unsigned int) ncount)) {
+        fprintf (stderr, "CCutil_swrite_int failed\n");
+        CCutil_sclose (out);
+        return 1;
+    }
+
+    rval = CCtsp_prob_putcuts ((CCtsp_PROB_FILE *) NULL, out, pool);
+    if (rval) {
+        fprintf (stderr, "CCtsp_prob_putcuts failed\n");
+        CCutil_sclose (out);
+        return 1;
+    }
+
+    CCutil_sclose (out);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_search_cutpool (CCtsp_lpcuts *pool, CCtsp_lpcut_in **cuts,
+        int *cutcount, int ncount, int ecount, int *elist, double *x)
+#else
+int CCtsp_search_cutpool (pool, cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcuts *pool;
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount, ecount;
+int *elist;
+double *x;
+#endif
+{
+    int rval = 0;
+    double *cval = (double *) NULL;
+    int *ind = (int *) NULL;
+    int i;
+    CCtsp_lpcut_in *newc;
+    double maxviol;
+
+    *cutcount = 0;
+    *cuts = (CCtsp_lpcut_in *) NULL;
+
+    if (pool->cutcount == 0) return 0;
+
+    cval = CC_SAFE_MALLOC (pool->cutcount, double);
+    if (!cval) {
+        fprintf (stderr, "out of memory in CCtsp_search_cutpool\n");
+        rval = 1; goto CLEANUP;
+    }
+    rval = CCtsp_price_cuts (pool, ncount, ecount, elist, x, cval);
+    if (rval) {
+        fprintf (stderr, "CCtsp_price_cuts failed\n");
+        goto CLEANUP;
+    }
+
+    ind = CC_SAFE_MALLOC (pool->cutcount, int);
+    if (!ind) {
+        fprintf (stderr, "out of memory in CCtsp_search_cutpool\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0; i < pool->cutcount; i++) {
+        ind[i] = i;
+    }
+
+    CCutil_rselect (ind, 0, pool->cutcount - 1, POOL_MAXCUTS, cval);
+
+    maxviol = 0.0;
+    for (i = 0; i < pool->cutcount && i < POOL_MAXCUTS; i++) {
+        if (cval[ind[i]] < maxviol) maxviol = cval[ind[i]];
+        if (cval[ind[i]] < -POOL_MINVIOL) {
+            newc = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+            if (!newc) {
+                fprintf (stderr, "out of memory in CCtsp_search_cutpool\n");
+                goto CLEANUP;
+            }
+            rval = CCtsp_lpcut_to_lpcut_in (pool, &pool->cuts[ind[i]], newc);
+            if (rval) {
+                fprintf (stderr, "CCtsp_lpcut_to_lpcut_in failed\n");
+                CC_FREE (newc, CCtsp_lpcut_in);
+                goto CLEANUP;
+            }
+            newc->next = *cuts;
+            *cuts = newc;
+            (*cutcount)++;
+        }
+    }
+    printf ("%d pool cuts found, max violation %.3f\n", *cutcount, -maxviol);
+    rval = 0;
+
+CLEANUP:
+
+    CC_IFFREE (cval, double);
+    CC_IFFREE (ind, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_search_cutpool_cliques (CCtsp_lpcuts *pool, CCtsp_lpclique **cliques,
+        int *cliquecount, int ncount, int ecount, int *elist, double *x,
+        double maxdelta, int maxcliques, double **cliquevals)
+#else
+int CCtsp_search_cutpool_cliques (pool, cliques, cliquecount, ncount, ecount,
+        elist, x, maxdelta, maxcliques, cliquevals)
+CCtsp_lpcuts *pool;
+CCtsp_lpclique **cliques;
+int *cliquecount;
+int ncount, ecount;
+int *elist;
+double *x;
+double maxdelta;
+int maxcliques;
+double **cliquevals;
+#endif
+{
+    int rval = 0;
+    double *cval = (double *) NULL;
+    int *ind = (int *) NULL;
+    double upperdelta, lowerdelta;
+    int i, k;
+    int ccount = 0;
+
+    *cliquecount = 0;
+    *cliques = (CCtsp_lpclique *) NULL;
+    if (cliquevals) {
+        *cliquevals = (double *) NULL;
+    }
+
+    if (pool->cutcount == 0) return 0;
+
+    cval = CC_SAFE_MALLOC (pool->cliqueend, double);
+    if (!cval) {
+        fprintf (stderr, "out of memory in CCtsp_search_cutpool_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = price_cliques (pool, ncount, ecount, elist, x, cval);
+    if (rval) {
+        fprintf (stderr, "price_cliques failed\n");
+        goto CLEANUP;
+    }
+
+    ind = CC_SAFE_MALLOC (pool->cliqueend, int);
+    if (!ind) {
+        fprintf (stderr, "out of memory in CCtsp_search_cutpool_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < pool->cliqueend; i++) {
+        ind[i] = i;
+    }
+
+    CCutil_rselect (ind, 0, pool->cliqueend - 1, maxcliques, cval);
+
+    upperdelta = -1.0;
+    lowerdelta = maxdelta;
+    for (i = 0; i < pool->cliqueend && i < maxcliques; i++) {
+        if (cval[ind[i]] < maxdelta) {
+            ccount++;
+            if (cval[ind[i]] < lowerdelta) lowerdelta = cval[ind[i]];
+            if (cval[ind[i]] > upperdelta) upperdelta = cval[ind[i]];
+        }
+    }
+
+    if (ccount == 0) {
+        printf ("Found no nearly tight cliques\n"); fflush (stdout);
+        goto CLEANUP;
+    }
+
+    *cliques = CC_SAFE_MALLOC (ccount, CCtsp_lpclique);
+    if (!(*cliques)) {
+        fprintf (stderr, "out of memory in CCtsp_search_cutpool_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+    if (cliquevals) {
+        *cliquevals = CC_SAFE_MALLOC (ccount, double);
+        if (!(*cliquevals)) {
+            fprintf (stderr, "out of memory in CCtsp_search_cutpool_cliques\n");
+            CC_FREE (*cliques, CCtsp_lpclique);
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    ccount = 0;
+    for (i = 0; i < pool->cliqueend && i < maxcliques; i++) {
+        if (cval[ind[i]] < maxdelta) {
+            rval = CCtsp_copy_lpclique (&(pool->cliques[ind[i]]),
+                                        &((*cliques)[ccount]));
+            if (rval) {
+                fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+                for (k = 0; k < ccount; k++) {
+                    CC_FREE ((*cliques)[k].nodes, CCtsp_segment);
+                }
+                CC_FREE (*cliques, CCtsp_lpclique);
+                if (cliquevals) {
+                    CC_FREE (*cliquevals, double);
+                }
+                goto CLEANUP;
+            }
+            if (cliquevals) {
+                (*cliquevals)[ccount] = cval[ind[i]];
+            }
+            ccount++;
+        }
+    }
+    *cliquecount = ccount;
+
+    printf ("%d nearly tight cliques found, range (%.3f, %.3f)\n",
+              *cliquecount, lowerdelta, upperdelta);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (cval, double);
+    CC_IFFREE (ind, int);
+    return rval;
+}
+
+#define BRANCH_CLIQUE_GOAL 3.00
+#define BRANCH_CLIQUE_TOL  0.99
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_branch_cutpool_cliques (CCtsp_lpcuts *pool, CCtsp_lpclique **cliques,
+        int *cliquecount, int ncount, int ecount, int *elist, double *x,
+        int nwant, double **cliquevals)
+#else
+int CCtsp_branch_cutpool_cliques (pool, cliques, cliquecount, ncount, ecount,
+        elist, x, nwant, cliquevals)
+CCtsp_lpcuts *pool;
+CCtsp_lpclique **cliques;
+int *cliquecount;
+int ncount, ecount;
+int *elist;
+double *x;
+int nwant;
+double **cliquevals;
+#endif
+{
+    int rval = 0;
+    double *cval = (double *) NULL;
+    double upperdelta, lowerdelta;
+    double t;
+    int i, k;
+    int ccount = 0;
+    int *blist =   (int *) NULL;
+    double *bval = (double *) NULL;
+
+    printf ("branch_cutpool_cliques ...\n"); fflush (stdout);
+
+    *cliquecount = 0;
+    *cliques = (CCtsp_lpclique *) NULL;
+    if (cliquevals) {
+        *cliquevals = (double *) NULL;
+    }
+
+    if (pool->cutcount == 0 || nwant <= 0) return 0;
+
+    blist = CC_SAFE_MALLOC (nwant + 1, int);
+    bval  = CC_SAFE_MALLOC (nwant + 1, double);
+    cval = CC_SAFE_MALLOC (pool->cliqueend, double);
+    if (!blist || !bval || !cval) {
+        fprintf (stderr, "out of memory in CCtsp_search_cutpool_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = price_cliques (pool, ncount, ecount, elist, x, cval);
+    if (rval) {
+        fprintf (stderr, "price_cliques failed\n");
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < nwant; i++) {
+        blist[i] = -1;
+        bval[i]  = CCtsp_LP_MAXDOUBLE;
+    }
+    blist[nwant] = -1;
+    bval[i]      = -1.0;
+
+    for (i = 0; i < pool->cliqueend; i++) {
+        t = CC_OURABS (BRANCH_CLIQUE_GOAL - cval[i]);
+        if (t < bval[0] && t < BRANCH_CLIQUE_TOL) {
+            for (k = 0; t < bval[k+1]; k++) {
+                blist[k] = blist[k+1];
+                bval[k]  =  bval[k+1];
+            }
+            blist[k] = i;
+            bval[k]  = t;
+        }
+    }
+
+    upperdelta = -1.0;
+    lowerdelta = CCtsp_LP_MAXDOUBLE;
+    for (i = 0; i < nwant; i++) {
+        if (blist[i] != -1) {
+            if (upperdelta < cval[blist[i]]) {
+                upperdelta = cval[blist[i]];
+            }
+            if (lowerdelta > cval[blist[i]]) {
+                lowerdelta = cval[blist[i]];
+            }
+            ccount++;
+        }
+    }
+
+    if (ccount == 0) {
+        printf ("Found no nearly tight cliques\n"); fflush (stdout);
+        goto CLEANUP;
+    }
+
+    *cliques = CC_SAFE_MALLOC (ccount, CCtsp_lpclique);
+    if (!(*cliques)) {
+        fprintf (stderr, "out of memory in CCtsp_search_cutpool_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+    if (cliquevals) {
+        *cliquevals = CC_SAFE_MALLOC (ccount, double);
+        if (!(*cliquevals)) {
+            fprintf (stderr, "out of memory in CCtsp_search_cutpool_cliques\n");
+            CC_FREE (*cliques, CCtsp_lpclique);
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    ccount = 0;
+    for (i = nwant - 1; i >= 0; i--) {
+        if (blist[i] != -1) {
+            rval = CCtsp_copy_lpclique (&(pool->cliques[blist[i]]),
+                                      &((*cliques)[ccount]));
+            if (rval) {
+                fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+                for (k = 0; k < ccount; k++) {
+                    CC_FREE ((*cliques)[k].nodes, CCtsp_segment);
+                }
+                CC_FREE (*cliques, CCtsp_lpclique);
+                if (cliquevals) {
+                    CC_FREE (*cliquevals, double);
+                }
+                goto CLEANUP;
+            }
+            if (cliquevals) {
+                (*cliquevals)[ccount] = cval[blist[i]];
+            }
+            ccount++;
+        }
+    }
+    *cliquecount = ccount;
+
+    printf ("%d candidate branching cliques, range (%.3f, %.3f)\n",
+              *cliquecount, lowerdelta, upperdelta);
+    fflush (stdout);
+
+
+CLEANUP:
+
+    CC_IFFREE (blist, int);
+    CC_IFFREE (bval, double);
+    CC_IFFREE (cval, double);
+    return rval;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_to_cutpool (CCtsp_lpcuts *pool, CCtsp_lpcuts *cuts,
+        CCtsp_lpcut *c)
+#else
+int CCtsp_add_to_cutpool (pool, cuts, c)
+CCtsp_lpcuts *pool;
+CCtsp_lpcuts *cuts;
+CCtsp_lpcut *c;
+#endif
+{
+    int rval = 0;
+    CCtsp_lpcut_in cin;
+    int k;
+
+    if (!c || c->cliquecount <= 1)
+        return 0;
+
+    cin.cliquecount = 0;
+    cin.cliques = (CCtsp_lpclique *) NULL;
+
+
+    rval = CCtsp_lpcut_to_lpcut_in (cuts, c, &cin);
+    if (rval) {
+        fprintf (stderr, "CCtsp_lpcut_to_lpcut_in failed\n");
+        goto CLEANUP;
+    }
+
+    rval = CCtsp_add_to_cutpool_lpcut_in (pool, &cin);
+    if (rval) {
+        fprintf (stderr, "CCtsp_add_to_cutpool_lpcut_in failed\n");
+        goto CLEANUP;
+    }
+
+CLEANUP:
+
+    for (k = 0; k < cin.cliquecount; k++) {
+        CC_IFFREE (cin.cliques[k].nodes, CCtsp_segment);
+    }
+    CC_IFFREE (cin.cliques, CCtsp_lpclique);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_to_cutpool_lpcut_in (CCtsp_lpcuts *pool, CCtsp_lpcut_in *cut)
+#else
+int CCtsp_add_to_cutpool_lpcut_in (pool, cut)
+CCtsp_lpcuts *pool;
+CCtsp_lpcut_in *cut;
+#endif
+{
+    int rval = 0;
+    CCtsp_lpcut new;
+    int cutloc;
+    unsigned int hval;
+
+    if (!pool)
+        return 0;
+
+    new.rhs      = cut->rhs;
+    new.branch   = cut->branch;
+    new.sense    = cut->sense;
+    new.modcount = 0;
+    new.mods = (CCtsp_sparser *) NULL;
+    new.handlecount = 0;
+    new.cliquecount = 0;
+    new.cliques = (int *) NULL;
+    new.age = 0;
+
+    rval = CCtsp_register_cliques (pool, cut, &new);
+    if (rval) {
+        fprintf (stderr, "register_cliques failed\n");
+        return rval;
+    }
+
+    sort_cliques (&new);
+
+    cutloc = CCtsp_add_cut_to_cutlist (pool, &new);
+    if (cutloc < 0) {
+        fprintf (stderr, "CCtsp_add_cut_to_cutlist failed\n");
+        CCtsp_unregister_cliques (pool, &new);
+        return cutloc;
+    }
+
+    hval = CCutil_genhash_hash (pool->cuthash, (void *) ((long) cutloc));
+    if (CCutil_genhash_lookup_h (pool->cuthash, hval,
+                                 (void *) ((long) cutloc))) {
+        /* cut was already in pool */
+        CCtsp_delete_cut_from_cutlist (pool, cutloc);
+        return 0;
+    }
+
+    rval = CCutil_genhash_insert_h (pool->cuthash, hval, (void *) ((long) cutloc),
+            (void *) ((long) 1));
+    if (rval) {
+        fprintf (stderr, "CCgenhash_insert_h failed\n");
+        CCtsp_delete_cut_from_cutlist (pool, cutloc);
+        return rval;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void sort_cliques (CCtsp_lpcut *c)
+#else
+static void sort_cliques (c)
+CCtsp_lpcut *c;
+#endif
+{
+    CCutil_int_array_quicksort (c->cliques, c->handlecount);
+    CCutil_int_array_quicksort (c->cliques + c->handlecount,
+                               c->cliquecount - c->handlecount);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int register_lpcuts (CCtsp_lpcuts *pool)
+#else
+static int register_lpcuts (pool)
+CCtsp_lpcuts *pool;
+#endif
+{
+    int i;
+    unsigned int hval;
+    int rval = 0;
+    int ndup = 0;
+
+    for (i=0; i<pool->cutcount; i++) {
+        sort_cliques (&pool->cuts[i]);
+        hval = CCutil_genhash_hash (pool->cuthash, (void *) ((long) i));
+        if (CCutil_genhash_lookup_h (pool->cuthash, hval,
+                                     (void *) ((long) i))) {
+            ndup++;
+        } else {
+            rval = CCutil_genhash_insert_h (pool->cuthash, hval,
+                                            (void *) ((long) i),
+                                            (void *) ((long) 1));
+            if (rval) {
+                fprintf (stderr, "CCgenhash_insert_h failed\n");
+                return rval;
+            }
+        }
+    }
+    if (ndup) {
+        printf ("%d duplicates detected in pool\n", ndup);
+        fflush (stdout);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_display_cutpool (CCtsp_lpcuts *pool)
+#else
+int CCtsp_display_cutpool (pool)
+CCtsp_lpcuts *pool;
+#endif
+{
+    int i, k;
+    CCtsp_lpcut_in c;
+
+    for (i = 0; i < pool->cutcount; i++) {
+        if (CCtsp_lpcut_to_lpcut_in (pool, &(pool->cuts[i]), &c)) {
+            fprintf (stderr, "CCtsp_lpcut_to_lpcut_in failed\n");
+            return 1;
+        }
+        CCtsp_print_lpcut_in (&c);
+        for (k = 0; k < c.cliquecount; k++) {
+            CC_IFFREE (c.cliques[k].nodes, CCtsp_segment);
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_price_cuts (CCtsp_lpcuts *pool, int ncount, int ecount, int *elist,
+        double *x, double *cutval)
+#else
+int CCtsp_price_cuts (pool, ncount, ecount, elist, x, cutval)
+CCtsp_lpcuts *pool;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+double *cutval;
+#endif
+{
+    double *cval = (double *) NULL;
+    int cutcount = pool->cutcount;
+    int i, j;
+    CCtsp_lpcut *c;
+    int rval = 0;
+
+    cval = CC_SAFE_MALLOC (pool->cliqueend, double);
+    if (!cval) {
+        fprintf (stderr, "out of memory in CCtsp_price_cuts\n");
+        return 1;
+    }
+
+    rval = price_cliques (pool, ncount, ecount, elist, x, cval);
+    if (rval) {
+        fprintf (stderr, "price_cliques failed\n");
+        return rval;
+    }
+
+    for (i = 0, c = pool->cuts; i < cutcount; i++, c++) {
+        cutval[i] = (double) -(c->rhs);
+        for (j  = 0; j < c->cliquecount; j++)  {
+            cutval[i] += cval[c->cliques[j]];
+        }
+    }
+
+    CC_FREE (cval, double);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int price_cliques (CCtsp_lpcuts *pool, int ncount, int ecount,
+        int *elist, double *x, double *cval)
+#else
+static int price_cliques (pool, ncount, ecount, elist, x, cval)
+CCtsp_lpcuts *pool;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+double *cval;
+#endif
+{
+    poolnode *nlist = (poolnode *) NULL;
+    pooledge *espace = (pooledge *) NULL;
+    pooledge *p;
+    char *marks = (char *) NULL;
+    int marker = 0;
+    int i, j, a, b, count;
+    int cend = pool->cliqueend;
+    int rval = 0;
+
+    nlist = CC_SAFE_MALLOC (ncount, poolnode);
+    if (!nlist) {
+        fprintf (stderr, "out of memory in price_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        nlist[i].mark = 0;
+        nlist[i].deg = 0;
+    }
+
+    count = 0;
+    for (i = 0; i < ecount; i++) {
+        if (x[i] >= ZERO_EPSILON) {
+            nlist[elist[2*i]].deg++;
+            nlist[elist[2*i+1]].deg++;
+            count++;
+        }
+    }
+    espace = CC_SAFE_MALLOC (2*count, pooledge);
+    if (!espace) {
+        fprintf (stderr, "out of memory in price_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    p = espace;
+    for (i = 0; i < ncount; i++) {
+        nlist[i].adj = p;
+        p += nlist[i].deg;
+        nlist[i].deg = 0;
+    }
+    for (i = 0; i < ecount; i++) {
+        if (x[i] >= ZERO_EPSILON) {
+            a = elist[2*i];
+            b = elist[2*i+1];
+            nlist[a].adj[nlist[a].deg].x = x[i];
+            nlist[a].adj[nlist[a].deg++].to = b;
+            nlist[b].adj[nlist[b].deg].x = x[i];
+            nlist[b].adj[nlist[b].deg++].to = a;
+        }
+    }
+
+    marks = CC_SAFE_MALLOC (cend, char);
+    if (!marks) {
+        fprintf (stderr, "out of memory in price_cliques\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0; i < cend; i++) {
+        marks[i] = 0;
+    }
+    for (i = 0; i < pool->cutcount; i++) {
+        for (j = 0; j < pool->cuts[i].cliquecount; j++) {
+            marks[pool->cuts[i].cliques[j]] = 1;
+        }
+    }
+
+    for (i = 0; i < cend; i++) {
+        if (marks[i]) {
+            marker++;
+            cval[i] = price_clique (nlist, &(pool->cliques[i]), marker);
+        } else {
+            cval[i] = 0.0;
+        }
+    }
+
+CLEANUP:
+
+    CC_IFFREE (nlist, poolnode);
+    CC_IFFREE (espace, pooledge);
+    CC_IFFREE (marks, char);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double price_clique (poolnode *nlist, CCtsp_lpclique *c, int marker)
+#else
+static double price_clique (nlist, c, marker)
+poolnode *nlist;
+CCtsp_lpclique *c;
+int marker;
+#endif
+{
+    double val = 0.0;
+    poolnode *n;
+    int i, j, k;
+
+    for (i = 0; i < c->segcount; i++) {
+        for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+            nlist[j].mark = marker;
+        }
+    }
+    for (i = 0; i < c->segcount; i++) {
+        for (j = c->nodes[i].lo; j <= c->nodes[i].hi; j++) {
+            n = &(nlist[j]);
+            for (k = 0; k < n->deg; k++) {
+                if (nlist[n->adj[k].to].mark != marker) {
+                    val += n->adj[k].x;
+                }
+            }
+        }
+    }
+    return val;
+}
diff --git a/contrib/blossom/concorde97/TSP/edgemap.c b/contrib/blossom/concorde97/TSP/edgemap.c
new file mode 100644
index 0000000000000000000000000000000000000000..1349bf3e24d2de4b55b249769b654ac8bb333c87
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/edgemap.c
@@ -0,0 +1,158 @@
+/***************************************************************************/
+/*                                                                         */
+/*            ROUTINES TO MAP NODE PAIRS TO EDGES                          */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: September 27, 1995                                               */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+#include "macrorus.h"
+
+CC_PTR_ALLOC_ROUTINE (CCtsp_edgeinf, edgeinf_alloc, edgeinf_bigchunklist,
+        edgeinf_freelist)
+CC_PTR_FREE_ROUTINE (CCtsp_edgeinf, edgeinf_free, edgeinf_freelist)
+CC_PTR_FREE_LIST_ROUTINE(CCtsp_edgeinf, edgeinf_list_free, edgeinf_free)
+CC_PTR_FREE_WORLD_ROUTINE (CCtsp_edgeinf, edgeinf_free_world,
+        edgeinf_bigchunklist, edgeinf_freelist)
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_edgehash_init (CCtsp_edgehash *h, int size)
+#else
+int CCtsp_edgehash_init (h, size)
+CCtsp_edgehash *h;
+int size;
+#endif
+{
+    unsigned int i;
+
+    h->size = CCutil_nextprime ((unsigned int) size);
+    h->mult = (int) sqrt ((double) h->size);
+    h->table = CC_SAFE_MALLOC ((int) h->size, CCtsp_edgeinf *);
+    if (!h->table) {
+        h->size = 0;
+        return 1;
+    }
+    for (i=0; i<h->size; i++) {
+        h->table[i] = (CCtsp_edgeinf *) NULL;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_edgehash_add (CCtsp_edgehash *h, int end1, int end2, int val)
+#else
+int CCtsp_edgehash_add (h, end1, end2, val)
+CCtsp_edgehash *h;
+int end1;
+int end2;
+int val;
+#endif
+{
+    int t;
+    unsigned int loc;
+    CCtsp_edgeinf *e;
+
+    if (h->size == 0) return 1;
+    e = edgeinf_alloc();
+    if (!e) return 1;
+
+    if (end1 > end2) CC_SWAP (end1, end2, t);
+    loc = (end1 * h->mult + end2) % h->size;
+    e->ends[0] = end1;
+    e->ends[1] = end2;
+    e->val = val;
+    e->next = h->table[loc];
+    h->table[loc] = e;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_edgehash_del (CCtsp_edgehash *h, int end1, int end2)
+#else
+int CCtsp_edgehash_del (h, end1, end2)
+CCtsp_edgehash *h;
+int end1;
+int end2;
+#endif
+{
+    int t;
+    CCtsp_edgeinf **prev;
+    CCtsp_edgeinf *p;
+
+    if (end1 > end2) CC_SWAP (end1, end2, t);
+    if (h->size == 0) return 1;
+
+    prev  = &h->table[(end1 * h->mult + end2) % h->size];
+    p = *prev;
+    while (p) {
+        if (p->ends[0] == end1 && p->ends[1] == end2) {
+            *prev = p->next;
+            edgeinf_free (p);
+            return 0;
+        }
+        prev = &p->next;
+        p = *prev;
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_edgehash_delall (CCtsp_edgehash *h)
+#else
+void CCtsp_edgehash_delall (h)
+CCtsp_edgehash *h;
+#endif
+{
+    unsigned int i;
+
+    for (i=0; i<h->size; i++) {
+        if (h->table[i]) {
+            edgeinf_list_free (h->table[i]);
+            h->table[i] = (CCtsp_edgeinf *) NULL;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_edgehash_find (CCtsp_edgehash *h, int end1, int end2)
+#else
+int CCtsp_edgehash_find (h, end1, end2)
+CCtsp_edgehash *h;
+int end1;
+int end2;
+#endif
+{
+    int t;
+    CCtsp_edgeinf *p;
+
+    if (end1 > end2) CC_SWAP (end1, end2, t);
+    if (h->size == 0) return -1;
+
+    for (p = h->table[(end1 * h->mult + end2) % h->size]; p; p = p->next) {
+        if (p->ends[0] == end1 && p->ends[1] == end2) {
+            return p->val;
+        }
+    }
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_edgehash_free (CCtsp_edgehash *h)
+#else
+void CCtsp_edgehash_free (h)
+CCtsp_edgehash *h;
+#endif
+{
+    CCtsp_edgehash_delall (h);
+    CC_FREE (h->table, CCtsp_edgeinf *);
+    edgeinf_free_world ();
+    h->size = 0;
+}
diff --git a/contrib/blossom/concorde97/TSP/ex_price.c b/contrib/blossom/concorde97/TSP/ex_price.c
new file mode 100644
index 0000000000000000000000000000000000000000..f0c50aaea51879c49c92e46c5d53beb31624b845
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/ex_price.c
@@ -0,0 +1,1196 @@
+/***************************************************************************/
+/*                                                                         */
+/*            ROUTINES TO PRICE EDGES USING BIGGUY ARITHMETIC              */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: January 21, 1997                                                 */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_exact_price (CCtsp_lp *lp, CCbigguy *bound, int phase1)    */
+/*     RETURNS a bound that is valid for the entire edge set; the values   */
+/*          of the dual variables will be stored in lp->exact_dual unless  */
+/*          the existing lp->exact_dual's cutcount aggrees with the        */
+/*          cutcount in for lp                                             */
+/*       -lp is a pointer to the tsp lp                                    */
+/*       -bound returns the LP bound                                       */
+/*       -phase1 is either 0 or 1, with 1 indicating that the pricing      */
+/*        should be to determine a Farkas' lemma bound to prove that the   */
+/*        LP is infeasbile                                                 */
+/*                                                                         */
+/*    int CCtsp_edge_elimination (CCtsp_lp *lp)                            */
+/*     USES the bound information to elimination edges and set edges to 1; */
+/*          the remaining edges are placed into lp->fulladj (the old adj   */
+/*          is freed) and the fixed edges are placed on the list           */
+/*          lp->fixededges; the dual values are taken from lp->exact_dual  */
+/*       -lp is a pointer to the tsp lp; lp->exact_lowerbound will be used */
+/*        together with lp->upperbound to determine the cutoff to elim     */
+/*        and fix edges                                                    */
+/*       NOTE: this function does not alter the LP or lp->graph            */
+/*                                                                         */
+/*    int CCtsp_exact_dual (CCtsp_lp *lp, CCtsp_bigdual **d)               */
+/*      RETURNS the dual values as bigguys (used to store the info used    */
+/*          to establish the exact lower bound); the values will be        */
+/*          stored in lp->exact_dual (and the existing values freed)       */
+/*       -lp is the CCtsp_lp                                               */
+/*                                                                         */
+/*    int CCtsp_verify_infeasible_lp (CCtsp_lp *lp, int *yesno)            */
+/*      VERIFIES that the lp is infeasible using exact pricing.            */
+/*       -yesno is set to 1 if the lp is infeasible and 0 otherwise.       */
+/*                                                                         */
+/*    int CCtsp_verify_lp_prune (CCtsp_lp *lp, int *yesno)                 */
+/*      VERIFIES that the lp bound is less than the lp upperbound - 1.     */
+/*       -yesno is set to 1 if bound < upperbound - 1 and 0 otherwise.     */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "macrorus.h"
+#include "bigguy.h"
+#include "tsp.h"
+
+#define BIG_PRICE_GEN 20000
+
+typedef struct bigpredge {
+    int ends[2];
+    int len;
+    CCbigguy rc;
+} bigpredge;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    big_pricing_duals (CCtsp_lp *lp, CCbigguy *node_pi, CCbigguy *node_piest,
+        CCbigguy *cut_pi, CCbigguy *clique_pi, CCbigguy *rhs_sum),
+    big_price_list (CCtsp_lp *lp, int ecount, bigpredge *elist,
+        CCbigguy *node_pi, CCbigguy *clique_pi),
+    big_generate_edges (CCtsp_lp *lp, CCbigguy *node_piest, int nwant,
+        int *gencount, bigpredge *genlist, int *n1, int *n2,
+        int *finished, CCbigguy cutoff, int phase1),
+    add_to_inlist (CCtsp_lp *lp, bigpredge *inlist, int *count, int end0,
+        int end1, int phase1),
+    add_to_adj (CCtsp_lp *lp, CCtsp_genadj *adj, int end0, int end1,
+        int *count),
+    test_edge (int end1, int end2, int len, CCbigguy *node_pi, CCbigguy cutoff);
+
+#else
+
+static int
+    big_pricing_duals (),
+    big_price_list (),
+    big_generate_edges (),
+    add_to_inlist (),
+    add_to_adj (),
+    test_edge ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_exact_price (CCtsp_lp *lp, CCbigguy *bound, int phase1)
+#else
+int CCtsp_exact_price (lp, bound, phase1)
+CCtsp_lp *lp;
+CCbigguy *bound;
+int phase1;
+#endif
+{
+    int incount;
+    bigpredge *inlist = (bigpredge *) NULL;
+    CCbigguy penalty, rhs_sum;
+    CCbigguy *node_pi = (CCbigguy *) NULL;
+    CCbigguy *node_piest = (CCbigguy *) NULL;
+    CCbigguy *clique_pi = (CCbigguy *) NULL;
+    CCbigguy *cut_pi = (CCbigguy *) NULL;
+    int nbranch = 0;
+    int n1, n2, i, j, finished;
+    int rval = 0;
+    double szeit;
+
+    printf ("exact_price ...\n"); fflush (stdout);
+    szeit = CCutil_zeit ();
+
+    *bound = CCbigguy_ZERO;
+
+    if (!lp->dat && !lp->full_edges_valid) {
+        fprintf (stderr, "must have dat file or full edge set\n");
+        return 1;
+    }
+
+    if (phase1) {
+        printf ("phase 1 pricing\n");
+        fflush (stdout);
+    }
+
+    if (!lp->exact_dual || lp->exact_dual->cutcount != lp->cuts.cutcount) {
+        printf ("Fetch the bigguy dual variables\n");
+        fflush (stdout);
+        rval = CCtsp_exact_dual (lp);
+        if (rval) {
+            fprintf (stderr, "tsp_exact_dual failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    for (i = 0; i < lp->branchdepth; i++) {
+        if (lp->branchhistory[i].ends[0] != -1) {
+            nbranch++;
+        }
+    }
+
+    incount = 0;
+    if (BIG_PRICE_GEN >= lp->nfixededges + nbranch) {
+        inlist = CC_SAFE_MALLOC (BIG_PRICE_GEN, bigpredge);
+    } else {
+        inlist = CC_SAFE_MALLOC (lp->nfixededges + nbranch, bigpredge);
+    }
+    node_pi    = CC_SAFE_MALLOC (lp->graph.ncount, CCbigguy);
+    node_piest = CC_SAFE_MALLOC (lp->graph.ncount, CCbigguy);
+    if (!inlist || !node_pi || !node_piest) {
+        fprintf (stderr, "out of memory in CCtsp_exact_price\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (lp->cuts.cliqueend) {
+        clique_pi = CC_SAFE_MALLOC (lp->cuts.cliqueend, CCbigguy);
+        if (!clique_pi) {
+            fprintf (stderr, "out of memory in CCtsp_exact_price\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (lp->cuts.cutcount) {
+        cut_pi = CC_SAFE_MALLOC (lp->cuts.cutcount, CCbigguy);
+        if (!cut_pi) {
+            fprintf (stderr, "out of memory in CCtsp_exact_price\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    rval = big_pricing_duals (lp, node_pi, node_piest, cut_pi, clique_pi,
+                              &rhs_sum);
+    if (rval) goto CLEANUP;
+    finished = 0;
+    n1 = 0;
+    n2 = (lp->full_edges_valid ? 0 : 1);
+    penalty = CCbigguy_ZERO;
+
+    while (!finished) {
+        rval = big_generate_edges (lp, node_pi, BIG_PRICE_GEN, &incount,
+                          inlist, &n1, &n2, &finished, CCbigguy_ZERO, phase1);
+        if (rval) {
+            fprintf (stderr, "big_generate_edges failed\n");
+            goto CLEANUP;
+        }
+
+        rval = big_price_list (lp, incount, inlist, node_pi, clique_pi);
+        if (rval) {
+            fprintf (stderr, "big_price_list failed\n");
+            goto CLEANUP;
+        }
+        for (i = 0; i < incount; i++) {
+            if (CCbigguy_cmp (inlist[i].rc, CCbigguy_ZERO) < 0) {
+                CCbigguy_add (&penalty, inlist[i].rc);
+/*
+                {
+                    int q;
+                    q = CCtsp_find_edge (&lp->graph, inlist[i].ends[0],
+                                   inlist[i].ends[1]);
+                    if (q == -1) {
+                        printf ("YIPES: %f [%d, %d %d]: %f %f\n",
+                          CCbigguytod (inlist[i].rc), inlist[i].ends[0],
+                          inlist[i].ends[1], inlist[i].len,
+                          CCbigguytod (node_pi[inlist[i].ends[0]]),
+                          CCbigguytod (node_pi[inlist[i].ends[1]]));
+                        fflush (stdout);
+                    }
+                }
+*/
+            }
+        }
+    }
+
+    if (lp->nfixededges + nbranch) {
+        int end0, end1;
+
+        /* Adjust bound for fixed/branch edges                            */
+        /* If a fixed or a branch=1 edge has positive rc, it can be added */
+        /* If a branch=0 edge has negative rc, it should be subtracted    */
+        /* from the penalty since it was earlier added.                   */
+
+        incount = 0;
+        for (i = 0; i < lp->nfixededges; i++) {
+            end0 = lp->fixededges[2*i];
+            end1 = lp->fixededges[2*i+1];
+            rval = add_to_inlist (lp, inlist, &incount, end0, end1, phase1);
+            if (rval) {
+                fprintf (stderr, "add_to_inlist failed\n");
+                goto CLEANUP;
+            }
+        }
+        for (i = 0; i < lp->branchdepth; i++) {
+            if (lp->branchhistory[i].ends[0] != -1) {
+                end0 = lp->branchhistory[i].ends[0];
+                end1 = lp->branchhistory[i].ends[1];
+                rval = add_to_inlist (lp, inlist, &incount, end0, end1, phase1);
+                if (rval) {
+                    fprintf (stderr, "add_to_inlist failed\n");
+                    goto CLEANUP;
+                }
+            }
+        }
+
+        rval = big_price_list (lp, incount, inlist, node_pi, clique_pi);
+        if (rval) {
+            fprintf (stderr, "big_price_list failed\n");
+            goto CLEANUP;
+        }
+        for (i = 0; i < lp->nfixededges; i++) {
+            if (CCbigguy_cmp (inlist[i].rc, CCbigguy_ZERO) > 0) {
+                CCbigguy_add (&penalty, inlist[i].rc);
+            }
+        }
+        for (i = lp->nfixededges, j = 0; i < lp->nfixededges+nbranch; i++) {
+            while (lp->branchhistory[j].ends[0] == -1)
+                j++;
+            if (lp->branchhistory[j].rhs == 0) {
+                if (CCbigguy_cmp (inlist[i].rc, CCbigguy_ZERO) < 0) {
+                    CCbigguy_sub (&penalty, inlist[i].rc);
+                }
+            } else {
+                if (CCbigguy_cmp (inlist[i].rc, CCbigguy_ZERO) > 0) {
+                    CCbigguy_add (&penalty, inlist[i].rc);
+                }
+            }
+            j++;
+        }
+    }
+
+    *bound = rhs_sum;
+    CCbigguy_add (bound, penalty);
+
+    printf ("Exact Price Time: %.2f seconds\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+    rval = 0;
+
+CLEANUP:
+
+    CC_IFFREE (cut_pi, CCbigguy);
+    CC_IFFREE (clique_pi, CCbigguy);
+    CC_IFFREE (node_pi, CCbigguy);
+    CC_IFFREE (node_piest, CCbigguy);
+    CC_IFFREE (inlist, bigpredge);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_to_inlist (CCtsp_lp *lp, bigpredge *inlist, int *count,
+        int end0, int end1, int phase1)
+#else
+static int add_to_inlist (lp, inlist, count, end0, end1, phase1)
+CCtsp_lp *lp;
+bigpredge *inlist;
+int *count;
+int end0, end1;
+int phase1;
+#endif
+{
+    int rval = 0;
+    int j;
+    int len = 0;
+    CCtsp_genadj *adj = lp->fulladj;
+
+    if (end0 > end1) {
+        CC_SWAP (end0, end1, j);
+    }
+    if (phase1) {
+        len = 0;
+    } else {
+        if (lp->full_edges_valid) {
+            for (j = 0; j < adj[end0].deg; j++) {
+                if (adj[end0].list[j].end == end1) {
+                    len = adj[end0].list[j].len;
+                    break;
+                }
+            }
+            if (j == adj[end0].deg) {
+                fprintf (stderr, "ERROR: fixed edge not in fulladj\n");
+                rval = 1; goto CLEANUP;
+            }
+        } else {
+            len = CCutil_dat_edgelen (end0, end1, lp->dat);
+        }
+    }
+    inlist[*count].ends[0] = end0;
+    inlist[*count].ends[1] = end1;
+    inlist[*count].len     = len;
+    (*count)++;
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_edge_elimination (CCtsp_lp *lp)
+#else
+int CCtsp_edge_elimination (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int incount;
+    bigpredge *inlist = (bigpredge *) NULL;
+    CCbigguy rhs_sum;
+    CCbigguy *node_pi = (CCbigguy *) NULL;
+    CCbigguy *node_piest = (CCbigguy *) NULL;
+    CCbigguy *clique_pi = (CCbigguy *) NULL;
+    CCbigguy *cut_pi = (CCbigguy *) NULL;
+    CCtsp_genadj *adj = (CCtsp_genadj *) NULL;
+    CCtsp_genadjobj *adjspace = (CCtsp_genadjobj *) NULL;
+    CCtsp_genadjobj *pa;
+    int i, n1, n2, finished, nremain, nfixed, ek;
+    int nbranch = 0;
+    int end0, end1;
+    int oldnfixed = lp->nfixededges;
+    int rval = 0;
+    CCbigguy cutoff, negcutoff;
+    double szeit;
+
+    /* This code has not been tested after branching (at present, we only */
+    /* call edge_elimination at the root LP).                             */
+
+    if (CCbigguy_cmp (lp->exact_lowerbound, CCbigguy_MINBIGGUY) == 0) {
+        fprintf (stderr, "need an exact lowerbound to run elimination\n");
+        return 1;
+    }
+    if (lp->upperbound == CCtsp_LP_MAXDOUBLE) {
+        fprintf (stderr, "need an exact upperbound to run elimination\n");
+        return 1;
+    }
+    if (!lp->exact_dual || lp->exact_dual->cutcount != lp->cuts.cutcount) {
+        fprintf (stderr, "no exact_dual in big_pricing_duals\n");
+        return 1;
+    }
+
+    szeit = CCutil_zeit ();
+
+    cutoff = CCbigguy_dtobigguy (lp->upperbound);
+    CCbigguy_sub (&cutoff, lp->exact_lowerbound);
+    CCbigguy_sub (&cutoff, CCbigguy_ONE);
+    negcutoff = CCbigguy_ZERO;
+    CCbigguy_sub (&negcutoff, cutoff);
+    printf ("Edge Elimination Cutoff: %f\n", CCbigguy_bigguytod (cutoff));
+    fflush (stdout);
+    if (CCbigguy_cmp (cutoff, CCbigguy_ZERO) < 0) {
+        printf ("Cutoff is less than ZERO, do not eliminate\n");
+        fflush (stdout);
+        return 1;
+    }
+
+    incount = 0;
+    inlist     = CC_SAFE_MALLOC (BIG_PRICE_GEN, bigpredge);
+    node_pi    = CC_SAFE_MALLOC (lp->graph.ncount, CCbigguy);
+    node_piest = CC_SAFE_MALLOC (lp->graph.ncount, CCbigguy);
+    if (!inlist || !node_pi || !node_piest) {
+        fprintf (stderr, "out of memory in CCtsp_edge_elimination\n");
+        rval = 1; goto CLEANUP;
+    }
+    if (lp->cuts.cliqueend) {
+        clique_pi = CC_SAFE_MALLOC (lp->cuts.cliqueend, CCbigguy);
+        if (!clique_pi) {
+            fprintf (stderr, "out of memory in CCtsp_edge_elimination\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+    if (lp->cuts.cutcount) {
+        cut_pi = CC_SAFE_MALLOC (lp->cuts.cutcount, CCbigguy);
+        if (!cut_pi) {
+            fprintf (stderr, "out of memory in CCtsp_edge_elimination\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    rval = big_pricing_duals (lp, node_pi, node_piest, cut_pi, clique_pi,
+                              &rhs_sum);
+    if (rval) {
+        fprintf (stderr, "big_pricing_duals failed\n");
+        goto CLEANUP;
+    }
+
+    adj = CC_SAFE_MALLOC (lp->graph.ncount, CCtsp_genadj);
+    if (!adj) {
+        fprintf (stderr, "out of memory in CCtsp_edge_elimination\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i < lp->graph.ncount; i++)
+        adj[i].deg = 0;
+
+    finished = 0;
+    nremain = 0;
+    nfixed = 0;
+    n1 = 0;
+    n2 = (lp->full_edges_valid ? 0 : 1);
+
+    while (!finished) {
+        rval = big_generate_edges (lp, node_piest, BIG_PRICE_GEN, &incount,
+                          inlist, &n1, &n2, &finished, cutoff, 0);
+        if (rval) {
+            fprintf (stderr, "big_generate_edges failed\n");
+            CC_FREE (adj, CCtsp_genadj);
+            goto CLEANUP;
+        }
+        rval = big_price_list (lp, incount, inlist, node_pi, clique_pi);
+        if (rval) {
+            fprintf (stderr, "big_price_list failed\n");
+            CC_FREE (adj, CCtsp_genadj);
+            goto CLEANUP;
+        }
+
+        for (i = 0; i < incount; i++) {
+            if (CCbigguy_cmp (inlist[i].rc, cutoff) <= 0) {
+                adj[inlist[i].ends[0]].deg++;
+                nremain++;
+                if (CCbigguy_cmp (inlist[i].rc, negcutoff) < 0) {
+                    ek = CCtsp_find_edge (&(lp->graph),inlist[i].ends[0],
+                                                 inlist[i].ends[1]);
+                    if (ek == -1 || (lp->graph.edges[ek].fixed  == 0 &&
+                                     lp->graph.edges[ek].branch == 0)) {
+                        if (ek == -1) printf ("GONG  ");
+                        printf ("[%d, %d] ", inlist[i].ends[0],
+                                             inlist[i].ends[1]);
+                        fflush (stdout);
+                        nfixed++;
+                    }
+                }
+            }
+        }
+    }
+
+    /* leave enough room for the old fixed edges and the branch edges */
+
+    for (i = 0; i < lp->branchdepth; i++) {
+        if (lp->branchhistory[i].ends[0] != -1) {
+            end0 = lp->branchhistory[i].ends[0];
+            end1 = lp->branchhistory[i].ends[1];
+        if (end0 < end1)
+            adj[end0].deg++;
+        else
+            adj[end1].deg++;
+            nbranch++;
+        }
+    }
+    for (i = 0; i < lp->nfixededges; i++) {
+        end0 = lp->fixededges[2*i];
+        end1 = lp->fixededges[2*i+1];
+        if (end0 < end1)
+            adj[end0].deg++;
+        else
+            adj[end1].deg++;
+    }
+
+    if (nremain + lp->nfixededges + nbranch) {
+        adjspace = CC_SAFE_MALLOC (nremain + lp->nfixededges + nbranch,
+                                   CCtsp_genadjobj);
+        if (!adjspace) {
+            fprintf (stderr, "out of memory in CCtsp_edge_elimination\n");
+            CC_FREE (adj, CCtsp_genadj);
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (nfixed) {
+        rval = CCutil_reallocrus_count ((void **) &(lp->fixededges),
+                  2 * (lp->nfixededges + nfixed), sizeof (int));
+        if (rval) {
+            fprintf (stderr, "out of memory in CCtsp_edge_elimination\n");
+            CC_FREE (adj, CCtsp_genadj);
+            CC_IFFREE (adjspace, CCtsp_genadjobj);
+            goto CLEANUP;
+        }
+    }
+
+    pa = adjspace;
+    for (i = 0; i < lp->graph.ncount; i++) {
+        adj[i].list = pa;
+        pa += adj[i].deg;
+        adj[i].deg = 0;
+    }
+
+    finished = 0;
+    n1 = 0;
+    n2 = (lp->full_edges_valid ? 0 : 1);
+
+    while (!finished) {
+        rval = big_generate_edges (lp, node_piest, BIG_PRICE_GEN, &incount,
+                          inlist, &n1, &n2, &finished, cutoff, 0);
+        if (rval) {
+            fprintf (stderr, "big_generate_edges failed\n");
+            CC_FREE (adj, CCtsp_genadj);
+            CC_IFFREE (adjspace, CCtsp_genadjobj);
+            goto CLEANUP;
+        }
+        rval = big_price_list (lp, incount, inlist, node_pi, clique_pi);
+        if (rval) {
+            fprintf (stderr, "big_price_list failed\n");
+            CC_FREE (adj, CCtsp_genadj);
+            CC_IFFREE (adjspace, CCtsp_genadjobj);
+            goto CLEANUP;
+        }
+        for (i = 0; i < incount; i++) {
+            if (CCbigguy_cmp (inlist[i].rc, cutoff) <= 0) {
+                adj[inlist[i].ends[0]].list[adj[inlist[i].ends[0]].deg].end =
+                                              inlist[i].ends[1];
+                adj[inlist[i].ends[0]].list[adj[inlist[i].ends[0]].deg].len =
+                                              inlist[i].len;
+                adj[inlist[i].ends[0]].deg++;
+                if (CCbigguy_cmp (inlist[i].rc, negcutoff) < 0) {
+                    ek = CCtsp_find_edge (&(lp->graph),inlist[i].ends[0],
+                                                 inlist[i].ends[1]);
+                    if (ek == -1 || (lp->graph.edges[ek].fixed  == 0 &&
+                                     lp->graph.edges[ek].branch == 0)) {
+                        lp->fixededges[2*lp->nfixededges] = inlist[i].ends[0];
+                        lp->fixededges[2*lp->nfixededges+1] =
+                                                            inlist[i].ends[1];
+                        lp->nfixededges++;
+                    }
+                }
+            }
+        }
+    }
+
+    /* some of the old fixed and branched edges may not have made it into adj */
+
+    for (i = 0; i < lp->branchdepth; i++) {
+        if (lp->branchhistory[i].ends[0] != -1) {
+            end0 = lp->branchhistory[i].ends[0];
+            end1 = lp->branchhistory[i].ends[1];
+            rval = add_to_adj (lp, adj, end0, end1, &nremain);
+            if (rval) {
+                fprintf (stderr, "add_to_adj failed\n"); goto CLEANUP;
+            }
+        }
+    }
+    for (i = 0; i < oldnfixed; i++) {
+        end0 = lp->fixededges[2*i];
+        end1 = lp->fixededges[2*i+1];
+        rval = add_to_adj (lp, adj, end0, end1, &nremain);
+        if (rval) {
+            fprintf (stderr, "add_to_adj failed\n"); goto CLEANUP;
+        }
+    }
+    rval = 0;
+
+    CC_IFFREE (lp->fulladjspace, CCtsp_genadjobj);
+    CC_IFFREE (lp->fulladj, CCtsp_genadj);
+    lp->fullcount = nremain;
+    lp->fulladjspace = adjspace;
+    lp->fulladj = adj;
+    lp->full_edges_valid = 1;
+
+    printf ("Remaining Edges: %d (with %d new fixed)\n", nremain, nfixed);
+    printf ("Edge Elimination Time: %.2f seconds\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (cut_pi, CCbigguy);
+    CC_IFFREE (clique_pi, CCbigguy);
+    CC_IFFREE (node_pi, CCbigguy);
+    CC_IFFREE (node_piest, CCbigguy);
+    CC_IFFREE (inlist, bigpredge);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_to_adj (CCtsp_lp *lp, CCtsp_genadj *adj, int end0, int end1,
+         int *count)
+#else
+static int add_to_adj (lp, adj, end0, end1, count)
+CCtsp_lp *lp;
+CCtsp_genadj *adj;
+int end0, end1;
+int *count;
+#endif
+{
+    int rval = 0;
+    int len  = 0;
+    int j, k;
+
+    if (end0 > end1) {
+        CC_SWAP (end0, end1, k);
+    }
+    for (k = 0; k < adj[end0].deg; k++) {
+        if (adj[end0].list[k].end == end1)
+            break;
+    }
+    if (k == adj[end0].deg) {
+        if (lp->full_edges_valid) {
+            for (j = 0; j < lp->fulladj[end0].deg; j++) {
+                if (lp->fulladj[end0].list[j].end == end1) {
+                    len = lp->fulladj[end0].list[j].len;
+                    break;
+                }
+            }
+            if (j == lp->fulladj[end0].deg) {
+                fprintf (stderr, "ERROR: fixed/branch edge not in fulladj\n");
+                rval = 1; goto CLEANUP;
+            }
+        } else {
+            len = CCutil_dat_edgelen (end0, end1, lp->dat);
+        }
+        adj[end0].list[adj[end0].deg].end = end1;
+        adj[end0].list[adj[end0].deg].len = len;
+        adj[end0].deg++;
+        (*count)++;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int big_pricing_duals (CCtsp_lp *lp, CCbigguy *node_pi,
+        CCbigguy *node_piest, CCbigguy *cut_pi, CCbigguy *clique_pi,
+        CCbigguy *rhs_sum)
+#else
+static int big_pricing_duals (lp, node_pi, node_piest, cut_pi, clique_pi,
+        rhs_sum)
+CCtsp_lp *lp;
+CCbigguy *node_pi;
+CCbigguy *node_piest;
+CCbigguy *cut_pi;
+CCbigguy *clique_pi;
+CCbigguy *rhs_sum;
+#endif
+{
+    CCbigguy x;
+    int i, j, k;
+    int rval = 0;
+
+    *rhs_sum = CCbigguy_ZERO;
+
+    if (!lp->exact_dual || lp->exact_dual->cutcount != lp->cuts.cutcount) {
+        fprintf (stderr, "no exact_dual in big_pricing_duals\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < lp->graph.ncount; i++) {
+        node_pi[i] = lp->exact_dual->node_pi[i];
+    }
+    for (i = 0; i < lp->cuts.cutcount; i++) {
+        cut_pi[i] = lp->exact_dual->cut_pi[i];
+    }
+
+    for (i = 0; i < lp->graph.ncount; i++)
+        CCbigguy_addmult (rhs_sum, node_pi[i], 2);
+
+    for (i = 0; i < lp->cuts.cutcount; i++) {
+        x = cut_pi[i];
+        CCbigguy_addmult (rhs_sum, x, (short) lp->cuts.cuts[i].rhs);
+        for (j = 0; j < lp->cuts.cuts[i].modcount; j++) {
+            CCbigguy_addmult (rhs_sum, x, ((short) 2) *
+                (((short) lp->cuts.cuts[i].mods[j].mult) - ((short) 128)));
+        }
+    }
+
+    for (i = 0; i < lp->cuts.cliqueend; i++) {
+        clique_pi[i] = CCbigguy_ZERO;
+    }
+
+    for (i = 0; i < lp->cuts.cutcount; i++) {
+        x = cut_pi[i];
+        for (j = 0; j < lp->cuts.cuts[i].modcount; j++) {
+            CCbigguy_addmult (&(node_pi[lp->cuts.cuts[i].mods[j].node]), x,
+                              ((short) lp->cuts.cuts[i].mods[j].mult) -
+                              ((short) 128));
+        }
+        for (j = 0; j < lp->cuts.cuts[i].cliquecount; j++) {
+            CCbigguy_add (&(clique_pi[lp->cuts.cuts[i].cliques[j]]), x);
+        }
+    }
+
+    for (i = 0; i < lp->graph.ncount; i++) {
+        node_piest[i] = node_pi[i];
+    }
+
+    for (i = 0; i < lp->cuts.cliqueend; i++) {
+        x = clique_pi[i];
+        if (CCbigguy_cmp (x, CCbigguy_ZERO) > 0) {
+            for (j = 0; j < lp->cuts.cliques[i].segcount; j++) {
+                for (k = lp->cuts.cliques[i].nodes[j].lo;
+                     k <= lp->cuts.cliques[i].nodes[j].hi; k++) {
+                    CCbigguy_add (&(node_pi[k]), x);
+                    CCbigguy_add (&(node_piest[k]), x);
+                }
+            }
+        } else if (CCbigguy_cmp (x, CCbigguy_ZERO) < 0) {
+            for (j = 0; j < lp->cuts.cliques[i].segcount; j++) {
+                for (k = lp->cuts.cliques[i].nodes[j].lo;
+                     k <= lp->cuts.cliques[i].nodes[j].hi; k++) {
+                    CCbigguy_add (&(node_pi[k]), x);
+                }
+            }
+        }
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int big_price_list (CCtsp_lp *lp, int ecount, bigpredge *elist,
+        CCbigguy *node_pi, CCbigguy *clique_pi)
+#else
+static int big_price_list (lp, ecount, elist, node_pi, clique_pi)
+CCtsp_lp *lp;
+int ecount;
+bigpredge *elist;
+CCbigguy *node_pi;
+CCbigguy *clique_pi;
+#endif
+{
+    CCtsp_lpadj *adjspace = (CCtsp_lpadj *) NULL;
+    CCtsp_lpnode *n = (CCtsp_lpnode *) NULL;
+    int i, j, k, l;
+    CCtsp_lpadj *a;
+    int marker = 0;
+    CCbigguy x;
+    int ncount = lp->graph.ncount;
+    int ccount = lp->cuts.cliqueend;
+    CCtsp_lpclique *c = lp->cuts.cliques;
+
+    if (ecount == 0) return 0;
+
+    n = CC_SAFE_MALLOC (ncount, CCtsp_lpnode);
+    adjspace = CC_SAFE_MALLOC (2*ecount, CCtsp_lpadj);
+    if (!n || !adjspace) {
+        fprintf (stderr, "out of memory in big_price_list\n");
+        CC_IFFREE (n, CCtsp_lpnode);
+        CC_IFFREE (adjspace, CCtsp_lpadj);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        n[i].deg = 0;
+        n[i].mark = 0;
+    }
+    for (i = 0; i < ecount; i++) {
+        elist[i].rc = CCbigguy_itobigguy (elist[i].len);
+        CCbigguy_sub (&(elist[i].rc), node_pi[elist[i].ends[0]]);
+        CCbigguy_sub (&(elist[i].rc), node_pi[elist[i].ends[1]]);
+        n[elist[i].ends[0]].deg++;
+        n[elist[i].ends[1]].deg++;
+    }
+    a = adjspace;
+    for (i = 0; i < ncount; i++) {
+        n[i].adj = a;
+        a += n[i].deg;
+        n[i].deg = 0;
+    }
+    for (i = 0; i < ecount; i++) {
+        j = elist[i].ends[0];
+        n[j].adj[n[j].deg].to = elist[i].ends[1];
+        n[j].adj[n[j].deg].edge = i;
+        n[j].deg++;
+        j = elist[i].ends[1];
+        n[j].adj[n[j].deg].to = elist[i].ends[0];
+        n[j].adj[n[j].deg].edge = i;
+        n[j].deg++;
+    }
+
+    for (i = 0; i < ccount; i++) {
+        if (CCbigguy_cmp (clique_pi[i], CCbigguy_ZERO)) {
+            x = clique_pi[i];
+            CCbigguy_add (&x, clique_pi[i]);
+            marker++;
+            for (j = 0; j < c[i].segcount; j++) {
+                for (k = c[i].nodes[j].lo; k <= c[i].nodes[j].hi; k++) {
+                    a = n[k].adj;
+                    for (l = 0; l < n[k].deg; l++) {
+                        if (n[a[l].to].mark == marker) {
+                            CCbigguy_add (&(elist[a[l].edge].rc), x);
+                        }
+                    }
+                    n[k].mark = marker;
+                }
+            }
+        }
+    }
+    CC_FREE (n, CCtsp_lpnode);
+    CC_FREE (adjspace, CCtsp_lpadj);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int big_generate_edges (CCtsp_lp *lp, CCbigguy *node_piest, int nwant,
+        int *gencount, bigpredge *genlist, int *n1, int *n2,
+        int *finished, CCbigguy cutoff, int phase1)
+#else
+static int big_generate_edges (lp, node_piest, nwant, gencount, genlist,
+        n1, n2, finished, cutoff, phase1)
+CCtsp_lp *lp;
+CCbigguy *node_piest;
+int nwant;
+int *gencount;
+bigpredge *genlist;
+int *n1, *n2;
+int *finished;
+CCbigguy cutoff;
+int phase1;     /* Set to nonzero to use phase 1 objective */
+#endif
+{
+    int i = *n1;
+    int j = *n2;
+    int cnt = 0;
+    int len;
+    CCtsp_genadj *adj;
+    CCdatagroup *dat;
+    int ncount = lp->graph.ncount;
+
+    *gencount = 0;
+    *finished = 0;
+
+    if (!lp->dat && !lp->full_edges_valid) {
+        fprintf (stderr, "no source of edges in big_generate_edges\n");
+        return 1;
+    }
+
+    if (i >= ncount) {
+        *finished = 1;
+        return 0;
+    }
+
+    if (lp->full_edges_valid) {
+        if (!phase1) {
+            adj = lp->fulladj;
+            for (; j < adj[i].deg; j++) {
+                if (test_edge (i, adj[i].list[j].end, adj[i].list[j].len,
+                               node_piest, cutoff)) {
+                    genlist[cnt].ends[0] = i;
+                    genlist[cnt].ends[1] = adj[i].list[j].end;
+                    genlist[cnt].len = adj[i].list[j].len;
+                    cnt++;
+                    if (cnt == nwant) {
+                        *finished = 0;
+                        *gencount = cnt;
+                        *n1 = i; *n2 = j + 1;
+                        return 0;
+                    }
+                }
+            }
+            for (i++; i < ncount; i++) {
+                for (j = 0; j < adj[i].deg; j++) {
+                    if (test_edge (i, adj[i].list[j].end, adj[i].list[j].len,
+                                   node_piest, cutoff)) {
+                        genlist[cnt].ends[0] = i;
+                        genlist[cnt].ends[1] = adj[i].list[j].end;
+                        genlist[cnt].len = adj[i].list[j].len;
+                        cnt++;
+                        if (cnt == nwant) {
+                            *finished = 0;
+                            *gencount = cnt;
+                            *n1 = i; *n2 = j + 1;
+                            return 0;
+                        }
+                    }
+                }
+            }
+        } else {
+            adj = lp->fulladj;
+            for (; j < adj[i].deg; j++) {
+                if (test_edge (i, adj[i].list[j].end, 0,
+                               node_piest, cutoff)) {
+                    genlist[cnt].ends[0] = i;
+                    genlist[cnt].ends[1] = adj[i].list[j].end;
+                    genlist[cnt].len = 0;
+                    cnt++;
+                    if (cnt == nwant) {
+                        *finished = 0;
+                        *gencount = cnt;
+                        *n1 = i; *n2 = j + 1;
+                        return 0;
+                    }
+                }
+            }
+            for (i++; i < ncount; i++) {
+                for (j = 0; j < adj[i].deg; j++) {
+                    if (test_edge (i, adj[i].list[j].end, 0,
+                                   node_piest, cutoff)) {
+                        genlist[cnt].ends[0] = i;
+                        genlist[cnt].ends[1] = adj[i].list[j].end;
+                        genlist[cnt].len = 0;
+                        cnt++;
+                        if (cnt == nwant) {
+                            *finished = 0;
+                            *gencount = cnt;
+                            *n1 = i; *n2 = j + 1;
+                            return 0;
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        if (!phase1) {
+            dat = lp->dat;
+            for (; j < ncount; j++) {
+                len = CCutil_dat_edgelen (i, j, dat);
+                if (test_edge (i, j, len, node_piest, cutoff)) {
+                    genlist[cnt].ends[0] = i;
+                    genlist[cnt].ends[1] = j;
+                    genlist[cnt].len = len;
+                    cnt++;
+                    if (cnt == nwant) {
+                        *finished = 0;
+                        *gencount = cnt;
+                        *n1 = i; *n2 = j + 1;
+                        return 0;
+                    }
+                }
+            }
+            for (i++; i < ncount; i++) {
+                for (j = i + 1; j < ncount; j++) {
+                    len = CCutil_dat_edgelen (i, j, dat);
+                    if (test_edge (i, j, len, node_piest, cutoff)) {
+                        genlist[cnt].ends[0] = i;
+                        genlist[cnt].ends[1] = j;
+                        genlist[cnt].len = len;
+                        cnt++;
+                        if (cnt == nwant) {
+                            *finished = 0;
+                            *gencount = cnt;
+                            *n1 = i; *n2 = j + 1;
+                            return 0;
+                        }
+                    }
+                }
+            }
+        } else {
+            for (; j < ncount; j++) {
+                if (test_edge (i, j, 0, node_piest, cutoff)) {
+                    genlist[cnt].ends[0] = i;
+                    genlist[cnt].ends[1] = j;
+                    genlist[cnt].len = 0;
+                    cnt++;
+                    if (cnt == nwant) {
+                        *finished = 0;
+                        *gencount = cnt;
+                        *n1 = i; *n2 = j + 1;
+                        return 0;
+                    }
+                }
+            }
+            for (i++; i < ncount; i++) {
+                for (j = i + 1; j < ncount; j++) {
+                    if (test_edge (i, j, 0, node_piest, cutoff)) {
+                        genlist[cnt].ends[0] = i;
+                        genlist[cnt].ends[1] = j;
+                        genlist[cnt].len = 0;
+                        cnt++;
+                        if (cnt == nwant) {
+                            *finished = 0;
+                            *gencount = cnt;
+                            *n1 = i; *n2 = j + 1;
+                            return 0;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    *n1 = ncount;
+    *n2 = ncount;
+    *gencount = cnt;
+    *finished = 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int test_edge (int end1, int end2, int len, CCbigguy *node_pi,
+        CCbigguy cutoff)
+#else
+static int test_edge (end1, end2, len, node_pi, cutoff)
+int end1, end2;
+int len;
+CCbigguy *node_pi;
+CCbigguy cutoff;
+#endif
+{
+    CCbigguy rc;
+
+    rc = CCbigguy_itobigguy (len);
+    CCbigguy_sub (&rc, node_pi[end1]);
+    CCbigguy_sub (&rc, node_pi[end2]);
+    if (CCbigguy_cmp (rc, cutoff) <= 0) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_exact_dual (CCtsp_lp *lp)
+#else
+int CCtsp_exact_dual (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int i;
+    int ncount = lp->graph.ncount;
+    int cutcount = lp->cuts.cutcount;
+    double *d_node_pi = (double *) NULL;
+    double *d_cut_pi = (double *) NULL;
+    CCtsp_bigdual *d = (CCtsp_bigdual *) NULL;
+    int rval = 0;
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL,
+                    (int *) NULL, (int **) NULL, (double **) NULL,
+                    (double **) NULL, &d_node_pi, &d_cut_pi);
+    if (rval) {
+        fprintf (stderr, "get_lp_result failed\n");
+        fflush (stdout);
+        goto CLEANUP;
+    }
+
+    d = CC_SAFE_MALLOC (1, CCtsp_bigdual);
+    if (!(d)) {
+        fprintf (stderr, "out of memory in CCtsp_exact_dual C\n");
+        rval = 1; goto CLEANUP;
+    }
+    d->cutcount = cutcount;
+    d->node_pi = (CCbigguy *) NULL;
+    d->cut_pi = (CCbigguy *) NULL;
+
+    d->node_pi = CC_SAFE_MALLOC (ncount, CCbigguy);
+    if (!d->node_pi) {
+        fprintf (stderr, "out of memory in CCtsp_exact_dual B\n");
+        CC_FREE (d, CCtsp_bigdual);
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        d->node_pi[i] = CCbigguy_dtobigguy (d_node_pi[i]);
+    }
+
+    if (cutcount) {
+        printf ("Request %d bigguys\n", cutcount); fflush (stdout);
+        d->cut_pi = CC_SAFE_MALLOC (cutcount, CCbigguy);
+        if (!d->cut_pi) {
+            fprintf (stderr, "out of memory in CCtsp_exact_dual A\n");
+            CC_FREE (d->node_pi, CCbigguy);
+            CC_FREE (d, CCtsp_bigdual);
+            rval = 1; goto CLEANUP;
+        }
+        for (i = 0; i < lp->cuts.cutcount; i++) {
+            d->cut_pi[i] = CCbigguy_dtobigguy (d_cut_pi[i]);
+        }
+    }
+
+    if (lp->exact_dual) {
+        CC_IFFREE (lp->exact_dual->node_pi, CCbigguy);
+        CC_IFFREE (lp->exact_dual->cut_pi, CCbigguy);
+        CC_FREE (lp->exact_dual, CCtsp_bigdual);
+    }
+    lp->exact_dual = d;
+
+
+CLEANUP:
+
+    CC_IFFREE (d_node_pi, double);
+    CC_IFFREE (d_cut_pi, double);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_bigdual (CCtsp_bigdual **d)
+#else
+void CCtsp_free_bigdual (d)
+CCtsp_bigdual **d;
+#endif
+{
+    if (d) {
+        if (*d) {
+            CC_IFFREE ((*d)->node_pi, CCbigguy);
+            CC_IFFREE ((*d)->cut_pi,  CCbigguy);
+            CC_IFFREE ((*d), CCtsp_bigdual);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_verify_infeasible_lp (CCtsp_lp *lp, int *yesno)
+#else
+int CCtsp_verify_infeasible_lp (lp, yesno)
+CCtsp_lp *lp;
+int *yesno;
+#endif
+{
+    int rval = 0;
+    CCbigguy exactbound;
+
+    *yesno = 0;
+    rval = CCtsp_exact_price (lp, &exactbound, 1);
+    if (rval) {
+        fprintf (stderr, "CCtsp_exact_price_failed\n"); goto CLEANUP;
+    }
+
+    if (CCbigguy_cmp (exactbound, CCbigguy_ZERO) < 0) {
+        printf ("Problem is shown to be infeasible\n"); fflush (stdout);
+        *yesno = 1;
+        lp->infeasible = 1; lp->lowerbound = CCtsp_LP_MAXDOUBLE;
+    } else {
+        printf ("Did not verify an infeasible LP\n"); fflush (stdout);
+        *yesno = 0;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_verify_lp_prune (CCtsp_lp *lp, int *yesno)
+#else
+int CCtsp_verify_lp_prune (lp, yesno)
+CCtsp_lp *lp;
+int *yesno;
+#endif
+{
+    int rval = 0;
+    CCbigguy exactbound, bnd;
+
+    *yesno = 0;
+    rval = CCtsp_exact_price (lp, &exactbound, 0);
+    if (rval) {
+        fprintf (stderr, "CCtsp_exact_price_failed\n"); goto CLEANUP;
+    }
+    printf ("Exact LP bound: %f\n", CCbigguy_bigguytod (exactbound));
+    fflush (stdout);
+
+    bnd = CCbigguy_dtobigguy (lp->upperbound);
+    CCbigguy_sub (&bnd, CCbigguy_ONE);
+    if (CCbigguy_cmp (exactbound, bnd) > 0) {
+        printf ("Can prune lp.\n"); fflush (stdout);
+        *yesno = 1;
+        lp->exact_lowerbound = exactbound;
+    } else {
+        printf ("Cannot prune lp.\n"); fflush (stdout);
+        *yesno = 0;
+    }
+
+CLEANUP:
+
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/TSP/generate.c b/contrib/blossom/concorde97/TSP/generate.c
new file mode 100644
index 0000000000000000000000000000000000000000..c2bdd259e3233c1f0c880568d7f7912a1b8f8598
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/generate.c
@@ -0,0 +1,854 @@
+/***************************************************************************/
+/*                                                                         */
+/*            GENERATION OF EDGES FOR THE PRICING ROUTINE                  */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 10, 1995                                                */
+/*  Last Change: July 10, 1996 (Bico)                                      */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_init_edgegenerator (edgegenerator *eg, int ncount,         */
+/*           CCdatagroup *dg, CCtsp_genadj *adj, int nneighbors)           */
+/*      SETS UP the edgegenerator structure. Must be called before calls   */
+/*      to the other edgegenerator functions.                              */
+/*        -eg must point to an edgegenerator struct.                       */
+/*        -ncount is the number of nodes.                                  */
+/*        -dg will not be copied, only the pointer is recorded.            */
+/*        -adj will be used as the edgelist if it is nonnull (in this case */
+/*         dg can be NULL).                                                */
+/*        -nneighbors is the number of neighbors that will be considered   */
+/*         from each node. To consider all edges, this should be set to    */
+/*         CCtsp_PRICE_COMPLETE_GRAPH.                                     */
+/*    void CCtsp_free_edgegenerator (edgegenerator *eg)                    */
+/*      FREES the space used by the structures in eg (but not eg itself).  */
+/*    int CCtsp_reset_edgegenerator (edgegenerator *eg, double *node_piest)*/
+/*      ADDS the pi values to the eg and records the starting position in  */
+/*      the loop through the edges (so we can determine when we have       */
+/*      circled through all edges with a single set of pi values). This    */
+/*      must be called before the first call to generate_edges.            */
+/*        -eg must have been set up with a call to init_edgegenerator.     */
+/*        -node_piest is pi values "estimates" on the nodes.               */
+/*    int CCtsp_generate_edges (CCtsp_edgegenerator *eg, int nwant,        */
+/*           int *pngot, int *elist, int *elen, int *finished)             */
+/*      RETURNS a list of edges that have a chance of having negative      */
+/*      reduced costs in that len(i,j) - pi[i] - pi[j] is negative. If an  */
+/*      entire pass has been made through the edgeset since the last call  */
+/*      to reset_edgegenerator, then finished is set to 1 (otherwise 0).   */
+/*        -eg must have been initialized with a call to init_edgegenerator */
+/*         followed by a call to reset_edgegenerator.                      */
+/*        -nwant is the maximum number of edges that should be returned.   */
+/*        -pngot returns the number of edges found.                        */
+/*        -elist returns the edges in node node format (this must have     */
+/*         been allocated by the calling routine and should be at least    */
+/*         2*nwant long.                                                   */
+/*        -elen returns the lengths of the edges in elist (this must have  */
+/*         been allocated by the calling routine and have nwant entries).  */
+/*        -finished is set to 1 if an entire loop through the edges has    */
+/*         been made since the last call to reset_edgegenerator.           */
+/*    int CCtsp_edgelist_to_genadj (int ncount, int ecount, int *elist,    */
+/*            int *elen, CCtsp_genadj **adj, CCtsp_genadjobj **adjobjspace)*/
+/*      RETURNS the genadj struct corresponding the list of edges.         */
+/*        -ncount is the number of nodes.                                  */
+/*        -ecount is the number of edges.                                  */
+/*        -elist is the array of edges in end1 end2 format.                */
+/*        -elen is the array of edge lengths.                              */
+/*        -adj is a pointer to an genadj struct address; upon return it    */
+/*         will point to the filled in adj struct.                         */
+/*        -adjobjspace will return a pointer to the list of genadjobj's    */
+/*         used in adj (this can be used to free the objects)              */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*       All (nonvoid) routines return 0 if successful.                    */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "macrorus.h"
+#include "tsp.h"
+#include "kdtree.h"
+#include "edgegen.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    xprice_free (CCtsp_xnorm_pricer *xp);
+
+static int
+    xprice_build (int ncount, CCdatagroup *dat, CCtsp_xnorm_pricer *xp),
+    xprice_reset (CCtsp_xnorm_pricer *xp, double *pi, int currentnode),
+    xprice_node (CCtsp_xnorm_pricer *xp, int n, int *count, int *nlist);
+
+#else
+
+static void
+    xprice_free ();
+
+static int
+    xprice_build (),
+    xprice_reset (),
+    xprice_node ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_init_edgegenerator (CCtsp_edgegenerator *eg, int ncount,
+        CCdatagroup *dg, CCtsp_genadj *adj, int nneighbors)
+#else
+int CCtsp_init_edgegenerator (eg, ncount, dg, adj, nneighbors)
+CCtsp_edgegenerator *eg;
+int ncount;
+CCdatagroup *dg;
+CCtsp_genadj *adj;
+int nneighbors;
+#endif
+{
+    int rval;
+
+    printf ("CCtsp_init_edgegenerator (%d)\n", nneighbors); fflush (stdout);
+
+    eg->node_piest = (double *) NULL;
+    eg->kdtree = (CCkdtree *) NULL;
+    eg->xnear = (CCxnear *) NULL;
+    eg->xprice = (CCtsp_xnorm_pricer *) NULL;
+    eg->supply = (int *) NULL;
+    eg->adjobjspace = (CCtsp_genadjobj *) NULL;
+    eg->ncount = ncount;
+    eg->dg = dg;
+    eg->adj = adj;
+
+    if (nneighbors == CCtsp_PRICE_COMPLETE_GRAPH) {
+        eg->nneighbors = CCtsp_PRICE_COMPLETE_GRAPH;
+        eg->supplyhead = 0;
+        eg->start = 0;
+        eg->current = 0;
+        if (((dg->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) ||
+            ((dg->norm & CC_NORM_BITS) == CC_X_NORM_TYPE)) {
+            eg->supply = CC_SAFE_MALLOC (ncount, int);
+            if (!eg->supply) {
+                fprintf (stderr, "out of memory in init_edgegenerator\n");
+                return 1;
+            }
+            eg->xprice = CC_SAFE_MALLOC (1, CCtsp_xnorm_pricer);
+            if (!eg->xprice) {
+                fprintf (stderr, "out of memory in init_edgegenerator\n");
+                return 1;
+            }
+            rval = xprice_build (ncount, dg, eg->xprice);
+            if (rval) {
+                fprintf (stderr, "xprice_build failed\n");
+                CC_FREE (eg->xprice, CCtsp_xnorm_pricer);
+                return rval;
+            }
+        }
+    } else {
+        eg->nneighbors = (nneighbors >= ncount - 1 ? ncount - 1 : nneighbors);
+        eg->start = 0;
+        eg->current = 0;
+
+        if (adj) {
+            eg->supplyhead = 0;
+            eg->supplycount = 0;
+        } else if (eg->nneighbors <= CCtsp_GEN_USE_ADJ) {
+            int i, k, ecount;
+            int *elist = (int *) NULL;
+            CCtsp_genadjobj *padj;
+
+            eg->supplyhead = 0;
+            eg->supplycount = 0;
+
+            if ((dg->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+                CCkdtree kt;
+                rval = CCkdtree_build (&kt, ncount, dg, (double *) NULL);
+                if (rval) {
+                    fprintf (stderr, "CCkdtree_build failed\n");
+                    return rval;
+                }
+                rval = CCkdtree_k_nearest (&kt, ncount, eg->nneighbors, dg,
+                         (double *) NULL, 1, &ecount, &elist);
+                if (rval) {
+                    fprintf (stderr, "CCkdtree_k_nearest failed\n");
+                    return rval;
+                }
+                CCkdtree_free (&kt);
+            } else if ((dg->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+                rval = CCedgegen_x_k_nearest (ncount, eg->nneighbors, dg,
+                         (double *) NULL, 1, &ecount, &elist);
+                if (rval) {
+                    fprintf (stderr, "CCedgegen_x_k_nearest failed\n");
+                    return rval;
+                }
+            } else {
+                rval = CCedgegen_junk_k_nearest (ncount, eg->nneighbors, dg,
+                         (double *) NULL, 1, &ecount, &elist);
+                if (rval) {
+                    fprintf (stderr, "CCedgegen_junk_k_nearest failed\n");
+                    return rval;
+                }
+            }
+            eg->adj = CC_SAFE_MALLOC (ncount, CCtsp_genadj);
+            if (!eg->adj) {
+                fprintf (stderr, "out of memory in init_edgegenerator\n");
+                CC_IFFREE (elist, int);
+                return 1;
+            }
+            for (i = 0; i < ncount; i++)
+                eg->adj[i].deg = 0;
+            for (i = 0; i < ecount; i++) {
+                if (elist[2*i] > elist[2*i + 1]) {
+                    CC_SWAP (elist[2*i], elist[2*i + 1], k);
+                }
+                eg->adj[elist[2*i]].deg++;
+            }
+
+            eg->adjobjspace = CC_SAFE_MALLOC (ecount, CCtsp_genadjobj);
+            if (!eg->adjobjspace) {
+                fprintf (stderr, "out of memory in init_edgegenerator\n");
+                CC_IFFREE (elist, int);
+                CC_IFFREE (eg->adj, CCtsp_genadj);
+                return 1;
+            }
+
+            padj = eg->adjobjspace;
+            for (i = 0; i < ncount; i++) {
+                eg->adj[i].list = padj;
+                padj += eg->adj[i].deg;
+                eg->adj[i].deg = 0;
+            }
+            for (i = 0; i < ecount; i++) {
+                k = elist[2*i];
+                eg->adj[k].list[eg->adj[k].deg].end = elist[2*i + 1];
+                eg->adj[k].list[eg->adj[k].deg].len =
+                        CCutil_dat_edgelen (k, elist[2*i + 1], dg);
+                eg->adj[k].deg++;
+            }
+            CC_IFFREE (elist, int);
+        } else {
+            eg->supplycount = 0;
+            eg->supplyhead = 0;
+            eg->supply = CC_SAFE_MALLOC (eg->nneighbors, int);
+            if (!eg->supply) {
+                fprintf (stderr, "out of memory in init_edgegenerator\n");
+                return 1;
+            }
+
+            if ((dg->norm & CC_NORM_BITS) == CC_KD_NORM_TYPE) {
+                eg->kdtree = CC_SAFE_MALLOC (1, CCkdtree);
+                if (!eg->kdtree) {
+                    fprintf (stderr, "out of memory in init_edgegenerator\n");
+                    CC_FREE (eg->supply, int);
+                    return 1;
+                }
+                rval = CCkdtree_build (eg->kdtree, ncount, dg,
+                                       (double *) NULL);
+                if (rval) {
+                    fprintf (stderr, "CCkdtree_build failed\n");
+                    CC_FREE (eg->kdtree, CCkdtree);
+                    CC_FREE (eg->supply, int);
+                    return rval;
+                }
+            } else if ((dg->norm & CC_NORM_BITS) == CC_X_NORM_TYPE) {
+                eg->xnear = CC_SAFE_MALLOC (1, CCxnear);
+                if (!eg->xnear) {
+                    fprintf (stderr, "out of memory in init_edgegenerator\n");
+                    CC_FREE (eg->supply, int);
+                    return 1;
+                }
+                rval = CCedgegen_xnear_build (ncount, dg, (double *) NULL,
+                                              eg->xnear);
+                if (rval) {
+                    fprintf (stderr, "CCedgegen_xnear_build failed\n");
+                    CC_FREE (eg->xnear, CCxnear);
+                    CC_FREE (eg->supply, int);
+                    return rval;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_edgegenerator (CCtsp_edgegenerator *eg)
+#else
+void CCtsp_free_edgegenerator (eg)
+CCtsp_edgegenerator *eg;
+#endif
+{
+    printf ("free_edgegenerator\n"); fflush (stdout);
+
+    CC_IFFREE (eg->supply, int);
+
+    if (eg->kdtree)
+        CCkdtree_free (eg->kdtree);
+    if (eg->xnear)
+        CCedgegen_xnear_free (eg->ncount, eg->xnear);
+    if (eg->xprice) {
+        xprice_free (eg->xprice);
+        CC_FREE (eg->xprice, CCtsp_xnorm_pricer);
+    }
+    if (eg->adjobjspace) {
+        CC_FREE (eg->adjobjspace, CCtsp_genadjobj);
+        CC_IFFREE (eg->adj, CCtsp_genadj);
+    }
+
+    eg->dg = (CCdatagroup *) NULL;
+    eg->node_piest = (double *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_reset_edgegenerator (CCtsp_edgegenerator *eg, double *node_piest)
+#else
+int CCtsp_reset_edgegenerator (eg, node_piest)
+CCtsp_edgegenerator *eg;
+double *node_piest;
+#endif
+{
+    printf ("reset_edgegenerator\n"); fflush (stdout);
+
+    eg->node_piest = node_piest;
+    if (eg->nneighbors == CCtsp_PRICE_COMPLETE_GRAPH) {
+        eg->start = eg->current;
+        eg->supplyhead = -1;
+        if (eg->xprice) {
+            if (xprice_reset (eg->xprice, node_piest, eg->current)) {
+                fprintf (stderr, "xprice_reset failed\n");
+                return 1;
+            }
+            eg->supplycount = 0;
+        }
+    } else {
+        eg->start = eg->current;
+        eg->supplycount = 0;
+        eg->supplyhead = -1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_generate_edges (CCtsp_edgegenerator *eg, int nwant, int *pngot,
+        int *elist, int *elen, int *finished)
+#else
+int CCtsp_generate_edges (eg, nwant, pngot, elist, elen, finished)
+CCtsp_edgegenerator *eg;
+int nwant;
+int *pngot;
+int *elist;
+int *elen;
+int *finished;
+#endif
+{
+    int len, end;
+    int ngot = 0;
+    int rval;
+
+    printf ("generate_edges (%d)\n", nwant); fflush (stdout);
+
+    *finished = 0;
+    *pngot = 0;
+    if (!eg->node_piest) {
+        fprintf (stderr, "generate, but no node_piest\n");
+        return 1;
+    }
+
+    if (eg->nneighbors == CCtsp_PRICE_COMPLETE_GRAPH) {
+        if (eg->xprice) {
+            int *supply = eg->supply;
+            int supplyhead = eg->supplyhead;
+            int supplycount = eg->supplycount;
+            int current = eg->current;
+            int realcurrent;
+
+            while (ngot < nwant) {
+                if (supplyhead == supplycount || supplyhead == -1) {
+                    if (supplyhead != -1) {
+                        current++;
+                        if (current >= eg->ncount)
+                            current = 0;
+                        if (current == eg->start) {
+                            *pngot = ngot;
+                            *finished = 1;
+                            eg->supplyhead = supplyhead;
+                            eg->supplycount = supplycount;
+                            eg->current = current;
+                            return 0;
+                        }
+                        if (current == 0) {
+                            rval = xprice_reset (eg->xprice, eg->node_piest, 0);
+                            if (rval) {
+                                fprintf (stderr, "xprice_reset failed\n");
+                                return rval;
+                            }
+                        }
+                    }
+                    rval = xprice_node (eg->xprice, current, &supplycount,
+                                                                  supply);
+                    if (rval) {
+                        fprintf (stderr, "xprice_node failed\n");
+                        return rval;
+                    }
+                    supplyhead = 0;
+                }
+                realcurrent = eg->xprice->order[current];
+                while (supplyhead < supplycount && ngot < nwant) {
+                    len = CCutil_dat_edgelen (realcurrent, supply[supplyhead],
+                                              eg->dg);
+                    if (((double) len) - eg->node_piest[realcurrent]
+                                       - eg->node_piest[supply[supplyhead]] <
+                                                  CCtsp_GEN_PRICE_EPSILON) {
+                        elist[ngot*2] = realcurrent;
+                        elist[ngot*2+1] = supply[supplyhead];
+                        elen[ngot] = len;
+                        ngot++;
+                        if (ngot % 100000 == 0) {
+                            printf ("Y[%d]", current);
+                            fflush (stdout);
+                        }
+                    }
+                    supplyhead++;
+                }
+            }
+            eg->supplyhead = supplyhead;
+            eg->supplycount = supplycount;
+            eg->current = current;
+        } else {
+            int supplyhead = eg->supplyhead;
+            int current = eg->current;
+            int ncount = eg->ncount;
+
+            while (ngot < nwant) {
+                if (supplyhead == ncount || supplyhead == -1) {
+                    if (supplyhead != -1) {
+                        current++;
+                        if (current >= ncount)
+                            current = 0;
+                        if (current == eg->start) {
+                            *pngot = ngot;
+                            *finished = 1;
+                            eg->supplyhead = supplyhead;
+                            eg->current = current;
+                            return 0;
+                        }
+                    }
+                    supplyhead = current + 1;
+                }
+                if (supplyhead < ncount) {
+                    if (current == 0 && supplyhead == 15) {
+                        printf ("EVALUATE (0,15): \n"); fflush (stdout);
+                        len = CCutil_dat_edgelen (current, supplyhead, eg->dg);
+                        printf ("  Length: %d\n", len);
+                        printf ("  Estimate: %f\n",
+                            len - eg->node_piest[current]
+                                - eg->node_piest[supplyhead]);
+                        if (len - eg->node_piest[current] -
+                              eg->node_piest[supplyhead] <
+                              CCtsp_GEN_PRICE_EPSILON) {
+                            printf ("  TAKE IT\n");
+                        } else {
+                            printf ("  LEAVE IT\n");
+                        }
+                        fflush (stdout);
+                    }
+                    len = CCutil_dat_edgelen (current, supplyhead, eg->dg);
+                    if (len - eg->node_piest[current] -
+                          eg->node_piest[supplyhead] <
+                          CCtsp_GEN_PRICE_EPSILON) {
+                        elist[ngot*2] = current;
+                        elist[ngot*2+1] = supplyhead;
+                        elen[ngot] = len;
+                        if (current == 0 && supplyhead == 15) {
+                            printf ("    GRAB 0 15: %d\n", ngot);
+                            fflush (stdout);
+                        }
+                        ngot++;
+                    }
+                    supplyhead++;
+                }
+            }
+            eg->supplyhead = supplyhead;
+            eg->current = current;
+        }
+    } else if (eg->adj) {
+        int supplyhead = eg->supplyhead;
+        int supplycount = eg->supplycount;
+        int current = eg->current;
+        CCtsp_genadj *currentadj;
+
+        while (ngot < nwant) {
+            if (supplyhead == supplycount || supplyhead == -1) {
+                if (supplyhead != -1) {
+                    current++;
+                    if (current >= eg->ncount)
+                        current = 0;
+                    if (current == eg->start) {
+                        *pngot = ngot;
+                        *finished = 1;
+                        eg->supplyhead = supplyhead;
+                        eg->supplycount = supplycount;
+                        eg->current = current;
+                        return 0;
+                    }
+                }
+                supplyhead = 0;
+                supplycount = eg->adj[current].deg;
+            }
+            currentadj = &(eg->adj[current]);
+            while (supplyhead < supplycount && ngot < nwant) {
+                end = currentadj->list[supplyhead].end;
+                len = currentadj->list[supplyhead].len;
+                if (((double) len) - eg->node_piest[current] -
+                        eg->node_piest[end] < CCtsp_GEN_PRICE_EPSILON) {
+                    elist[ngot*2] = current;
+                    elist[ngot*2+1] = end;
+                    elen[ngot] = len;
+                    ngot++;
+                }
+                supplyhead++;
+            }
+        }
+        eg->supplyhead = supplyhead;
+        eg->supplycount = supplycount;
+        eg->current = current;
+    } else {
+        int *supply = eg->supply;
+        int supplyhead = eg->supplyhead;
+        int supplycount = eg->supplycount;
+        int current = eg->current;
+
+        while (ngot < nwant) {
+            if (supplyhead == supplycount || supplyhead == -1) {
+                if (supplyhead != -1) {
+                    current++;
+                    if (current >= eg->ncount)
+                        current = 0;
+                    if (current == eg->start) {
+                        *pngot = ngot;
+                        *finished = 1;
+                        eg->supplyhead = supplyhead;
+                        eg->supplycount = supplycount;
+                        eg->current = current;
+                        return 0;
+                    }
+                }
+                if (eg->kdtree) {
+                    rval = CCkdtree_node_k_nearest (eg->kdtree, eg->ncount,
+                            current, eg->nneighbors, eg->dg, (double *) NULL,
+                            supply);
+                    if (rval) {
+                        fprintf (stderr, "CCkdtree_node_k_nearest failed\n");
+                        return rval;
+                    }
+                } else if (eg->xnear) {
+                    rval = CCedgegen_x_node_k_nearest (eg->xnear, current,
+                            eg->nneighbors, eg->ncount, supply);
+                    if (rval) {
+                        fprintf (stderr, "CCedgegen_x_node_k_nearest failed\n");
+                        return 1;
+                    }
+                } else {
+                    rval = CCedgegen_junk_node_k_nearest (eg->dg,
+                               (double *) NULL, current, eg->nneighbors,
+                               eg->ncount, supply);
+                    if (rval) {
+                        fprintf (stderr, "junk_node_k_nearest failed\n");
+                        return 1;
+                    }
+                }
+                supplyhead = 0;
+                supplycount = eg->nneighbors;
+            }
+
+            if (supply[supplyhead] > current) {
+                len = CCutil_dat_edgelen (current, supply[supplyhead], eg->dg);
+                if (((double) len) - eg->node_piest[current] -
+                   eg->node_piest[supply[supplyhead]] <
+                                               CCtsp_GEN_PRICE_EPSILON) {
+                    elist[ngot*2] = current;
+                    elist[ngot*2+1] = supply[supplyhead];
+                    elen[ngot] = len;
+                    ngot++;
+                }
+            }
+            supplyhead++;
+        }
+        eg->supplyhead = supplyhead;
+        eg->supplycount = supplycount;
+        eg->current = current;
+    }
+
+    *pngot = ngot;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int xprice_build (int ncount, CCdatagroup *dat, CCtsp_xnorm_pricer *xp)
+#else
+static int xprice_build (ncount, dat, xp)
+int ncount;
+CCdatagroup *dat;
+CCtsp_xnorm_pricer *xp;
+#endif
+{
+    int i;
+
+    printf ("xprice_build\n");
+    fflush (stdout);
+
+    xp->pi = (double *) NULL;
+    xp->order = (int *) NULL;
+    xp->xminuspi = (CCtsp_xnorm_pricer_val *) NULL;
+    xp->xminuspi_space = (CCtsp_xnorm_pricer_val *) NULL;
+    xp->invxminuspi = (int *) NULL;
+
+    if (((dat->norm) & CC_NORM_BITS) != CC_KD_NORM_TYPE &&
+        ((dat->norm) & CC_NORM_BITS) != CC_X_NORM_TYPE) {
+        fprintf (stderr, "cannot run xprice_build with norm %d\n", dat->norm);
+        xprice_free (xp);
+        return 1;
+    }
+
+    xp->ncount = ncount;
+    xp->dat = dat;
+
+    xp->pi = CC_SAFE_MALLOC (ncount, double);
+    if (!xp->pi) {
+        fprintf (stderr, "out of memory in xprice_build\n");
+        xprice_free (xp);
+        return 1;
+    }
+
+    xp->order = CC_SAFE_MALLOC (ncount, int);
+    if (!xp->order) {
+        fprintf (stderr, "out of memory in xprice_build\n");
+        xprice_free (xp);
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        xp->order[i] = i;
+    CCutil_double_perm_quicksort (xp->order, dat->x, ncount);
+
+    xp->xminuspi_space = CC_SAFE_MALLOC (ncount + 1, CCtsp_xnorm_pricer_val);
+    if (!xp->xminuspi_space) {
+        fprintf (stderr, "out of memory in xprice_build\n");
+        xprice_free (xp);
+        return 1;
+    }
+
+    xp->invxminuspi = CC_SAFE_MALLOC (ncount, int);
+    if (!xp->invxminuspi) {
+        fprintf (stderr, "out of memory in xprice_build\n");
+        xprice_free (xp);
+        return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int xprice_reset (CCtsp_xnorm_pricer *xp, double *pi, int currentnode)
+#else
+static int xprice_reset (xp, pi, currentnode)
+CCtsp_xnorm_pricer *xp;
+double *pi;
+int currentnode;
+#endif
+{
+    int i;
+    double *xpi = (double *) NULL;
+    int *xpiperm = (int *) NULL;
+    int count = xp->ncount - currentnode;
+    int rval = 0;
+
+    printf ("xprice_reset (%d)\n", currentnode);
+    fflush (stdout);
+
+    for (i = 0; i < xp->ncount; i++)
+        xp->pi[i] = pi[i];
+
+    xpi = CC_SAFE_MALLOC (count, double);
+    xpiperm = CC_SAFE_MALLOC (count, int);
+    if (!xpi || !xpiperm) {
+        fprintf (stderr, "out of memory in xprice_build\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (xp->dat->norm == CC_GEOGRAPHIC) {
+        for (i = 0; i < count; i++) {
+            xpi[i] =
+             (CC_GEOGRAPHIC_SCALE * xp->dat->x[xp->order[i + currentnode]]) -
+                                         pi[xp->order[i + currentnode]];
+            xpiperm[i] = i;
+        }
+    } else if (xp->dat->norm == CC_ATT) {
+        for (i = 0; i < count; i++) {
+            xpi[i] =
+             (CC_ATT_SCALE * xp->dat->x[xp->order[i + currentnode]]) -
+                                  pi[xp->order[i + currentnode]];
+            xpiperm[i] = i;
+        }
+    } else {
+        for (i = 0; i < count; i++) {
+            xpi[i] = xp->dat->x[xp->order[i + currentnode]] -
+                             pi[xp->order[i + currentnode]];
+            xpiperm[i] = i;
+        }
+    }
+
+    CCutil_double_perm_quicksort (xpiperm, xpi, count);
+    for (i = 0; i < count; i++)
+        xp->invxminuspi[xp->order[xpiperm[i] + currentnode]] = i;
+
+    for (i = 1; i < count - 1; i++) {
+        xp->xminuspi_space[i].val = xpi[xpiperm[i]];
+        xp->xminuspi_space[i].index = xp->order[xpiperm[i] + currentnode];
+        xp->xminuspi_space[i].next = &(xp->xminuspi_space[i + 1]);
+        xp->xminuspi_space[i].prev = &(xp->xminuspi_space[i - 1]);
+    }
+    xp->xminuspi_space[0].val = xpi[xpiperm[0]];
+    xp->xminuspi_space[0].index = xp->order[xpiperm[0] + currentnode];
+    xp->xminuspi_space[0].next = &(xp->xminuspi_space[1]);
+    xp->xminuspi_space[0].prev = (CCtsp_xnorm_pricer_val *) NULL;
+    xp->xminuspi_space[count - 1].val = xpi[xpiperm[count - 1]];
+    xp->xminuspi_space[count - 1].index =
+     xp->order[xpiperm[count - 1] + currentnode];
+    xp->xminuspi_space[count - 1].next = &(xp->xminuspi_space[count]);
+    xp->xminuspi_space[count - 1].prev = &(xp->xminuspi_space[count - 2]);
+    xp->xminuspi_space[count].val = 1e30;  /* This anchors the linked list */
+    xp->xminuspi_space[count].next = (CCtsp_xnorm_pricer_val *) NULL;
+    xp->xminuspi_space[count].prev = &(xp->xminuspi_space[count - 1]);
+    xp->xminuspi = xp->xminuspi_space;
+
+CLEANUP:
+
+    CC_IFFREE (xpi, double);
+    CC_IFFREE (xpiperm, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int xprice_node (CCtsp_xnorm_pricer *xp, int n, int *count, int *nlist)
+#else
+static int xprice_node (xp, n, count, nlist)
+CCtsp_xnorm_pricer *xp;
+int n;
+int *count;
+int *nlist;
+#endif
+{
+    int k;
+    double kval;
+    CCtsp_xnorm_pricer_val *xnp;
+    double scale;
+
+    if (xp->dat->norm == CC_GEOGRAPHIC)
+        scale = CC_GEOGRAPHIC_SCALE;
+    else if (xp->dat->norm == CC_ATT)
+        scale = CC_ATT_SCALE;
+    else
+        scale = 1.0;
+
+    *count = 0;
+
+    k = xp->order[n];
+    kval = xp->pi[k] + (scale * xp->dat->x[k]);
+
+    xnp = xp->xminuspi_space + xp->invxminuspi[k];  /* Delete node k */
+    if (xnp == xp->xminuspi)
+        xp->xminuspi = xnp->next;
+    else
+        xnp->prev->next = xnp->next;
+    xnp->next->prev = xnp->prev;
+
+    for (xnp = xp->xminuspi; xnp->val < kval; xnp = xnp->next)
+        nlist[(*count)++] = xnp->index;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void xprice_free (CCtsp_xnorm_pricer *xp)
+#else
+static void xprice_free (xp)
+CCtsp_xnorm_pricer *xp;
+#endif
+{
+    if (xp->order)
+        CC_FREE (xp->order, int);
+    if (xp->pi)
+        CC_FREE (xp->pi, double);
+    if (xp->xminuspi_space)
+        CC_FREE (xp->xminuspi_space, CCtsp_xnorm_pricer_val);
+    if (xp->invxminuspi)
+        CC_FREE (xp->invxminuspi, int);
+    xp->ncount = 0;
+    xp->dat = (CCdatagroup *) NULL;
+    xp->xminuspi = (CCtsp_xnorm_pricer_val *) NULL;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_edgelist_to_genadj (int ncount, int ecount, int *elist, int *elen,
+        CCtsp_genadj **adj, CCtsp_genadjobj **adjobjspace)
+#else
+int CCtsp_edgelist_to_genadj (ncount, ecount, elist, elen, adj, adjobjspace)
+int ncount;
+int ecount;
+int *elist;
+int *elen;
+CCtsp_genadj **adj;
+CCtsp_genadjobj **adjobjspace;
+#endif
+{
+    int i, k, k1, k2;
+    CCtsp_genadj *a;
+    CCtsp_genadjobj *p;
+
+    *adj = CC_SAFE_MALLOC (ncount, CCtsp_genadj);
+    if (!(*adj)) {
+        fprintf (stderr, "out of memory in edgelist_to_genadj\n");
+        return 1;
+    }
+    a = *adj;
+
+    for (i = 0; i < ncount; i++)
+        a[i].deg = 0;
+    for (i = 0; i < ecount; i++) {
+        if (elist[2*i] > elist[2*i + 1])
+            a[elist[2*i + 1]].deg++;
+        else
+            a[elist[2*i]].deg++;
+    }
+
+    *adjobjspace = CC_SAFE_MALLOC (ecount, CCtsp_genadjobj);
+    if (!(*adjobjspace)) {
+        fprintf (stderr, "out of memory in edgelist_to_genadj\n");
+        CC_IFFREE (*adj, CCtsp_genadj);
+        return 1;
+    }
+
+    p = *adjobjspace;
+    for (i = 0; i < ncount; i++) {
+        a[i].list = p;
+        p += a[i].deg;
+        a[i].deg = 0;
+    }
+    for (i = 0; i < ecount; i++) {
+        k1 = elist[2*i];
+        k2 = elist[2*i + 1];
+        if (k1 > k2) {
+            CC_SWAP (k1, k2, k);
+        }
+        a[k1].list[a[k1].deg].end = k2;
+        a[k1].list[a[k1].deg].len = elen[i];
+        a[k1].deg++;
+    }
+
+    return 0;
+}
diff --git a/contrib/blossom/concorde97/TSP/poolcat.c b/contrib/blossom/concorde97/TSP/poolcat.c
new file mode 100644
index 0000000000000000000000000000000000000000..ea343e08b6c7667c5adaf98663d7d2a70b2d74ba
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/poolcat.c
@@ -0,0 +1,288 @@
+/***************************************************************************/
+/*                                                                         */
+/*                         MERGE CUTPOOLS                                  */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: May 2, 1997                                                      */
+/*                                                                         */
+/*  SEE short decsribtion in usage ().                                     */
+/*                                                                         */
+/*  Link with:                                                             */
+/*    SEE Makefile                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+
+static int seed = 0;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+
+static void
+    usage (char *f);
+
+#else
+
+int
+    main ();
+
+static void
+    usage ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    double szeit;
+    int i, k, count;
+    CCtsp_lpcut_in *c, *cnext;
+    CCtsp_lpcut_in *cuts   = (CCtsp_lpcut_in *) NULL;
+    CCtsp_lpcuts *pool     = (CCtsp_lpcuts *) NULL;
+    CCtsp_lpcuts *nextpool = (CCtsp_lpcuts *) NULL;
+    CC_SFILE *in;
+    int ncount;
+    int textout, textin;
+    int *ptour = (int *) NULL;
+    int *qtour = (int *) NULL;
+    int *perm  = (int *) NULL;
+    int rval = 0;
+
+    if (ac < 2) {
+        usage (*av);
+        return 0;
+    }
+
+    szeit = CCutil_zeit ();
+    seed = (int) CCutil_real_zeit ();
+    CCutil_sprand (seed);
+
+    k = 1;
+    if (av[k][0] == '-' && av[k][1] == 't') {
+        CCdatagroup dat;
+        printf ("Read master ...\n");
+        if (CCutil_getmaster (av[k+1], &ncount, &dat, &ptour)) {
+            fprintf (stderr, "CCutil_getmaster failed\n");
+            return 1;
+        }
+        CCutil_freedatagroup (ncount, &dat);
+        textout = 1;
+        k += 2;
+    } else {
+        textout = 0;
+    }
+
+    if (av[k][0] == '-' && av[k][1] == 's') {
+        CCdatagroup dat;
+        printf ("Read master ...\n");
+        if (CCutil_getmaster (av[k+1], &ncount, &dat, &qtour)) {
+            fprintf (stderr, "CCutil_getmaster failed\n");
+            return 1;
+        }
+        CCutil_freedatagroup (ncount, &dat);
+        textin = 1;
+        k += 2;
+    } else {
+        textin = 0;
+    }
+
+    if (av[k][0] == '-' && av[k][1] == 'p') {
+        FILE *tin = fopen (av[k+1], "r");
+
+        printf ("Read permutation tour ...\n");
+        if (!tin) {
+            fprintf (stderr, "could not open %s for reading\n", av[k+1]);
+            rval = 1; goto CLEANUP;
+        }
+
+        if (fscanf (tin, "%d", &ncount) != 1) {
+            fprintf (stderr, "perm file in wrong format\n");
+            rval = 1; fclose (tin); goto CLEANUP;
+        }
+        perm = CC_SAFE_MALLOC (ncount, int);
+        if (!perm) {
+            fprintf (stderr, "out of memory in main\n");
+            rval = 1; fclose (tin); goto CLEANUP;
+        }
+        for (i = 0; i < ncount; i++) {
+            if (fscanf (tin, "%d", &(perm[i])) != 1) {
+                fprintf (stderr, "perm file in wrong format\n");
+                rval = 1; fclose (tin); goto CLEANUP;
+            }
+        }
+        fclose (tin);
+        k += 2;
+    }
+
+    if (textin) {
+        printf ("Number of Nodes: %d\n", ncount); fflush (stdout);
+
+        rval = CCtsp_init_cutpool (ncount, (char *) NULL, &pool);
+        if (rval) {
+            fprintf (stderr, "CCtsp_init_cutpool failed\n"); goto CLEANUP;
+        }
+
+        cuts = (CCtsp_lpcut_in *) NULL;
+        rval = CCtsp_file_cuts (av[k], &cuts, &count, ncount, qtour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_file_cuts failed\n"); goto CLEANUP;
+        }
+        printf ("File has %d cuts\n", count); fflush (stdout);
+        for (c = cuts; c; c = cnext) {
+            cnext = c->next;
+            rval = CCtsp_add_to_cutpool_lpcut_in (pool, c);
+            if (rval) {
+                fprintf (stderr, "CCtsp_add_to_cutpool_lpcut_in failed\n");
+                goto CLEANUP;
+            }
+            CCtsp_free_lpcut_in (c);
+            CC_FREE (c, CCtsp_lpcut_in);
+        }
+        k++;
+    } else {
+        in = CCutil_sopen (av[k], "r");
+        if (!in) {
+            fprintf (stderr, "sopen failed\n"); goto CLEANUP;
+        }
+        if (CCutil_sread_int (in, (unsigned int *) &ncount)) {
+            fprintf (stderr, "CCutil_sread_int failed\n");
+            CCutil_sclose (in);
+            return 1;
+        }
+        CCutil_sclose (in);
+        printf ("Number of Nodes: %d\n", ncount); fflush (stdout);
+
+        rval = CCtsp_init_cutpool (ncount, av[k], &pool);
+        if (rval) {
+            fprintf (stderr, "CCtsp_init_cutpool failed\n"); goto CLEANUP;
+        }
+        printf ("Initial Pool: %d cuts\n", pool->cutcount);
+        fflush (stdout);
+        k++;
+    }
+
+    for (; k < ac; k++) {
+        printf ("Adding Pool %s ... ", av[k]);
+        fflush (stdout);
+
+        if (textin) {
+            cuts = (CCtsp_lpcut_in *) NULL;
+            rval = CCtsp_file_cuts (av[k], &cuts, &count, ncount, qtour);
+            if (rval) {
+                fprintf (stderr, "CCtsp_file_cuts failed\n"); goto CLEANUP;
+            }
+            for (c = cuts; c; c = cnext) {
+                cnext = c->next;
+                rval = CCtsp_add_to_cutpool_lpcut_in (pool, c);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_add_to_cutpool_lpcut_in failed\n");
+                    goto CLEANUP;
+                }
+                CCtsp_free_lpcut_in (c);
+                CC_FREE (c, CCtsp_lpcut_in);
+            }
+        } else {
+            rval = CCtsp_init_cutpool (ncount, av[k], &nextpool);
+            if (rval) {
+                fprintf (stderr, "CCtsp_init_cutpool failed\n"); goto CLEANUP;
+            }
+
+            for (i = 0; i < nextpool->cutcount; i++) {
+                rval = CCtsp_add_to_cutpool (pool, nextpool,
+                                             &(nextpool->cuts[i]));
+                if (rval) {
+                    fprintf (stderr, "CCtsp_add_to_cutpool failed\n");
+                    goto CLEANUP;
+                }
+            }
+            CCtsp_free_cutpool (&nextpool);
+        }
+        printf ("%d\n", pool->cutcount); fflush (stdout);
+    }
+
+
+    printf ("Final Pool: %d cuts\n", pool->cutcount);
+    fflush (stdout);
+
+    if (textout) {
+        printf ("Write text file ...\n"); fflush (stdout);
+        if (perm) {
+            int *pperm = (int *) NULL;
+
+            pperm = CC_SAFE_MALLOC (ncount, int);
+            if (!pperm) {
+                fprintf (stderr, "out of memory in main\n");
+                rval = 1; goto CLEANUP;
+            }
+            for (i = 0; i < ncount; i++) {
+                pperm[i] = perm[ptour[i]];
+            }
+            for (i = 0; i < ncount; i++) {
+                ptour[i] = pperm[i];
+            }
+            CC_FREE (pperm, int);
+        }
+        rval = CCtsp_file_cuts_write ("merge.txt", pool, ptour);
+        if (rval) {
+            fprintf (stderr, "CCtsp_file_cuts_write failed\n");
+            goto CLEANUP;
+        }
+    } else {
+        rval = CCtsp_write_cutpool (ncount, "merge.pul", pool);
+        if (rval) {
+            fprintf (stderr, "CCtsp_write_cutpool failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    printf ("Running Time: %.2f seconds\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    if (pool) {
+        CCtsp_free_cutpool (&pool);
+    }
+    if (nextpool) {
+        CCtsp_free_cutpool (&nextpool);
+    }
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: CCutil_bigchunk_free_world failed\n");
+        return 1;
+    }
+    CC_IFFREE (ptour, int);
+    CC_IFFREE (qtour, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "Usage: %s [-t] pool1 pool2 ... \n", f);
+    fprintf (stderr, "       -t f:  to write a text file specify a master\n");
+    fprintf (stderr, "       -p f:  to permute nodes when writing text\n");
+    fprintf (stderr, "       -s f:  to read text files specify a master\n");
+    fprintf (stderr, "Note: merged pool will be written merge.pul (.txt)\n");
+    fprintf (stderr, "      the master files are used to map the nodes\n");
+    fprintf (stderr, "      the permuation given by p can be used to\n");
+    fprintf (stderr, "      handle the different node orders in dat and tsp\n");
+}
diff --git a/contrib/blossom/concorde97/TSP/prob_io.c b/contrib/blossom/concorde97/TSP/prob_io.c
new file mode 100644
index 0000000000000000000000000000000000000000..dc6ce512a78b9c1779c947c96997445bdfdae672
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/prob_io.c
@@ -0,0 +1,1741 @@
+/**************************************************************************/
+/*                                                                        */
+/* Date: April 19, 1996  (dave)                                           */
+/*       August 28, 1996 (bico)                                           */
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/* CCtsp_PROB_FILE                                                        */
+/*     *CCtsp_prob_read (char *f, int n),                                 */
+/*     *CCtsp_prob_read_name (char *f),                                   */
+/*     *CCtsp_prob_write (char *f, int n);                                */
+/*     *CCtsp_prob_write_name (char *fname, char *pname);                 */
+/*                                                                        */
+/* int                                                                    */
+/*     CCtsp_prob_file_delete (char *f, int n),                           */
+/*     CCtsp_prob_getname (CCtsp_PROB_FILE *p, char *name),               */
+/*     CCtsp_prob_getid (CCtsp_PROB_FILE *p, int *id),                    */
+/*     CCtsp_prob_getparent (CCtsp_PROB_FILE *p, int *parent),            */
+/*     CCtsp_prob_getub (CCtsp_PROB_FILE *p, double *ub),                 */
+/*     CCtsp_prob_getlb (CCtsp_PROB_FILE *p, double *lb),                 */
+/*     CCtsp_prob_getexactlb (CCtsp_PROB_FILE *p, CCbigguy *lb),          */
+/*     CCtsp_prob_getnnodes (CCtsp_PROB_FILE *p, int *nnodes),            */
+/*     CCtsp_prob_getchildren (CCtsp_PROB_FILE *p, int *child0,           */
+/*             int *child1),                                              */
+/*     CCtsp_prob_getreal (CCtsp_PROB_FILE *p, int *real),                */
+/*     CCtsp_prob_getprocessed (CCtsp_PROB_FILE *p, int *processed),      */
+/*     CCtsp_prob_getinfeasible (CCtsp_PROB_FILE *p, int *infeasible),    */
+/*     CCtsp_prob_gettour (CCtsp_PROB_FILE *p, int **tour),               */
+/*     CCtsp_prob_getedges (CCtsp_PROB_FILE *p, int *nedges, int **elist, */
+/*             int **elen),                                               */
+/*     CCtsp_prob_getcuts (CCtsp_PROB_FILE *p, CCtsp_lp *lp);             */
+/*     CCtsp_prob_getbasis (CCtsp_PROB_FILE *p, int *ccount, int *rcount, */
+/*             int **cstat, int **rstat),                                 */
+/*     CCtsp_prob_getnorms (CCtsp_PROB_FILE *p, int *rcount,              */
+/*             double **dnorm),                                           */
+/*     CCtsp_prob_getexactdual (CCtsp_PROB_FILE *p, ncount,               */
+/*             CCtsp_bigdual **d)                                         */
+/*     CCtsp_prob_gethistory (CCtsp_PROB_FILE *p, int *depth,             */
+/*             CCtsp_branchobj **history)                                 */
+/*     CCtsp_prob_rclose (CCtsp_PROB_FILE *p),                            */
+/*                                                                        */
+/*     CCtsp_prob_putname (CCtsp_PROB_FILE *p, char *name),               */
+/*     CCtsp_prob_putid (CCtsp_PROB_FILE *p, int id),                     */
+/*     CCtsp_prob_putparent (CCtsp_PROB_FILE *p, int parent),             */
+/*     CCtsp_prob_putub (CCtsp_PROB_FILE *p, double ub),                  */
+/*     CCtsp_prob_putlb (CCtsp_PROB_FILE *p, double lb),                  */
+/*     CCtsp_prob_putexactlb (CCtsp_PROB_FILE *p, CCbigguy lb),           */
+/*     CCtsp_prob_putnnodes (CCtsp_PROB_FILE *p, int nnodes),             */
+/*     CCtsp_prob_putchildren (CCtsp_PROB_FILE *p, int child0,            */
+/*             int child1),                                               */
+/*     CCtsp_prob_putreal (CCtsp_PROB_FILE *p, int real),                 */
+/*     CCtsp_prob_putprocessed (CCtsp_PROB_FILE *p, int processed),       */
+/*     CCtsp_prob_putinfeasible (CCtsp_PROB_FILE *p, int infeasible),     */
+/*     CCtsp_prob_puttour (CCtsp_PROB_FILE *p, int *tour),                */
+/*     CCtsp_prob_putedges (CCtsp_PROB_FILE *p, int ecount, int *elist,   */
+/*             int *elen);                                                */
+/*     CCtsp_prob_putcuts (CCtsp_PROB_FILE *p, CCtsp_lp *lp);             */
+/*     CCtsp_prob_putbasis (CCtsp_PROB_FILE *p, int ccount, int rcount,   */
+/*             int *cstat, int *rstat),                                   */
+/*     CCtsp_prob_putnorms (CCtsp_PROB_FILE *p, int rcount, double *dnorm)*/
+/*     CCtsp_prob_putexact_dual (CCtsp_PROB_FILE *p,                      */
+/*             CCtsp_bigdual *exact_dual)                                 */
+/*     CCtsp_prob_puthistory (CCtsp_PROB_FILE *p, int depth,              */
+/*             CCtsp_branchobj *history)                                  */
+/*     CCtsp_prob_wclose (CCtsp_PROB_FILE *p),                            */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+#include "bigguy.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    prob_name (char *buf, int buflen, char *f, int n),
+    write_header (CCtsp_PROB_FILE *p);
+
+static void
+    prob_init (CCtsp_PROB_FILE *p);
+
+#else
+
+static int
+    prob_name (),
+    write_header ();
+
+static void
+    prob_init ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_file_delete (char *f, int n)
+#else
+int CCtsp_prob_file_delete (f, n)
+char *f;
+int n;
+#endif
+{
+    char nambuf[1024];
+    int sval;
+
+    if (prob_name (nambuf, sizeof (nambuf), f, n)) return 1;
+    printf ("Delete file: %s\n", nambuf);
+    fflush (stdout);
+    sval = CCutil_sdelete_file (nambuf);
+    if (sval) {
+        printf ("Prob file %s could not be deleted\n", nambuf);
+        fflush (stdout);
+    }
+    sval = CCutil_sdelete_file_backup (nambuf);
+    if (!sval) {
+        printf ("Deleted backup to file: %s\n", nambuf);
+        fflush (stdout);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+CCtsp_PROB_FILE *CCtsp_prob_read (char *f, int n)
+#else
+CCtsp_PROB_FILE *CCtsp_prob_read (f, n)
+char *f;
+int n;
+#endif
+{
+    char nambuf[1024];
+
+    if (prob_name (nambuf, sizeof (nambuf), f, n))
+        return (CCtsp_PROB_FILE *) NULL;
+
+    return CCtsp_prob_read_name (nambuf);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+CCtsp_PROB_FILE *CCtsp_prob_read_name (char *f)
+#else
+CCtsp_PROB_FILE *CCtsp_prob_read_name (f)
+char *f;
+#endif
+{
+    CCtsp_PROB_FILE *p = (CCtsp_PROB_FILE *) NULL;
+    unsigned char version;
+    int i;
+
+    printf ("Read File %s\n", f); fflush (stdout);
+
+    p = CC_SAFE_MALLOC (1, CCtsp_PROB_FILE);
+    if (p == (CCtsp_PROB_FILE *) NULL) goto CLEANUP;
+    prob_init (p);
+
+    p->f = CCutil_sopen (f, "r");
+    if (!p->f) goto CLEANUP;
+
+    if (CCutil_sread_char (p->f, &version)) goto CLEANUP;
+    for (i = 0; i < CCtsp_PROB_FILE_NAME_LEN; i++)
+        if (CCutil_sread_char (p->f, (unsigned char *) &p->name[i]))
+            goto CLEANUP;
+
+    switch (version) {
+      case 1:
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->parent))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->id))
+            goto CLEANUP;
+        if (CCutil_sread_double (p->f, &p->ub))
+            goto CLEANUP;
+        if (CCutil_sread_double (p->f, &p->lb))
+            goto CLEANUP;
+        if (CCbigguy_sread (p->f, &p->exactlb))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->nnodes))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->child0))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->child1))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->real))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->processed))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->infeasible))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.dat))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.edge))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.fulladj))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.cut))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.tour))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.basis))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.norms))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.fix))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.exactdual))
+            goto CLEANUP;
+        if (CCutil_sread_int (p->f, (unsigned int *) &p->offsets.history))
+            goto CLEANUP;
+        break;
+      default:
+        fprintf (stderr, "Unknown problem version %ud\n", version);
+        goto CLEANUP;
+    }
+    return p;
+
+  CLEANUP:
+    if (p) {
+        if (p->f) {
+            CCutil_sclose (p->f);
+        }
+        CC_FREE (p, CCtsp_PROB_FILE);
+    }
+    return (CCtsp_PROB_FILE *) NULL;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+CCtsp_PROB_FILE *CCtsp_prob_write (char *f, int n)
+#else
+CCtsp_PROB_FILE *CCtsp_prob_write (f, n)
+char *f;
+int n;
+#endif
+{
+    char nambuf[1024];
+
+    if (prob_name (nambuf, sizeof (nambuf), f, n))
+        return (CCtsp_PROB_FILE *) NULL;
+
+    return CCtsp_prob_write_name (nambuf, f);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+CCtsp_PROB_FILE *CCtsp_prob_write_name (char *fname, char *pname)
+#else
+CCtsp_PROB_FILE *CCtsp_prob_write_name (fname, pname)
+char *fname, *pname;
+#endif
+{
+    CCtsp_PROB_FILE *p = (CCtsp_PROB_FILE *) NULL;
+    int i;
+
+    printf ("Write File %s\n", fname); fflush (stdout);
+
+    p = CC_SAFE_MALLOC (1, CCtsp_PROB_FILE);
+    if (p == (CCtsp_PROB_FILE *) NULL) goto CLEANUP;
+    prob_init (p);
+    for (i = 0; pname[i] && i < CCtsp_PROB_FILE_NAME_LEN - 1; i++)
+        p->name[i] = pname[i];
+    p->name[i] = '\0';
+
+    p->f = CCutil_sopen (fname, "w");
+    if (!p->f) goto CLEANUP;
+
+    if (write_header (p)) {
+        printf ("write_header failed\n");
+        goto CLEANUP;
+    }
+
+    return p;
+
+CLEANUP:
+    if (p) {
+        if (p->f) {
+            CCutil_sclose (p->f);
+        }
+        CC_FREE (p, CCtsp_PROB_FILE);
+    }
+    return (CCtsp_PROB_FILE *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int write_header (CCtsp_PROB_FILE *p)
+#else
+static int write_header (p)
+CCtsp_PROB_FILE *p;
+#endif
+{
+    int  i;
+
+    if (CCutil_srewind (p->f)) return 1;
+    if (CCutil_swrite_char (p->f, (unsigned char) CCtsp_PROB_IO_VERSION)) return 1;
+    for (i = 0; i < CCtsp_PROB_FILE_NAME_LEN; i++) {
+        if (CCutil_swrite_char (p->f, (unsigned char) p->name[i])) return 1;
+    }
+    if (CCutil_swrite_int (p->f, (unsigned int) p->parent)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->id)) return 1;
+    if (CCutil_swrite_double (p->f, p->ub)) return 1;
+    if (CCutil_swrite_double (p->f, p->lb)) return 1;
+    if (CCbigguy_swrite (p->f, p->exactlb)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->nnodes)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->child0)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->child1)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->real)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->processed)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->infeasible)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.dat)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.edge)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.fulladj)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.cut)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.tour)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.basis)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.norms)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.fix)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.exactdual)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) p->offsets.history)) return 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int prob_name (char *buf, int buflen, char *f, int n)
+#else
+static int prob_name (buf, buflen, f, n)
+char *buf;
+int buflen;
+char *f;
+int n;
+#endif
+{
+    int l = strlen(f);
+    int lastslash;
+    int i;
+    int d;
+
+    if (l + 5 > buflen || n >= 1000 + 26*36*36 || n < 0) {
+        fprintf (stderr, "Cannot generate filename for %s node %d\n",
+                 f, n);
+        return -1;
+    }
+
+    for (i = 0, lastslash = -1; i < l; i++) {
+        if (f[i] == '/') lastslash = i;
+        buf[i] = f[i];
+    }
+    if (l > lastslash + 9) l = lastslash + 9;
+    for (i = lastslash+1; i < l; i++) {
+        if (buf[i] == '.') buf[i] = '_';
+    }
+    buf[l++] = '.';
+    if (n < 1000) {
+        d = n/100;
+        buf[l++] = '0' + ((unsigned char) d);
+        n -= d*100;
+        d = n/10;
+        buf[l++] = '0' + ((unsigned char) d);
+        n -= d*10;
+        d = n;
+        buf[l++] = '0' + ((unsigned char) d);
+    } else {
+        n -= 1000;
+        d = n/1296;
+        buf[l++] = 'a' + ((unsigned char) d);
+        n -= d*1296;
+        d = n/36;
+        buf[l++] = (d < 10) ? '0'+((unsigned char) d)
+                            : 'a'+((unsigned char) (d-10));
+        n -= d*36;
+        d = n;
+        buf[l++] = (d < 10) ? '0'+((unsigned char) d)
+                            : 'a'+((unsigned char) (d-10));
+    }
+    buf[l] = '\0';
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void prob_init (CCtsp_PROB_FILE *p)
+#else
+static void prob_init (p)
+CCtsp_PROB_FILE *p;
+#endif
+{
+    int i;
+
+    p->f = (CC_SFILE *) NULL;
+    for (i = 0; i < CCtsp_PROB_FILE_NAME_LEN; i++)
+        p->name[i] = '\0';
+    p->id = -1;
+    p->parent = -1;
+    p->lb = -1.0;
+    p->ub = -1.0;
+    p->exactlb = CCbigguy_ZERO;
+    p->nnodes = -1;
+    p->child0 = -1;
+    p->child1 = -1;
+    p->real = -1;
+    p->processed = -1;
+    p->infeasible = -1;
+    p->offsets.dat = -1;
+    p->offsets.edge = -1;
+    p->offsets.fulladj = -1;
+    p->offsets.cut = -1;
+    p->offsets.tour = -1;
+    p->offsets.basis = -1;
+    p->offsets.norms = -1;
+    p->offsets.fix = -1;
+    p->offsets.exactdual = -1;
+    p->offsets.history = -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_rclose (CCtsp_PROB_FILE *p)
+#else
+int CCtsp_prob_rclose (p)
+CCtsp_PROB_FILE *p;
+#endif
+{
+    int rval;
+
+    rval = CCutil_sclose (p->f);
+
+    CC_FREE (p, CCtsp_PROB_FILE);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_wclose (CCtsp_PROB_FILE *p)
+#else
+int CCtsp_prob_wclose (p)
+CCtsp_PROB_FILE *p;
+#endif
+{
+    int rval;
+
+    rval = write_header (p);
+    if (rval) return rval;
+
+    rval = CCutil_sclose (p->f);
+
+    CC_FREE (p, CCtsp_PROB_FILE);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getname (CCtsp_PROB_FILE *p, char *name)
+#else
+int CCtsp_prob_getname (p, name)
+CCtsp_PROB_FILE *p;
+char *name;
+#endif
+{
+    int i;
+
+    if (!p) return -1;
+
+    for (i = 0; i < CCtsp_PROB_FILE_NAME_LEN; i++)
+        name[i] = p->name[i];
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putname (CCtsp_PROB_FILE *p, char *name)
+#else
+int CCtsp_prob_putname (p, name)
+CCtsp_PROB_FILE *p;
+char *name;
+#endif
+{
+    int i;
+
+    if (!p) return 1;
+
+    for (i = 0; name[i] && i < CCtsp_PROB_FILE_NAME_LEN - 1; i++)
+        p->name[i] = name[i];
+    for (; i < CCtsp_PROB_FILE_NAME_LEN; i++)
+        p->name[i] = '\0';
+
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getid (CCtsp_PROB_FILE *p, int *id)
+#else
+int CCtsp_prob_getid (p, id)
+CCtsp_PROB_FILE *p;
+int *id;
+#endif
+{
+    if (!p) return -1;
+
+    *id = p->id;
+    if (*id == -1) {
+        printf ("Setting -1 ID to 0\n"); fflush (stdout);
+        *id = 0;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putid (CCtsp_PROB_FILE *p, int id)
+#else
+int CCtsp_prob_putid (p, id)
+CCtsp_PROB_FILE *p;
+int id;
+#endif
+{
+    if (!p) return 1;
+
+    p->id = id;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getparent (CCtsp_PROB_FILE *p, int *parent)
+#else
+int CCtsp_prob_getparent (p, parent)
+CCtsp_PROB_FILE *p;
+int *parent;
+#endif
+{
+    if (!p) return -1;
+
+    *parent = p->parent;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putparent (CCtsp_PROB_FILE *p, int parent)
+#else
+int CCtsp_prob_putparent (p, parent)
+CCtsp_PROB_FILE *p;
+int parent;
+#endif
+{
+    if (!p) return 1;
+
+    p->parent = parent;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getub (CCtsp_PROB_FILE *p, double *ub)
+#else
+int CCtsp_prob_getub (p, ub)
+CCtsp_PROB_FILE *p;
+double *ub;
+#endif
+{
+    if (!p) return -1;
+
+    *ub = p->ub;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putub (CCtsp_PROB_FILE *p, double ub)
+#else
+int CCtsp_prob_putub (p, ub)
+CCtsp_PROB_FILE *p;
+double ub;
+#endif
+{
+    if (!p) return 1;
+
+    p->ub = ub;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getlb (CCtsp_PROB_FILE *p, double *lb)
+#else
+int CCtsp_prob_getlb (p, lb)
+CCtsp_PROB_FILE *p;
+double *lb;
+#endif
+{
+    if (!p) return -1;
+
+    *lb = p->lb;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putlb (CCtsp_PROB_FILE *p, double lb)
+#else
+int CCtsp_prob_putlb (p, lb)
+CCtsp_PROB_FILE *p;
+double lb;
+#endif
+{
+    if (!p) return 1;
+
+    p->lb = lb;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getexactlb (CCtsp_PROB_FILE *p, CCbigguy *lb)
+#else
+int CCtsp_prob_getexactlb (p, lb)
+CCtsp_PROB_FILE *p;
+CCbigguy *lb;
+#endif
+{
+    if (!p) return -1;
+
+    *lb = p->exactlb;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putexactlb (CCtsp_PROB_FILE *p, CCbigguy lb)
+#else
+int CCtsp_prob_putexactlb (p, lb)
+CCtsp_PROB_FILE *p;
+CCbigguy lb;
+#endif
+{
+    if (!p) return 1;
+
+    p->exactlb = lb;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getnnodes (CCtsp_PROB_FILE *p, int *nnodes)
+#else
+int CCtsp_prob_getnnodes (p, nnodes)
+CCtsp_PROB_FILE *p;
+int *nnodes;
+#endif
+{
+    if (!p) return -1;
+
+    *nnodes = p->nnodes;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putnnodes (CCtsp_PROB_FILE *p, int nnodes)
+#else
+int CCtsp_prob_putnnodes (p, nnodes)
+CCtsp_PROB_FILE *p;
+int nnodes;
+#endif
+{
+    if (!p) return 1;
+
+    p->nnodes = nnodes;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getchildren (CCtsp_PROB_FILE *p, int *child0, int *child1)
+#else
+int CCtsp_prob_getchildren (p, child0, child1)
+CCtsp_PROB_FILE *p;
+int *child0, *child1;
+#endif
+{
+    if (!p) return -1;
+
+    *child0 = p->child0;
+    *child1 = p->child1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putchildren (CCtsp_PROB_FILE *p, int child0, int child1)
+#else
+int CCtsp_prob_putchildren (p, child0, child1)
+CCtsp_PROB_FILE *p;
+int child0, child1;
+#endif
+{
+    if (!p) return 1;
+
+    p->child0 = child0;
+    p->child1 = child1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getreal (CCtsp_PROB_FILE *p, int *real)
+#else
+int CCtsp_prob_getreal (p, real)
+CCtsp_PROB_FILE *p;
+int *real;
+#endif
+{
+    if (!p) return -1;
+
+    *real = p->real;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putreal (CCtsp_PROB_FILE *p, int real)
+#else
+int CCtsp_prob_putreal (p, real)
+CCtsp_PROB_FILE *p;
+int real;
+#endif
+{
+    if (!p) return 1;
+
+    p->real = real;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getprocessed (CCtsp_PROB_FILE *p, int *processed)
+#else
+int CCtsp_prob_getprocessed (p, processed)
+CCtsp_PROB_FILE *p;
+int *processed;
+#endif
+{
+    if (!p) return -1;
+
+    *processed = p->processed;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putprocessed (CCtsp_PROB_FILE *p, int processed)
+#else
+int CCtsp_prob_putprocessed (p, processed)
+CCtsp_PROB_FILE *p;
+int processed;
+#endif
+{
+    if (!p) return 1;
+
+    p->processed = processed;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getinfeasible (CCtsp_PROB_FILE *p, int *infeasible)
+#else
+int CCtsp_prob_getinfeasible (p, infeasible)
+CCtsp_PROB_FILE *p;
+int *infeasible;
+#endif
+{
+    if (!p) return -1;
+
+    *infeasible = p->infeasible;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putinfeasible (CCtsp_PROB_FILE *p, int infeasible)
+#else
+int CCtsp_prob_putinfeasible (p, infeasible)
+CCtsp_PROB_FILE *p;
+int infeasible;
+#endif
+{
+    if (!p) return 1;
+
+    p->infeasible = infeasible;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_puttour (CCtsp_PROB_FILE *p, int *tour)
+#else
+int CCtsp_prob_puttour (p, tour)
+CCtsp_PROB_FILE *p;
+int *tour;
+#endif
+{
+    int i;
+    int ncount;
+
+    if (!p) return 1;
+
+    ncount = p->nnodes;
+    if (ncount <= 0) {
+        printf ("nnodes not set in CCtsp_prob_puttour\n");
+        return 1;
+    }
+    p->offsets.tour = CCutil_stell (p->f);
+    for (i = 0; i < ncount; i++) {
+        if (CCutil_swrite_int (p->f, (unsigned int) tour[i]))
+            return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_gettour (CCtsp_PROB_FILE *p, int **tour)
+#else
+int CCtsp_prob_gettour (p, tour)
+CCtsp_PROB_FILE *p;
+int **tour;
+#endif
+{
+    int i;
+    int ncount;
+
+    if (!p) return -1;
+
+    ncount = p->nnodes;
+    if (ncount <= 0) {
+        printf ("nnodes not set in CCtsp_prob_gettour\n");
+        return 1;
+    }
+    if (p->offsets.tour == -1) {
+        printf ("No tour in file.\n");
+        return 1;
+    }
+    if (CCutil_sseek (p->f, p->offsets.tour)) {
+        printf ("CCutil_sseek failed in CCtsp_prob_gettour\n");
+        return -1;
+    }
+
+    *tour = CC_SAFE_MALLOC (ncount, int);
+    if (!(*tour)) {
+        fprintf (stderr, "out of memory in CCtsp_prob_gettour\n");
+        return -1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        if (CCutil_sread_int (p->f, (unsigned int *) &((*tour)[i]))) {
+            CC_FREE (*tour, int);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putedges (CCtsp_PROB_FILE *p, int ecount, int *elist, int *elen)
+#else
+int CCtsp_prob_putedges (p, ecount, elist, elen)
+CCtsp_PROB_FILE *p;
+int ecount;
+int *elist, *elen;
+#endif
+{
+    int i;
+
+    if (!p) return 1;
+
+    p->offsets.edge = CCutil_stell (p->f);
+    if (CCutil_swrite_int (p->f, (unsigned int) ecount))
+        return 1;
+    for (i = 0; i < 2 * ecount; i++) {
+        if (CCutil_swrite_int (p->f, (unsigned int) elist[i]))
+            return 1;
+    }
+    for (i = 0; i < ecount; i++) {
+        if (CCutil_swrite_int (p->f, (unsigned int) elen[i]))
+            return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getedges (CCtsp_PROB_FILE *p, int *ecount, int **elist, int **elen)
+#else
+int CCtsp_prob_getedges (p, ecount, elist, elen)
+CCtsp_PROB_FILE *p;
+int *ecount;
+int **elist, **elen;
+#endif
+{
+    int i;
+
+    if (!p) return -1;
+
+    if (p->offsets.edge == -1) {
+        printf ("No edges in file.\n");
+        return 1;
+    }
+    if (CCutil_sseek (p->f, p->offsets.edge)) {
+        printf ("CCutil_sseek failed in CCtsp_prob_getedges\n");
+        return -1;
+    }
+    if (CCutil_sread_int (p->f, (unsigned int *) ecount))
+        return -1;
+
+    *elist = CC_SAFE_MALLOC (2 * (*ecount), int);
+    *elen = CC_SAFE_MALLOC (*ecount, int);
+    if (!(*elist) || !(*elen)) {
+        fprintf (stderr, "out of memory in CCtsp_prob_getedges\n");
+        CC_IFFREE (*elist, int);
+        CC_IFFREE (*elen, int);
+        return -1;
+    }
+
+    for (i = 0; i < 2 * (*ecount); i++) {
+        if (CCutil_sread_int (p->f, (unsigned int *) &((*elist)[i]))) {
+            CC_FREE (*elist, int);
+            CC_FREE (*elen, int);
+            return -1;
+        }
+    }
+    for (i = 0; i < *ecount; i++) {
+        if (CCutil_sread_int (p->f, (unsigned int *) &((*elen)[i]))) {
+            CC_FREE (*elist, int);
+            CC_FREE (*elen, int);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putcuts (CCtsp_PROB_FILE *p, CC_SFILE *s, CCtsp_lpcuts *cuts)
+#else
+int CCtsp_prob_putcuts (p, s, cuts)
+CCtsp_PROB_FILE *p;
+CC_SFILE *s;
+CCtsp_lpcuts *cuts;
+#endif
+{
+    int *marks = (int *) NULL;
+    int cend = cuts->cliqueend;
+    int i, j, k;
+    CC_SFILE *f;
+
+    if (!p && !s) return 1;
+
+    if (p) {
+        p->offsets.cut = CCutil_stell (p->f);
+        f = p->f;
+    } else {
+        f = s;
+    }
+
+    if (CCutil_swrite_int (f, (unsigned int) CCtsp_PROB_IO_CUTS_VERSION))
+        return 1;
+
+    if (cend) {
+        marks = CC_SAFE_MALLOC (cend, int);
+        if (!marks) {
+            fprintf (stderr, "out of memory in CCtsp_prob_putcut\n");
+            return 1;
+        }
+        for (i = 0; i < cend; i++)
+            marks[i] = 0;
+
+        for (i = 0; i < cuts->cutcount; i++) {
+            for (j = 0; j < cuts->cuts[i].cliquecount; j++) {
+                marks[cuts->cuts[i].cliques[j]]++;
+            }
+        }
+        for (i = 0, k = 1; i < cend; i++) {  /* Start a 1 to avoid 0 as an index */
+            if (marks[i]) {
+                if (marks[i] != cuts->cliques[i].refcount) {
+                    fprintf (stderr, "SCREW UP in refcount for clique %d\n", i);
+                }
+                marks[i] = k++;
+            }
+        }
+
+        for (i = 0; i < cend; i++) {
+            if (marks[i]) {
+                if (CCutil_swrite_int (f, (unsigned int) cuts->cliques[i].segcount))
+                    return 1;
+                for (j = 0; j < cuts->cliques[i].segcount; j++) {
+                    if (CCutil_swrite_int (f,
+                            (unsigned int) cuts->cliques[i].nodes[j].lo))
+                        return 1;
+                    if (CCutil_swrite_int (f,
+                            (unsigned int) cuts->cliques[i].nodes[j].hi))
+                        return 1;
+                }
+            }
+        }
+    }
+
+    if (CCutil_swrite_int (f, (unsigned int) -1)) return 1;
+
+    for (i = 0; i < cuts->cutcount; i++) {
+        if (CCutil_swrite_int (f, (unsigned int) cuts->cuts[i].cliquecount))
+            return 1;
+        if (CCutil_swrite_int (f, (unsigned int) cuts->cuts[i].handlecount))
+            return 1;
+        if (CCutil_swrite_int (f, (unsigned int) cuts->cuts[i].rhs))
+            return 1;
+        if (CCutil_swrite_char (f, (unsigned char) cuts->cuts[i].sense))
+            return 1;
+
+        for (j = 0; j < cuts->cuts[i].cliquecount; j++) {
+            if (CCutil_swrite_int (f,
+              (unsigned int) marks[cuts->cuts[i].cliques[j]] - 1))
+                return 1;
+        }
+        if (p) {
+            if (CCutil_swrite_int (f, (unsigned int) cuts->cuts[i].modcount))
+                return 1;
+            for (j = 0; j < cuts->cuts[i].modcount; j++) {
+                if (CCutil_swrite_int (f,(unsigned int) cuts->cuts[i].mods[j].node))
+                    return 1;
+                if (CCutil_swrite_int (f,(unsigned int) cuts->cuts[i].mods[j].mult))
+                    return 1;
+            }
+        }
+    }
+    if (CCutil_swrite_int (f, (unsigned int) -1)) return 1;
+
+    CC_IFFREE (marks, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getcuts (CCtsp_PROB_FILE *p, CC_SFILE *s, CCtsp_lpcuts *cuts)
+#else
+int CCtsp_prob_getcuts (p, s, cuts)
+CCtsp_PROB_FILE *p;
+CC_SFILE *s;
+CCtsp_lpcuts *cuts;
+#endif
+{
+    int i, j, k, nseg, ncliq, nhand, rhs, cliq, nmod, hi, lo, n, mult;
+    char sense;
+    int cliqcount = 0, cutcount = 0;
+    CCtsp_lpclique c;
+    CCtsp_lpcut u;
+    int *hits = (int *) NULL;
+    int version = 0;
+    CC_SFILE *f;
+
+
+    if (!p && !s) return -1;
+
+    if (p) {
+        if (p->offsets.cut == -1) {
+            printf ("No cuts in file.\n");
+            return 1;
+        }
+        if (CCutil_sseek (p->f, p->offsets.cut)) {
+            printf ("CCutil_sseek failed in CCtsp_prob_getedges\n");
+            return -1;
+        }
+        f = p->f;
+    } else {
+        f = s;
+    }
+
+    if (CCutil_sread_int (f, (unsigned int *) &version))
+        goto CLEANUP;
+
+    if (version > CCtsp_PROB_IO_CUTS_VERSION_BASE) {
+        /* an initial version of the cut system did not have a version # */
+        printf ("Pre-sense version of files cuts\n"); fflush (stdout);
+        nseg = version;
+        version = 0;
+    } else {
+        if (CCutil_sread_int (f, (unsigned int *) &nseg)) goto CLEANUP;
+    }
+
+    while (nseg != -1) {
+        c.segcount = nseg;
+        if (nseg == 0) {
+            fprintf (stderr, "ERROR: Clique with no segs in read_da_cuts\n");
+            goto CLEANUP;
+        }
+        c.nodes = CC_SAFE_MALLOC (nseg, CCtsp_segment);
+        if (!c.nodes) {
+            fprintf (stderr, "out of memory in read_da_cuts\n");
+            goto CLEANUP;
+        }
+        for (j = 0; j < nseg; j++) {
+            if (CCutil_sread_int (f, (unsigned int *) &lo)) goto CLEANUP;
+            if (CCutil_sread_int (f, (unsigned int *) &hi)) goto CLEANUP;
+            c.nodes[j].lo = lo;
+            c.nodes[j].hi = hi;
+        }
+        k = CCtsp_register_clique (cuts, &c);
+        CC_FREE (c.nodes, CCtsp_segment);
+        if (k == -1) {
+            fprintf (stderr, "CCtsp_register_clique failed\n");
+            goto CLEANUP;
+        }
+        if (k != cliqcount) {
+            fprintf (stderr, "clique registration number is out of seq\n");
+            cliqcount++;
+            goto CLEANUP;
+        }
+        cliqcount++;
+        if (CCutil_sread_int (f, (unsigned int *) &nseg)) goto CLEANUP;
+    }
+
+
+    if (cliqcount) {
+        hits = CC_SAFE_MALLOC (cliqcount, int);
+        if (!hits) {
+            fprintf (stderr, "out of memory in read_da_cuts\n");
+            goto CLEANUP;
+        }
+        for (i = 0; i < cliqcount; i++)
+            hits[i] = 0;
+    }
+
+    if (CCutil_sread_int (f, (unsigned int *) &ncliq)) goto CLEANUP;
+    while (ncliq != -1) {
+        if (CCutil_sread_int (f, (unsigned int *) &nhand)) goto CLEANUP;
+        if (CCutil_sread_int (f, (unsigned int *) &rhs)) goto CLEANUP;
+        if (version <= CCtsp_PROB_IO_CUTS_VERSION_BASE) {
+            if (CCutil_sread_char (f, (unsigned char *) &sense)) goto CLEANUP;
+        } else {
+            sense = 'G';
+        }
+        u.cliquecount = ncliq;
+        u.handlecount = nhand;
+        u.rhs = rhs;
+        u.sense = sense;
+        u.branch = 0;
+        u.age = 0;
+        u.cliques = CC_SAFE_MALLOC (ncliq, int);
+        if (!u.cliques) {
+            fprintf (stderr, "out of memory in read_da_cuts\n");
+            goto CLEANUP;
+        }
+        for (j = 0; j < ncliq; j++) {
+            if (CCutil_sread_int (f, (unsigned int *) &cliq)) goto CLEANUP;
+            u.cliques[j] = cliq;
+            if (hits[cliq])
+                cuts->cliques[cliq].refcount++;
+            else
+                hits[cliq] = 1;
+        }
+        if (p) {
+            if (CCutil_sread_int (f, (unsigned int *) &nmod)) goto CLEANUP;
+            u.modcount = nmod;
+            if (nmod) {
+                u.mods = CC_SAFE_MALLOC (nmod, CCtsp_sparser);
+                if (!u.mods) {
+                    fprintf (stderr, "out of memory in read_da_cuts\n");
+                    CC_FREE (u.cliques, int);
+                    goto CLEANUP;
+                }
+            } else {
+                u.mods = (CCtsp_sparser *) NULL;
+            }
+            for (j = 0; j < nmod; j++) {
+                if (CCutil_sread_int (f, (unsigned int *) &n)) goto CLEANUP;
+                if (CCutil_sread_int (f, (unsigned int *) &mult)) goto CLEANUP;
+                u.mods[j].node = (unsigned int) n;
+                u.mods[j].mult = (unsigned int) mult;
+            }
+        } else {
+            u.mods = (CCtsp_sparser *) NULL;
+            u.modcount = 0;
+        }
+
+        k = CCtsp_add_cut_to_cutlist (cuts, &u);
+        if (k == -1) {
+            fprintf (stderr, "CCtsp_add_cut_to_cutlist failed\n");
+            cutcount++;
+            goto CLEANUP;
+        }
+        if (k != cutcount) {
+            fprintf (stderr, "cut location is out of seq\n");
+            goto CLEANUP;
+        }
+        cutcount++;
+        if (CCutil_sread_int (f, (unsigned int *) &ncliq)) goto CLEANUP;
+    }
+
+    CC_IFFREE (hits, int);
+    return 0;
+
+
+CLEANUP:
+
+    if (cutcount) {
+        for (i = 0; i < cutcount; i++)
+            CCtsp_delete_cut_from_cutlist (cuts, i);
+    } else {
+        for (i = 0; i < cliqcount; i++)
+            CCtsp_unregister_clique (cuts, i);
+    }
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putbasis (CCtsp_PROB_FILE *p, int ccount, int rcount, int *cstat,
+                   int *rstat)
+#else
+int CCtsp_prob_putbasis (p, ccount, rcount, cstat, rstat)
+CCtsp_PROB_FILE *p;
+int ccount, rcount;
+int *cstat, *rstat;
+#endif
+{
+    int i;
+
+    if (!p) return 1;
+
+    p->offsets.basis = CCutil_stell (p->f);
+
+    if (CCutil_swrite_int (p->f, (unsigned int) ccount)) return 1;
+    if (CCutil_swrite_int (p->f, (unsigned int) rcount)) return 1;
+
+    for (i = 0; i < ccount; i++) {
+        if (CCutil_swrite_bits (p->f, (unsigned int) cstat[i], 2)) return 1;
+    }
+
+    for (i = 0; i < rcount; i++) {
+        if (CCutil_swrite_bits (p->f, (unsigned int) rstat[i], 1)) return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getbasis (CCtsp_PROB_FILE *p, int *ccount, int *rcount, int **cstat,
+                   int **rstat)
+#else
+int CCtsp_prob_getbasis (p, ccount, rcount, cstat, rstat)
+CCtsp_PROB_FILE *p;
+int *ccount, *rcount;
+int **cstat, **rstat;
+#endif
+{
+    int i;
+
+    *ccount = 0;
+    *rcount = 0;
+    *cstat = (int *) NULL;
+    *rstat = (int *) NULL;
+
+    if (!p) return -1;
+
+    if (p->offsets.basis == -1) {
+        printf ("No basis in file.\n");
+        return 1;
+    }
+    if (CCutil_sseek (p->f, p->offsets.basis)) {
+        printf ("CCutil_sseek failed in CCtsp_prob_getbasis\n");
+        return -1;
+    }
+
+    if (CCutil_sread_int (p->f, (unsigned int *) ccount)) goto CLEANUP;
+    if (CCutil_sread_int (p->f, (unsigned int *) rcount)) goto CLEANUP;
+
+    *cstat = CC_SAFE_MALLOC (*ccount, int);
+    *rstat = CC_SAFE_MALLOC (*rcount, int);
+    if (!(*rstat) || !(*cstat)) {
+        fprintf (stderr, "out of memory in CCtsp_prob_getbasis\n");
+        goto CLEANUP;
+    }
+    for (i = 0; i < *ccount; i++) {
+        if (CCutil_sread_bits (p->f, (unsigned int *) &((*cstat)[i]), 2)) goto CLEANUP;
+    }
+    for (i = 0; i < *rcount; i++) {
+        if (CCutil_sread_bits (p->f, (unsigned int *) &((*rstat)[i]), 1)) goto CLEANUP;
+    }
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (*cstat, int);
+    CC_IFFREE (*rstat, int);
+    *ccount = 0;
+    *rcount = 0;
+
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putnorms (CCtsp_PROB_FILE *p, int rcount, double *dnorm)
+#else
+int CCtsp_prob_putnorms (p, rcount, dnorm)
+CCtsp_PROB_FILE *p;
+int rcount;
+double *dnorm;
+#endif
+{
+    int i;
+
+    if (!p) return 1;
+
+    p->offsets.norms = CCutil_stell (p->f);
+
+    if (CCutil_swrite_int (p->f, (unsigned int) rcount)) return 1;
+
+    for (i = 0; i < rcount; i++) {
+        if (CCutil_swrite_double (p->f, dnorm[i])) return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getnorms (CCtsp_PROB_FILE *p, int *rcount, double **dnorm)
+#else
+int CCtsp_prob_getnorms (p, rcount, dnorm)
+CCtsp_PROB_FILE *p;
+int *rcount;
+double **dnorm;
+#endif
+{
+    int i;
+
+    *rcount = 0;
+    *dnorm  = (double *) NULL;
+
+    if (!p) return -1;
+
+    if (p->offsets.norms == -1) {
+        printf ("No norms in file.\n");
+        return 1;
+    }
+    if (CCutil_sseek (p->f, p->offsets.norms)) {
+        printf ("CCutil_sseek failed in CCtsp_prob_getnorms\n");
+        return -1;
+    }
+
+    if (CCutil_sread_int (p->f, (unsigned int *) rcount)) goto CLEANUP;
+
+    *dnorm = CC_SAFE_MALLOC (*rcount, double);
+    if (!(*dnorm)) {
+        fprintf (stderr, "out of memory in CCtsp_prob_getnorms\n");
+        goto CLEANUP;
+    }
+    for (i = 0; i < *rcount; i++) {
+        if (CCutil_sread_double (p->f, &((*dnorm)[i]))) goto CLEANUP;
+    }
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (*dnorm, double);
+    *rcount = 0;
+
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putfulladj (CCtsp_PROB_FILE *p, int ncount, int fullcount,
+        CCtsp_genadj *adj)
+#else
+int CCtsp_prob_putfulladj (p, ncount, fullcount, adj)
+CCtsp_PROB_FILE *p;
+int ncount, fullcount;
+CCtsp_genadj *adj;
+#endif
+{
+    int i, j;
+
+    if (!p) return 1;
+
+    p->offsets.fulladj = CCutil_stell (p->f);
+
+    if (CCutil_swrite_int (p->f, (unsigned int) fullcount)) return 1;
+    for (i = 0; i < ncount; i++) {
+        if (CCutil_swrite_int (p->f, (unsigned int) adj[i].deg)) return 1;
+        for (j = 0; j < adj[i].deg; j++) {
+            if (CCutil_swrite_int (p->f, (unsigned int) adj[i].list[j].end))
+                return 1;
+            if (CCutil_swrite_int (p->f, (unsigned int) adj[i].list[j].len))
+                return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getfulladj (CCtsp_PROB_FILE *p, int ncount, int *fullcount,
+        CCtsp_genadj **adj, CCtsp_genadjobj **adjspace)
+#else
+int CCtsp_prob_getfulladj (p, ncount, fullcount, adj, adjspace)
+CCtsp_PROB_FILE *p;
+int ncount, *fullcount;
+CCtsp_genadj **adj;
+CCtsp_genadjobj **adjspace;
+#endif
+{
+    int i, j;
+    CCtsp_genadj *a;
+    CCtsp_genadjobj *s;
+
+    *fullcount = 0;
+    *adj = (CCtsp_genadj *) NULL;
+    *adjspace = (CCtsp_genadjobj *) NULL;
+
+    if (!p || ncount <= 0) return -1;
+
+    if (p->offsets.fulladj == -1) {
+        printf ("No fulladj in file.\n");
+        return 1;
+    }
+    if (CCutil_sseek (p->f, p->offsets.fulladj)) {
+        printf ("CCutil_sseek failed in CCtsp_prob_getfulladj\n");
+        return -1;
+    }
+
+    if (CCutil_sread_int (p->f, (unsigned int *) fullcount)) goto CLEANUP;
+
+    *adjspace = CC_SAFE_MALLOC (*fullcount, CCtsp_genadjobj);
+    *adj = CC_SAFE_MALLOC (ncount, CCtsp_genadj);
+    if (!adjspace || !adj) {
+        fprintf (stderr, "out of memory in CCtsp_prob_getfulladj\n");
+        goto CLEANUP;
+    }
+
+    s = *adjspace;
+    a = *adj;
+    for (i = 0; i < ncount; i++) {
+        a[i].list = s;
+        if (CCutil_sread_int (p->f, (unsigned int *) &(a[i].deg))) goto CLEANUP;
+        for (j = 0; j < a[i].deg; j++) {
+            if (CCutil_sread_int (p->f, (unsigned int *) &(a[i].list[j].end)))
+                goto CLEANUP;
+            if (CCutil_sread_int (p->f, (unsigned int *) &(a[i].list[j].len)))
+                goto CLEANUP;
+        }
+        s += a[i].deg;
+    }
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (*adjspace, CCtsp_genadjobj);
+    CC_IFFREE (*adj, CCtsp_genadj);
+    *fullcount = 0;
+
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putfixed (CCtsp_PROB_FILE *p, int ecount, int *elist)
+#else
+int CCtsp_prob_putfixed (p, ecount, elist)
+CCtsp_PROB_FILE *p;
+int ecount;
+int *elist;
+#endif
+{
+    int i;
+
+    if (!p) return 1;
+
+    p->offsets.fix = CCutil_stell (p->f);
+
+    if (CCutil_swrite_int (p->f, (unsigned int) ecount)) return 1;
+
+    for (i = 0; i < 2*ecount; i++) {
+        if (CCutil_swrite_int (p->f, (unsigned int) elist[i])) return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getfixed (CCtsp_PROB_FILE *p, int *ecount, int **elist)
+#else
+int CCtsp_prob_getfixed (p, ecount, elist)
+CCtsp_PROB_FILE *p;
+int *ecount;
+int **elist;
+#endif
+{
+    int i;
+
+    *ecount = 0;
+    *elist = (int *) NULL;
+    if (!p) return -1;
+
+    if (p->offsets.fix == -1) {
+        printf ("No fix in file\n");
+        return 1;
+    }
+    if (CCutil_sseek (p->f, p->offsets.fix)) {
+        printf ("CCutil_sseek failed in CCtsp_prob_getfix\n");
+        return -1;
+    }
+    if (CCutil_sread_int (p->f, (unsigned int *) ecount)) goto CLEANUP;
+
+    if (*ecount) {
+        *elist = CC_SAFE_MALLOC (2*(*ecount), int);
+        if (!(*elist)) {
+            fprintf (stderr, "out of memory in CCtsp_prob_getfixed\n");
+            goto CLEANUP;
+        }
+        for (i = 0; i < 2*(*ecount); i++) {
+            if (CCutil_sread_int (p->f, (unsigned int *) (&((*elist)[i]))))
+                goto CLEANUP;
+        }
+    }
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (*elist, int);
+    *ecount = 0;
+
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_putexactdual (CCtsp_PROB_FILE *p, CCtsp_bigdual *d, int ncount)
+#else
+int CCtsp_prob_putexactdual (p, d, ncount)
+CCtsp_PROB_FILE *p;
+CCtsp_bigdual *d;
+int ncount;
+#endif
+{
+    int i;
+
+    if (!p) return 1;
+
+    p->offsets.exactdual = CCutil_stell (p->f);
+
+    if (CCutil_swrite_int (p->f, (unsigned int) d->cutcount)) return 1;
+
+    for (i = 0; i < ncount; i++) {
+        if (CCbigguy_swrite (p->f, d->node_pi[i])) return 1;
+    }
+    for (i = 0; i < d->cutcount; i++) {
+        if (CCbigguy_swrite (p->f, d->cut_pi[i])) return 1;
+    }
+
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_getexactdual (CCtsp_PROB_FILE *p, int ncount, CCtsp_bigdual **d)
+#else
+int CCtsp_prob_getexactdual (p, ncount, d)
+CCtsp_PROB_FILE *p;
+int ncount;
+CCtsp_bigdual **d;
+#endif
+{
+    CCtsp_bigdual *rd;
+    int i;
+
+    *d = (CCtsp_bigdual *) NULL;
+
+    if (!p) return -1;
+
+    if (p->offsets.exactdual == -1) {
+        printf ("No exactdual in file\n");
+        fflush (stdout);
+        return 1;
+    }
+
+    *d = CC_SAFE_MALLOC (1, CCtsp_bigdual);
+    if (!(*d)) {
+        fprintf (stderr, "out of memory in CCtsp_prob_getexactdual\n");
+        goto CLEANUP;
+    }
+    rd = *d;
+    rd->cutcount = 0;
+    rd->node_pi = (CCbigguy *) NULL;
+    rd->cut_pi = (CCbigguy *) NULL;
+
+    if (CCutil_sseek (p->f, p->offsets.exactdual)) {
+        fprintf (stderr, "CCutil_sseek failed in CCtsp_prob_getexactdual\n");
+        return -1;
+    }
+    if (CCutil_sread_int (p->f, (unsigned int *) &(rd->cutcount))) goto CLEANUP;
+
+    rd->node_pi = CC_SAFE_MALLOC (ncount, CCbigguy);
+    if (!rd->node_pi) {
+        fprintf (stderr, "out of memory in CCtsp_prob_getexactdual\n");
+        goto CLEANUP;
+    }
+    for (i = 0; i < ncount; i++) {
+        if (CCbigguy_sread (p->f, &(rd->node_pi[i]))) goto CLEANUP;
+    }
+    if (rd->cutcount) {
+        rd->cut_pi = CC_SAFE_MALLOC (rd->cutcount, CCbigguy);
+        if (!rd->cut_pi) {
+            fprintf (stderr, "out of memory in CCtsp_prob_getexactdual\n");
+            goto CLEANUP;
+        }
+        for (i = 0; i < rd->cutcount; i++) {
+            if (CCbigguy_sread (p->f, &(rd->cut_pi[i]))) goto CLEANUP;
+        }
+    }
+
+    return 0;
+
+CLEANUP:
+
+    if (*d) {
+        CC_IFFREE ((*d)->node_pi, CCbigguy);
+        CC_IFFREE ((*d)->cut_pi, CCbigguy);
+        CC_FREE (*d, CCtsp_bigdual);
+    }
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_puthistory (CCtsp_PROB_FILE *p, int depth,
+        CCtsp_branchobj *history)
+#else
+int CCtsp_prob_puthistory (p, depth, history)
+CCtsp_PROB_FILE *p;
+int depth;
+CCtsp_branchobj *history;
+#endif
+{
+    int i, j;
+    CCtsp_lpclique *c;
+
+    if (!p) return 1;
+
+    p->offsets.history = CCutil_stell (p->f);
+
+    if (CCutil_swrite_int (p->f, (unsigned int) depth)) return 1;
+
+    for (i = 0; i < depth; i++) {
+        if (CCutil_swrite_int (p->f, (unsigned int) history[i].depth))
+            return 1;
+        if (CCutil_swrite_int (p->f, (unsigned int) history[i].rhs))
+            return 1;
+        if (CCutil_swrite_int (p->f, (unsigned int) history[i].ends[0]))
+            return 1;
+        if (CCutil_swrite_int (p->f, (unsigned int) history[i].ends[1]))
+            return 1;
+        if (history[i].clique) {
+            c = history[i].clique;
+            if (CCutil_swrite_int (p->f, (unsigned int) c->segcount))
+                return 1;
+            for (j = 0; j < c->segcount; j++) {
+                if (CCutil_swrite_int (p->f, (unsigned int) c->nodes[j].lo))
+                    return 1;
+                if (CCutil_swrite_int (p->f, (unsigned int) c->nodes[j].hi))
+                    return 1;
+            }
+        } else {
+            if (CCutil_swrite_int (p->f, (unsigned int) 0)) return 1;
+        }
+        if (CCutil_swrite_char (p->f, (unsigned char) history[i].sense))
+            return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_prob_gethistory (CCtsp_PROB_FILE *p, int *depth,
+        CCtsp_branchobj **history)
+#else
+int CCtsp_prob_gethistory (p, depth, history)
+CCtsp_PROB_FILE *p;
+int *depth;
+CCtsp_branchobj **history;
+#endif
+{
+    int i, j, nseg, rval;
+    CCtsp_lpclique *c = (CCtsp_lpclique *) NULL;
+    int *slist  = (int *) NULL;
+
+    *depth = 0;
+    *history = (CCtsp_branchobj *) NULL;
+    if (!p) return -1;
+
+    if (p->offsets.history == -1) {
+        printf ("No branch history in file\n");
+        return 1;
+    }
+    if (CCutil_sseek (p->f, p->offsets.history)) {
+        printf ("CCutil_sseek failed in CCtsp_prob_gethistory\n");
+        return -1;
+    }
+    if (CCutil_sread_int (p->f, (unsigned int *) depth)) goto CLEANUP;
+
+    if (*depth) {
+        *history = CC_SAFE_MALLOC (*depth, CCtsp_branchobj);
+        if (!(*history)) {
+            fprintf (stderr, "out of memory in CCtsp_prob_gethistory\n");
+            goto CLEANUP;
+        }
+        for (i = 0; i < (*depth); i++) {
+            if (CCutil_sread_int (p->f,
+                   (unsigned int *) &((*history)[i].depth)))
+                goto CLEANUP;
+            if (CCutil_sread_int (p->f,
+                   (unsigned int *) &((*history)[i].rhs)))
+                goto CLEANUP;
+            if (CCutil_sread_int (p->f,
+                   (unsigned int *) &((*history)[i].ends[0])))
+                goto CLEANUP;
+            if (CCutil_sread_int (p->f,
+                   (unsigned int *) &((*history)[i].ends[1])))
+                goto CLEANUP;
+            if (CCutil_sread_int (p->f, (unsigned int *) &nseg))
+                goto CLEANUP;
+            if (nseg) {
+                slist = CC_SAFE_MALLOC (2*nseg, int);
+                if (!slist) goto CLEANUP;
+                for (j = 0; j < nseg; j++) {
+                    if (CCutil_sread_int (p->f, (unsigned int *) &slist[2*j]))
+                        goto CLEANUP;
+                    if (CCutil_sread_int (p->f, (unsigned int *) &slist[2*j+1]))
+                        goto CLEANUP;
+                }
+                c = CC_SAFE_MALLOC (1, CCtsp_lpclique);
+                if (!c) goto CLEANUP;
+                rval = CCtsp_seglist_to_lpclique (nseg, slist, c);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_seglist_to_lpclique failed\n");
+                    CC_FREE (c, CCtsp_lpclique);
+                    goto CLEANUP;
+                }
+                (*history)[i].clique = c;
+            } else {
+                (*history)[i].clique = (CCtsp_lpclique *) NULL;
+            }
+            if (CCutil_sread_char (p->f,
+                   (unsigned char *) &((*history)[i].sense)))
+                return 1;
+        }
+    }
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (slist, int);
+    CC_IFFREE (*history, CCtsp_branchobj);
+    *depth = 0;
+
+    return -1;
+}
diff --git a/contrib/blossom/concorde97/TSP/qsparse.c b/contrib/blossom/concorde97/TSP/qsparse.c
new file mode 100644
index 0000000000000000000000000000000000000000..f6d927d6fe878ef3fe09327baf0b3dc64a9964eb
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/qsparse.c
@@ -0,0 +1,507 @@
+/***************************************************************************/
+/*                                                                         */
+/*   Function to Reduce the Number of Nonzeros in a Cut by add/sub Stars   */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: October 7, 1995                                                  */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_qsparsify (CCtsp_qsparsegroup **pqs, CCtsp_lpgraph *g,     */
+/*            int *pnzlist, int scount, CCtsp_sparser **slist,             */
+/*            int *savedcount)                                             */
+/*        -pqs (if *pqs is NULL, then it will be initialized)              */
+/*        -g (the graph)                                                   */
+/*        -pnzlist (pointer to an int that is the start of a linked list   */
+/*           of edges that is a superset of the nonzeros in the cut, it    */
+/*           returns a pointer to a superset of the nonzeros in the        */
+/*           sparsified cut. The links are via the coefnext field of       */
+/*           CCtsp_lpedge, and the coef field gives the actual nonzero     */
+/*           coefs.)                                                       */
+/*        -scount (returns the number of CCtsp_sparsers in slist)          */
+/*        -slist (rturns an array of CCtsp_sparsers)                       */
+/*        -savedcount (returns the number of nonzeros that were saved)     */
+/*      RETURNS 0 is it worked and 1 if it failed (probably due to running */
+/*      out of memory). free_qsparsify will free the allocated memory (it  */
+/*      is not freed after each call since the mallocs and initialization  */
+/*      require too much time).                                            */
+/*    void CCtsp_free_qsparsify (CCtsp_qsparsegroup **pqs)                 */
+/*        -pqs (will free the queues and arrays in the struct pointed to   */
+/*             by *pqs, and sets *pqs to NULL)                             */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      This functions uses priorty queues to line up the stars that would */
+/*    decrease the number of nonzeros if they were added or subtracted     */
+/*    there are separate add and subtract queues).                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    queue_add (CCdheap *q, int v, int k),
+    queue_delete (CCdheap *q, int v),
+    queue_keychange (CCdheap *q, int v, int k),
+    add_node(int v, CCtsp_qsparsegroup *qs, CCtsp_lpgraph *g, int *pnzlist),
+    sub_node(int v, CCtsp_qsparsegroup *qs, CCtsp_lpgraph *g, int *pnzlist),
+    update_queues (int v, CCtsp_qsparsegroup *qs, CCtsp_lpgraph *g);
+
+static int
+    init_qsparsify (CCtsp_qsparsegroup **pqs, int ncount),
+    queue_max (CCdheap *);
+
+#else
+
+static void
+    queue_add (),
+    queue_delete (),
+    queue_keychange (),
+    add_node(),
+    sub_node(),
+    update_queues ();
+
+static int
+    init_qsparsify (),
+    queue_max ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int init_qsparsify (CCtsp_qsparsegroup **pqs, int ncount)
+#else
+static int init_qsparsify (pqs, ncount)
+CCtsp_qsparsegroup **pqs;
+int ncount;
+#endif
+{
+    int i;
+    CCtsp_qsparsegroup *qs;
+
+    (*pqs) = CC_SAFE_MALLOC (1, CCtsp_qsparsegroup);
+    if (!(*pqs))
+        return 1;
+
+    qs = *pqs;
+    qs->add_queue = (CCdheap *) NULL;
+    qs->sub_queue = (CCdheap *) NULL;
+    qs->count_m1 = (int *) NULL;
+    qs->count_non0 = (int *) NULL;
+    qs->count_1 = (int *) NULL;
+    qs->on_add_queue = (int *) NULL;
+    qs->on_sub_queue = (int *) NULL;
+    qs->mults = (int *) NULL;
+
+    qs->add_queue = CC_SAFE_MALLOC (1, CCdheap);
+    qs->sub_queue = CC_SAFE_MALLOC (1, CCdheap);
+    if (!qs->add_queue || !qs->sub_queue) {
+        CCtsp_free_qsparsify (pqs);
+        return 1;
+    }
+    if (CCutil_dheap_init (qs->add_queue, ncount)) {
+        CCtsp_free_qsparsify (pqs);
+        return 1;
+    }
+    if (CCutil_dheap_init (qs->sub_queue, ncount)) {
+        CCtsp_free_qsparsify (pqs);
+        return 1;
+    }
+
+    qs->count_m1 = CC_SAFE_MALLOC (ncount, int);
+    qs->count_non0 = CC_SAFE_MALLOC (ncount, int);
+    qs->count_1 = CC_SAFE_MALLOC (ncount, int);
+    qs->on_add_queue = CC_SAFE_MALLOC (ncount, int);
+    qs->on_sub_queue = CC_SAFE_MALLOC (ncount, int);
+    qs->mults = CC_SAFE_MALLOC (ncount, int);
+    if (!qs->count_m1 || !qs->count_non0 || !qs->count_1 ||
+        !qs->on_add_queue || !qs->on_sub_queue || !qs->mults) {
+        CCtsp_free_qsparsify (pqs);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        qs->count_m1[i] = 0;
+        qs->count_non0[i] = 0;
+        qs->count_1[i] = 0;
+        qs->on_add_queue[i] = 0;
+        qs->on_sub_queue[i] = 0;
+        qs->mults[i] = 0;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_qsparsify (CCtsp_qsparsegroup **pqs)
+#else
+void CCtsp_free_qsparsify (pqs)
+CCtsp_qsparsegroup **pqs;
+#endif
+{
+    if (*pqs != (CCtsp_qsparsegroup *) NULL) {
+        if ((*pqs)->add_queue) {
+            CCutil_dheap_free ((*pqs)->add_queue);
+            CC_FREE ((*pqs)->add_queue, CCdheap);
+        }
+        if ((*pqs)->sub_queue) {
+            CCutil_dheap_free ((*pqs)->sub_queue);
+            CC_FREE ((*pqs)->sub_queue, CCdheap);
+        }
+        CC_IFFREE ((*pqs)->count_m1, int);
+        CC_IFFREE ((*pqs)->count_non0, int);
+        CC_IFFREE ((*pqs)->count_1, int);
+        CC_IFFREE ((*pqs)->on_add_queue, int);
+        CC_IFFREE ((*pqs)->on_sub_queue, int);
+        CC_IFFREE ((*pqs)->mults, int);
+        CC_FREE (*pqs, CCtsp_qsparsegroup);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_qsparsify (CCtsp_qsparsegroup **pqs, CCtsp_lpgraph *g, int *pnzlist,
+        int *scount, CCtsp_sparser **slist, int *savedcount)
+#else
+int CCtsp_qsparsify (pqs, g, pnzlist, scount, slist,  savedcount)
+CCtsp_qsparsegroup **pqs;
+CCtsp_lpgraph *g;
+int *pnzlist;
+int *scount;
+CCtsp_sparser **slist;
+int *savedcount;
+#endif
+{
+    int i, k, e, t;
+    int v, w;
+    CCtsp_qsparsegroup *qs;
+    int *count_non0, *count_1, *count_m1;
+    CCtsp_lpedge *edges = g->edges;
+    CCtsp_lpnode *nodes = g->nodes;
+
+    *scount = 0;
+    *slist = (CCtsp_sparser *) NULL;
+    *savedcount = 0;
+    if (*pnzlist == -1)
+        return 0;
+
+    if (*pqs == (CCtsp_qsparsegroup *) NULL) {
+        if (init_qsparsify(pqs, g->ncount))
+            return 1;
+    }
+
+    qs = *pqs;
+    count_non0 = qs->count_non0;
+    count_1 = qs->count_1;
+    count_m1 = qs->count_m1;
+
+    for (e = *pnzlist; e != -1; e = g->edges[e].coefnext) {
+        if (edges[e].coef) {
+            count_non0[edges[e].ends[0]]++;
+            count_non0[edges[e].ends[1]]++;
+            if (edges[e].coef == 1) {
+                count_1[edges[e].ends[0]]++;
+                count_1[edges[e].ends[1]]++;
+            } else if (edges[e].coef == -1) {
+                count_m1[edges[e].ends[0]]++;
+                count_m1[edges[e].ends[1]]++;
+            }
+        }
+    }
+
+    g->nodemarker++;
+    for (e = *pnzlist; e != -1; e = edges[e].coefnext) {
+        if (edges[e].coef) {
+            if (nodes[edges[e].ends[0]].mark != g->nodemarker) {
+                update_queues(edges[e].ends[0], qs, g);
+                nodes[edges[e].ends[0]].mark = g->nodemarker;
+            }
+            if (nodes[edges[e].ends[1]].mark != g->nodemarker) {
+                update_queues(edges[e].ends[1], qs, g);
+                nodes[edges[e].ends[1]].mark = g->nodemarker;
+            }
+        }
+    }
+
+    k = 0;
+    for (;;) {
+        v = queue_max (qs->add_queue);
+        w = queue_max (qs->sub_queue);
+        if (v == -1 && w == -1) break;
+        if (w == -1 || (v != -1 &&
+            count_m1[v] - (nodes[v].deg - count_non0[v]) >
+                     count_1[w] - (nodes[w].deg - count_non0[w]))) {
+            k += (count_m1[v] - (nodes[v].deg - count_non0[v]));
+            queue_delete (qs->add_queue, v);
+            qs->on_add_queue[v] = 0;
+            (qs->mults[v])++;
+            add_node (v, qs, g, pnzlist);
+        } else {
+            k += (count_1[w] - (nodes[w].deg - count_non0[w]));
+            queue_delete (qs->sub_queue, w);
+            qs->on_sub_queue[w] = 0;
+            (qs->mults[w])--;
+            sub_node (w, qs, g, pnzlist);
+        }
+    }
+
+
+    g->nodemarker++;
+    for (e = *pnzlist; e != -1; e = edges[e].coefnext) {
+        if (qs->mults[edges[e].ends[0]] &&
+                nodes[edges[e].ends[0]].mark != g->nodemarker) {
+            (*scount)++;
+            nodes[edges[e].ends[0]].mark = g->nodemarker;
+        }
+        if (qs->mults[edges[e].ends[1]] &&
+                nodes[edges[e].ends[1]].mark != g->nodemarker) {
+            (*scount)++;
+            nodes[edges[e].ends[1]].mark = g->nodemarker;
+        }
+    }
+    if (*scount) {
+        *slist = CC_SAFE_MALLOC (*scount, CCtsp_sparser);
+        if (!(*slist)) {
+            CCtsp_free_qsparsify (pqs);
+            *scount = 0;
+            *savedcount = 0;
+            return 1;
+        }
+        i = 0;
+        for (e = *pnzlist; e != -1; e = edges[e].coefnext) {
+            if (qs->mults[edges[e].ends[0]]) {
+                (*slist)[i].node = (unsigned int) edges[e].ends[0];
+                t = qs->mults[edges[e].ends[0]];
+                if (t > 0)
+                    (*slist)[i++].mult = (unsigned int) (128 + (t % 128));
+                else
+                    (*slist)[i++].mult = (unsigned int) (128 - ((-t) % 128));
+                qs->mults[edges[e].ends[0]] = 0;
+            }
+            if (qs->mults[edges[e].ends[1]]) {
+                (*slist)[i].node = (unsigned int) edges[e].ends[1];
+                t = qs->mults[edges[e].ends[1]];
+                if (t > 0)
+                    (*slist)[i++].mult = (unsigned int) (128 + (t % 128));
+                else
+                    (*slist)[i++].mult = (unsigned int) (128 - ((-t) % 128));
+                qs->mults[edges[e].ends[1]] = 0;
+            }
+        }
+    }
+
+
+    for (e = *pnzlist; e != -1; e = g->edges[e].coefnext) {
+        qs->count_m1[edges[e].ends[0]] = 0;
+        qs->count_non0[edges[e].ends[0]] = 0;
+        qs->count_1[edges[e].ends[0]] = 0;
+        qs->count_m1[edges[e].ends[1]] = 0;
+        qs->count_non0[edges[e].ends[1]] = 0;
+        qs->count_1[edges[e].ends[1]] = 0;
+    }
+
+    *savedcount = k;
+
+/*
+    printf ("sscount = %d  savedcount = %d\n", *scount, *savedcount);
+    fflush (stdout);
+*/
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void queue_add (CCdheap *q, int v, int k)
+#else
+static void queue_add (q, v, k)
+CCdheap *q;
+int v;
+int k;
+#endif
+{
+    /* adds v to q with key k */
+    q->key[v] = -k;  /* since dheap code works with min, not max */
+    CCutil_dheap_insert (q, v);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void queue_delete (CCdheap *q, int v)
+#else
+static void queue_delete (q, v)
+CCdheap *q;
+int v;
+#endif
+{
+    /* deletes v from q */
+    CCutil_dheap_delete (q, v);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void queue_keychange (CCdheap *q, int v, int k)
+#else
+static void queue_keychange (q, v, k)
+CCdheap *q;
+int v;
+int k;
+#endif
+{
+    /* changes v's key to k on q */
+    CCutil_dheap_changekey (q, v, (double) -k);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int queue_max (CCdheap *q)
+#else
+static int queue_max (q)
+CCdheap *q;
+#endif
+{
+    /* returns the node on q with the largest key */
+    return CCutil_dheap_findmin (q);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void add_node (int v, CCtsp_qsparsegroup *qs, CCtsp_lpgraph *g,
+        int *pnzlist)
+#else
+static void add_node (v, qs, g, pnzlist)
+int v;
+CCtsp_qsparsegroup *qs;
+CCtsp_lpgraph *g;
+int *pnzlist;
+#endif
+{
+    int j, w;
+    CCtsp_lpnode *lv = &(g->nodes[v]);
+    CCtsp_lpedge *e;
+
+    for (j = lv->deg - 1; j >= 0; j--) {
+        e = &(g->edges[lv->adj[j].edge]);
+        w = lv->adj[j].to;
+        if (e->coef == 0) {
+            if (e->coefnext == -2) {
+                e->coefnext = *pnzlist;
+                *pnzlist = lv->adj[j].edge;
+            }
+            qs->count_non0[v]++;
+            qs->count_1[v]++;
+            qs->count_non0[w]++;
+            qs->count_1[w]++;
+            update_queues (w, qs, g);
+        } else if (e->coef == 1) {
+            qs->count_1[v]--;
+            qs->count_1[w]--;
+            update_queues (w, qs, g);
+        } else if (e->coef == -1) {
+            qs->count_m1[v]--;
+            qs->count_non0[v]--;
+            qs->count_m1[w]--;
+            qs->count_non0[w]--;
+            update_queues (w, qs, g);
+        } else if (e->coef == -2) {
+            qs->count_m1[v]++;
+            qs->count_m1[w]++;
+            update_queues (w, qs, g);
+        }
+        e->coef++;
+    }
+    update_queues (v, qs, g);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void sub_node (int v, CCtsp_qsparsegroup *qs, CCtsp_lpgraph *g,
+        int *pnzlist)
+#else
+static void sub_node (v, qs, g, pnzlist)
+int v;
+CCtsp_qsparsegroup *qs;
+CCtsp_lpgraph *g;
+int *pnzlist;
+#endif
+{
+    int j, w;
+    CCtsp_lpnode *lv = &(g->nodes[v]);
+    CCtsp_lpedge *e;
+
+    for (j = lv->deg - 1; j >= 0; j--) {
+        e = &(g->edges[lv->adj[j].edge]);
+        w = lv->adj[j].to;
+        if (e->coef == 0) {
+            if (e->coefnext == -2) {
+                e->coefnext = *pnzlist;
+                *pnzlist = lv->adj[j].edge;
+            }
+            qs->count_non0[v]++;
+            qs->count_m1[v]++;
+            qs->count_non0[w]++;
+            qs->count_m1[w]++;
+            update_queues (w, qs, g);
+        } else if (e->coef == -1) {
+            qs->count_m1[v]--;
+            qs->count_m1[w]--;
+            update_queues (w, qs, g);
+        } else if (e->coef == 1) {
+            qs->count_1[v]--;
+            qs->count_non0[v]--;
+            qs->count_1[w]--;
+            qs->count_non0[w]--;
+            update_queues (w, qs, g);
+        } else if (e->coef == 2) {
+            qs->count_1[v]++;
+            qs->count_1[w]++;
+            update_queues (w, qs, g);
+        }
+        e->coef--;
+    }
+    update_queues (v, qs, g);
+}
+
+/* update_queues (v, qs, g) should be called whenever some of the counts for
+   v have changed */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void update_queues (int v, CCtsp_qsparsegroup *qs, CCtsp_lpgraph *g)
+#else
+static void update_queues (v, qs, g)
+int v;
+CCtsp_qsparsegroup *qs;
+CCtsp_lpgraph *g;
+#endif
+{
+    if (qs->count_m1[v] - (g->nodes[v].deg - qs->count_non0[v]) > 0) {
+        if (qs->on_add_queue[v]) {
+            queue_keychange (qs->add_queue, v,
+                  qs->count_m1[v] - (g->nodes[v].deg - qs->count_non0[v]));
+        } else {
+            queue_add (qs->add_queue, v,
+                  qs->count_m1[v] - (g->nodes[v].deg - qs->count_non0[v]));
+            qs->on_add_queue[v] = 1;
+        }
+    } else {
+        if (qs->on_add_queue[v]) {
+            queue_delete (qs->add_queue, v);
+            qs->on_add_queue[v] = 0;
+        }
+    }
+
+    if (qs->count_1[v] - (g->nodes[v].deg - qs->count_non0[v]) > 0) {
+        if (qs->on_sub_queue[v]) {
+            queue_keychange (qs->sub_queue, v,
+                  qs->count_1[v] - (g->nodes[v].deg - qs->count_non0[v]));
+        } else {
+            queue_add (qs->sub_queue, v,
+                  qs->count_1[v] - (g->nodes[v].deg - qs->count_non0[v]));
+            qs->on_sub_queue[v] = 1;
+        }
+    } else {
+        if (qs->on_sub_queue[v]) {
+            queue_delete (qs->sub_queue, v);
+            qs->on_sub_queue[v] = 0;
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/TSP/teething.c b/contrib/blossom/concorde97/TSP/teething.c
new file mode 100644
index 0000000000000000000000000000000000000000..52026861924d49808326f7c0ca2386cd3cc5839b
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/teething.c
@@ -0,0 +1,800 @@
+/***************************************************************************/
+/*                                                                         */
+/*                        Teething Combs                                   */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 13, 1997                                                   */
+/*        July 15, 1997                                                    */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_teething (CCtsp_lpgraph *g, double *x,                     */
+/*            CCtsp_lpcut_in *cut, CCtsp_lpcut_in **newcut)                */
+/*      -g is the graph of the active edges in the LP                      */
+/*      -x is an LP solution                                               */
+/*      -cut is the base comb                                              */
+/*      -newcut returns the comb found after teething                      */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      The new cut may be just a subtour inequality. This code is based   */
+/*  on the "Teething" section of the tsp notes.                            */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+
+typedef struct intptr {
+    int this;
+    struct intptr *next;
+} intptr;
+
+typedef struct Rrecord {
+    int add0;
+    int add1;
+    struct Rrecord *next;
+} Rrecord;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    teething_free_world (void),
+    identify_big_teeth (CCtsp_lpcut_in *cut, int handle, int *nbig,
+        CCtsp_lpclique **bigteeth);
+
+static int
+    optimal_pseudocomb (CCtsp_lpgraph *g, double *x, CCtsp_lpcut_in *c,
+        int ihandle, CCtsp_lpcut_in *d),
+    grab_record (Rrecord *r, int parity, intptr **list),
+    clean_pseudocomb (CCtsp_lpgraph *g, double *x, CCtsp_lpcut_in *c,
+        CCtsp_lpcut_in *d),
+    add_to_list (intptr **list, int item),
+    add_to_record (Rrecord **R, int add0, int add1);
+
+#else
+
+static void
+    teething_free_world (),
+    identify_big_teeth ();
+
+static int
+    optimal_pseudocomb (),
+    grab_record (),
+    clean_pseudocomb (),
+    add_to_list (),
+    add_to_record ();
+
+#endif
+
+
+CC_PTR_ALLOC_ROUTINE (intptr, intptralloc, intptrchunklist, intptrfreelist)
+CC_PTR_FREE_ROUTINE (intptr, intptrfree, intptrfreelist)
+CC_PTR_FREE_LIST_ROUTINE(intptr, intptrfree_list, intptrfree)
+CC_PTR_FREE_WORLD_ROUTINE(intptr, intptrfree_world, intptrchunklist,
+        intptrfreelist)
+CC_PTR_LEAKS_ROUTINE (intptr, intptr_check_leaks, intptrchunklist,
+        intptrfreelist, this, int)
+CC_PTR_STATUS_ROUTINE (intptr, intptr_status, intptrchunklist, intptrfreelist)
+
+CC_PTR_ALLOC_ROUTINE (Rrecord, Rrecordalloc, Rrecordchunklist, Rrecordfreelist)
+CC_PTR_FREE_ROUTINE (Rrecord, Rrecordfree, Rrecordfreelist)
+CC_PTR_FREE_LIST_ROUTINE(Rrecord, Rrecordfree_list, Rrecordfree)
+CC_PTR_FREE_WORLD_ROUTINE( Rrecord, Rrecordfree_world, Rrecordchunklist,
+        Rrecordfreelist)
+CC_PTR_LEAKS_ROUTINE (Rrecord, Rrecord_check_leaks, Rrecordchunklist,
+        Rrecordfreelist, add0, int)
+CC_PTR_STATUS_ROUTINE (Rrecord, Rrecord_status, Rrecordchunklist,
+        Rrecordfreelist)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_teething (CCtsp_lpgraph *g, double *x, CCtsp_lpcut_in *cut,
+        CCtsp_lpcut_in **newcut)
+#else
+int CCtsp_teething (g, x, cut, newcut)
+CCtsp_lpgraph *g;
+double *x;
+CCtsp_lpcut_in *cut;
+CCtsp_lpcut_in **newcut;
+#endif
+{
+    int rval = 0;
+    CCtsp_lpcut_in pseudo;
+    CCtsp_lpcut_in general;
+    int test, ihandle;
+
+/*
+    printf ("CCtsp_teething ....\n"); fflush (stdout);
+    CCtsp_print_lpcut_in (cut);
+*/
+
+    *newcut = (CCtsp_lpcut_in *) NULL;
+
+    if (cut->cliquecount > 1) {
+        rval = CCtsp_test_pure_comb (g->ncount, cut, &test, &ihandle);
+        if (rval) {
+            fprintf (stderr, "CCtsp_test_pure_comb failed\n"); goto CLEANUP;
+        }
+        if (test != 1) goto CLEANUP;
+    } else {
+        ihandle = 0;
+    }
+
+    rval = optimal_pseudocomb (g, x, cut, ihandle, &pseudo);
+    if (rval) {
+        fprintf (stderr, "optimal_pseudocomb failed\n"); goto CLEANUP;
+    }
+
+    if (pseudo.cliquecount == 2 || pseudo.cliquecount == 1) {
+        CCtsp_free_lpcut_in (&pseudo);
+        goto CLEANUP;
+    }
+    rval = CCtsp_test_pseudocomb (g->ncount, &pseudo, 0, &test);
+    if (rval) {
+        fprintf (stderr, "CCtsp_test_pseudocomb failed\n"); goto CLEANUP;
+    }
+    if (test != 1) {
+        fprintf (stderr, "Not a pseudocomb\n");
+        CCtsp_print_lpcut_in (&pseudo);
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_test_teeth_disjoint (g->ncount, &pseudo, 0, &test);
+    if (rval) {
+        fprintf (stderr, "CCtsp_test_teeth_disjoint failed\n"); goto CLEANUP;
+    }
+
+    if (!test) {
+        rval = clean_pseudocomb (g, x, &pseudo, &general);
+        CCtsp_free_lpcut_in (&pseudo);
+        if (rval) {
+            fprintf (stderr, "clean_pseudocomb failed\n");
+            goto CLEANUP;
+        }
+        if (general.cliquecount <= 2) {
+            CCtsp_free_lpcut_in (&general);
+            goto CLEANUP;
+        }
+    }
+
+
+    *newcut = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+    if (!(*newcut)) {
+        fprintf (stderr, "out or memory in CCtsp_teething\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    if (test) {
+        **newcut = pseudo;
+    } else {
+        **newcut = general;
+    }
+
+    rval = CCtsp_test_pure_comb (g->ncount, *newcut, &test, (int *) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_test_pure_comb failed\n");
+        CCtsp_print_lpcut_in (&general);
+        goto CLEANUP;
+    }
+
+CLEANUP:
+
+    teething_free_world ();
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int optimal_pseudocomb (CCtsp_lpgraph *g, double *x, CCtsp_lpcut_in *c,
+        int ihandle, CCtsp_lpcut_in *d)
+#else
+static int optimal_pseudocomb (g, x, c, ihandle, d)
+CCtsp_lpgraph *g;
+double *x;
+CCtsp_lpcut_in *c;
+int ihandle;
+CCtsp_lpcut_in *d;
+#endif
+{
+    int rval = 0;
+    CCtsp_lpclique **bigteeth = (CCtsp_lpclique **) NULL;
+    int *hhit           = (int *) NULL;
+    int *thit           = (int *) NULL;
+    int *grab0          = (int *) NULL;
+    int *grab1          = (int *) NULL;
+    int *usebig         = (int *) NULL;
+    double *ro0         = (double *) NULL;
+    double *ro1         = (double *) NULL;
+    intptr *newteeth    = (intptr *) NULL;
+    Rrecord **R         = (Rrecord **) NULL;
+    int  nbig, i, j, si, sj, u, v, e;
+    int ncount = g->ncount;
+    CCtsp_lpclique *cliques = c->cliques;
+    CCtsp_lpclique *handle;
+    int add0, add1, parity;
+    double nu0, nu1, delta;
+    intptr *ip;
+    int ends[2];
+
+    CCtsp_init_lpcut_in (d);
+
+    handle = &cliques[ihandle];
+
+    bigteeth = CC_SAFE_MALLOC (c->cliquecount, CCtsp_lpclique *);
+    hhit = CC_SAFE_MALLOC (ncount, int);
+    thit = CC_SAFE_MALLOC (ncount, int);
+    if (!bigteeth || !hhit || !thit) {
+        fprintf (stderr, "out of memory in optimal_pseudocombn");
+        rval = 1; goto CLEANUP;
+    }
+
+    identify_big_teeth (c, ihandle, &nbig, bigteeth);
+
+    ro0 = CC_SAFE_MALLOC (nbig + 1, double);
+    ro1 = CC_SAFE_MALLOC (nbig + 1, double);
+    grab0 = CC_SAFE_MALLOC (nbig + 1, int);
+    grab1 = CC_SAFE_MALLOC (nbig + 1, int);
+    usebig = CC_SAFE_MALLOC (nbig + 1, int);
+    if (!ro0 || !ro1 || !grab0 || !grab1 || !usebig) {
+        fprintf (stderr, "out of memory in optimal_pseudocomb\n");
+        rval = 1; goto CLEANUP;
+    }
+    R  = CC_SAFE_MALLOC (nbig + 1, Rrecord *);
+    if (!R) {
+        fprintf (stderr, "out of memory in optimal_pseudocomb\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 0; i <= nbig; i++) {
+        R[i]  = (Rrecord *) NULL;
+        ro0[i] = 0.0;
+        ro1[i] = CCtsp_LP_MAXDOUBLE;
+    }
+
+    CCtsp_mark_cut_and_neighbors (g, c, hhit, 0);
+    CCtsp_mark_cut_and_neighbors (g, c, thit, 0);
+    CCtsp_mark_clique (handle, hhit, 1);
+    for (i = 1; i <= nbig; i++) {
+        CCtsp_mark_clique (bigteeth[i], thit, i);
+    }
+
+    for (si = 0; si < handle->segcount; si++) {
+        for (u = handle->nodes[si].lo; u <= handle->nodes[si].hi; u++) {
+            for (sj = 0; sj < g->nodes[u].deg; sj++) {
+                v = g->nodes[u].adj[sj].to;
+                e = g->nodes[u].adj[sj].edge;
+                if (hhit[v] != 1 && x[e] > 0.0) {
+                    if (thit[v] != 0 && thit[v] == thit[u]) {
+                        i = thit[v];
+                    } else {
+                        i = 0;
+                    }
+                    nu0 = ro0[i];
+                    nu1 = ro1[i];
+                    if (nu1 + (1.0 - 2.0*x[e]) < nu0) {
+                        ro0[i] = nu1 + (1.0 - 2.0*x[e]);
+                        add0 = e;
+                    } else {
+                        add0 = -1;
+                    }
+                    if (nu0 + (1.0 - 2.0*x[e]) < nu1) {
+                        ro1[i] = nu0 + (1.0 - 2.0*x[e]);
+                        add1 = e;
+                    } else {
+                        add1 = -1;
+                    }
+                    if (add0 != -1 || add1 != -1) {
+                        rval = add_to_record (&R[i], add0, add1);
+                        if (rval) {
+                            fprintf (stderr, "add_to_record failed\n");
+                            goto CLEANUP;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    for (i = 1; i <= nbig; i++) {
+        rval = CCtsp_clique_delta (g, x, bigteeth[i], &delta);
+        if (rval) {
+            fprintf (stderr, "CCtsp_clique_delta failed\n"); goto CLEANUP;
+        }
+        if (delta - 3.0 < ro1[i]) {
+            ro1[i] = delta - 3.0;
+            usebig[i] = 1;
+        } else {
+            usebig[i] = 0;
+        }
+        nu0 = ro0[0];
+        nu1 = ro1[0];
+        if (nu1 + ro1[i] < nu0 + ro0[i]) {
+            ro0[0] = nu1 + ro1[i];
+            grab0[i] = 1;
+        } else {
+            ro0[0] = nu0 + ro0[i];
+            grab0[i] = 0;
+        }
+        if (nu0 + ro1[i] < nu1 + ro0[i]) {
+            ro1[0] = nu0 + ro1[i];
+            grab1[i] = 1;
+        } else {
+            ro1[0] = nu1 + ro0[i];
+            grab1[i] = 0;
+        }
+    }
+
+    parity = 1;
+    for (i = nbig; i > 0; i--) {
+        if (parity) {
+            if (grab1[i]) {
+                if (usebig[i]) {
+                    rval = add_to_list (&newteeth, -i);
+                    if (rval) goto CLEANUP;
+                } else {
+                    rval = grab_record (R[i], 1, &newteeth);
+                    if (rval) goto CLEANUP;
+                }
+                parity = 0;
+            } else {
+                rval = grab_record (R[i], 0, &newteeth);
+                if (rval) goto CLEANUP;
+                parity = 1;
+            }
+        } else {
+            if (grab0[i]) {
+                if (usebig) {
+                    rval = add_to_list (&newteeth, -i);
+                    if (rval) goto CLEANUP;
+                } else {
+                    rval = grab_record (R[i], 1, &newteeth);
+                    if (rval) goto CLEANUP;
+                }
+                parity = 1;
+            } else {
+                rval = grab_record (R[i], 0, &newteeth);
+                if (rval) goto CLEANUP;
+                parity = 0;
+            }
+        }
+    }
+    rval = grab_record (R[0], parity, &newteeth);
+    if (rval) goto CLEANUP;
+
+    d->cliquecount = 1;
+    for (ip = newteeth; ip; ip = ip->next) {
+        d->cliquecount++;
+    }
+    d->cliques = CC_SAFE_MALLOC (d->cliquecount, CCtsp_lpclique);
+    if (!d->cliques) {
+        fprintf (stderr, "out of memory in optimal_pseudocombs\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_copy_lpclique (handle, &d->cliques[0]);
+    if (rval) {
+        fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+        CC_FREE (d->cliques, CCtsp_lpclique);
+        goto CLEANUP;
+    }
+    for (i = 1, ip = newteeth; ip; ip = ip->next, i++) {
+        if (ip->this < 0) {
+            rval = CCtsp_copy_lpclique (bigteeth[-ip->this], &d->cliques[i]);
+            if (rval) {
+                fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+                for (j = 0; j < i; j++) {
+                    CCtsp_free_lpclique (&d->cliques[j]);
+                }
+                CC_FREE (d->cliques, CCtsp_lpclique);
+                goto CLEANUP;
+            }
+        } else {
+            ends[0] = g->edges[ip->this].ends[0];
+            ends[1] = g->edges[ip->this].ends[1];
+            rval = CCtsp_array_to_lpclique (ends, 2, &d->cliques[i]);
+            if (rval) {
+                fprintf (stderr, "CCtsp_array_to_lpclique failed\n");
+                for (j = 0; j < i; j++) {
+                    CCtsp_free_lpclique (&d->cliques[j]);
+                }
+                CC_FREE (d->cliques, CCtsp_lpclique);
+                goto CLEANUP;
+            }
+        }
+    }
+
+    d->sense = 'G';
+    d->rhs = 3 * d->cliquecount - 2;
+
+CLEANUP:
+
+    CC_IFFREE (bigteeth, CCtsp_lpclique *);
+    CC_IFFREE (hhit, int);
+    CC_IFFREE (thit, int);
+    if (R) {
+        for (i = 0; i <= nbig; i++) {
+            Rrecordfree_list (R[i]);
+        }
+        CC_FREE (R, Rrecord *);
+    }
+    intptrfree_list (newteeth);
+    CC_IFFREE (ro0, double);
+    CC_IFFREE (ro1, double);
+    CC_IFFREE (grab0, int);
+    CC_IFFREE (grab1, int);
+    CC_IFFREE (usebig, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grab_record (Rrecord *r, int parity, intptr **list)
+#else
+static int grab_record (r, parity, list)
+Rrecord *r;
+int parity;
+intptr **list;
+#endif
+{
+    int rval = 0;
+
+    while (r) {
+        if (parity) {
+            if (r->add1 != -1) {
+                rval = add_to_list (list, r->add1);
+                if (rval) goto CLEANUP;
+                parity = 0;
+            }
+        } else {
+            if (r->add0 != -1) {
+                rval = add_to_list (list, r->add0);
+                if (rval) goto CLEANUP;
+                parity = 1;
+            }
+        }
+        r = r->next;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int clean_pseudocomb (CCtsp_lpgraph *g, double *x, CCtsp_lpcut_in *c,
+        CCtsp_lpcut_in *d)
+#else
+static int clean_pseudocomb (g, x, c, d)
+CCtsp_lpgraph *g;
+double *x;
+CCtsp_lpcut_in *c;
+CCtsp_lpcut_in *d;
+#endif
+{
+    int rval = 0;
+    int *hmarks      = (int *) NULL;
+    int *activeteeth = (int *) NULL;
+    int *cardteeth   = (int *) NULL;
+    int *harray      = (int *) NULL;
+    intptr **inteeth = (intptr **) NULL;
+    intptr *hlist    = (intptr *) NULL;
+    int ccount = c->cliquecount;
+    CCtsp_lpclique *handle = &c->cliques[0];
+    CCtsp_lpclique *cl;
+    int i, j, k, si, ismarked, cnt, big, ibig, ismall, hcnt;
+    double delta, smalldelta;
+    intptr *ip;
+
+    CCtsp_init_lpcut_in (d);
+
+    hmarks       = CC_SAFE_MALLOC (g->ncount, int);
+    activeteeth  = CC_SAFE_MALLOC (ccount, int);
+    cardteeth    = CC_SAFE_MALLOC (ccount, int);
+    if (!hmarks || !activeteeth || !cardteeth) {
+        fprintf (stderr, "out of memory in clean_pseudocomb\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    CCtsp_mark_cut (c, hmarks, 0);
+    CCtsp_mark_clique (handle, hmarks, 1);
+    for (i = 1; i < ccount; i++) {
+        activeteeth[i] = 1;
+        CCtsp_clique_count (&c->cliques[i], &cardteeth[i]);
+    }
+
+    inteeth = CC_SAFE_MALLOC (g->ncount, intptr *);
+    if (!inteeth) {
+        fprintf (stderr, "out of memory in clean_pseudocomb\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (i = 1; i < ccount; i++) {
+        cl = &c->cliques[i];
+        for (j = 0; j < cl->segcount; j++) {
+            for (k = cl->nodes[j].lo; k <= cl->nodes[j].hi; k++) {
+                inteeth[k] = (intptr *) NULL;
+            }
+        }
+    }
+    for (i = 0; i < handle->segcount; i++) {
+        for (j = handle->nodes[i].lo; j <= handle->nodes[i].hi; j++) {
+            inteeth[j] = (intptr *) NULL;
+        }
+    }
+
+    for (i = 1; i < ccount; i++) {
+        cl = &c->cliques[i];
+        for (j = 0; j < cl->segcount; j++) {
+            for (k = cl->nodes[j].lo; k <= cl->nodes[j].hi; k++) {
+                add_to_list (&inteeth[k], i);
+            }
+        }
+    }
+    for (i = 1; i < ccount; i++) {
+        if (!activeteeth[i]) continue;
+        cl = &c->cliques[i];
+        for (j = 0; j < cl->segcount; j++) {
+            for (k = cl->nodes[j].lo; k <= cl->nodes[j].hi; k++) {
+                if (!hmarks[k]) {
+                    cnt = 0;
+                    big = 0;
+                    ibig = -1;
+                    for (ip = inteeth[k]; ip; ip = ip->next) {
+                        if (activeteeth[ip->this]) {
+                            cnt++;
+                            if (cardteeth[ip->this] > big) {
+                                big = cardteeth[ip->this];
+                                ibig = ip->this;
+                            }
+                        }
+                    }
+                    if (cnt > 1) {
+                        CCtsp_mark_clique (&c->cliques[ibig], hmarks, 1);
+                        for (si = 1; si < ccount; si++) {
+                            if (activeteeth[si]) {
+                                CCtsp_is_clique_marked (&c->cliques[si],
+                                           hmarks, 0, &ismarked);
+                                activeteeth[si] = ismarked;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    for (i = 0; i < handle->segcount; i++) {
+        for (j = handle->nodes[i].lo; j <= handle->nodes[i].hi; j++) {
+            if (hmarks[j]) {
+                cnt = 0;
+                big = 0;
+                ibig = -1;
+                for (ip = inteeth[j]; ip; ip = ip->next) {
+                    if (activeteeth[ip->this]) {
+                        cnt++;
+                        if (cardteeth[ip->this] > big) {
+                            big = cardteeth[ip->this];
+                            ibig = ip->this;
+                        }
+                    }
+                }
+                if (cnt > 1) {
+                    CCtsp_mark_clique (&c->cliques[ibig], hmarks, 0);
+                    for (si = 1; si < ccount; si++) {
+                        if (activeteeth[si]) {
+                            CCtsp_is_clique_marked (&c->cliques[si],
+                                       hmarks, 1, &ismarked);
+                            activeteeth[si] = ismarked;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    for (i = 0, hcnt = 0; i < ccount; i++) {
+        cl = &c->cliques[i];
+        for (j = 0; j < cl->segcount; j++) {
+            for (k = cl->nodes[j].lo; k <= cl->nodes[j].hi; k++) {
+                if (hmarks[k] == 1) {
+                    rval = add_to_list (&hlist, k);
+                    if (rval) goto CLEANUP;
+                    hmarks[k] = 2;
+                    hcnt++;
+                }
+            }
+        }
+    }
+
+    if (!hcnt) {
+        printf ("WARNING: generalized comb gets and empty handle\n");
+        fflush (stdout);
+        goto CLEANUP;
+    }
+    harray = CC_SAFE_MALLOC (hcnt, int);
+    if (!harray) {
+        fprintf (stderr, "out of memory in clean_pseudocomb\n");
+        rval = 1; goto CLEANUP;
+    }
+    for (ip = hlist, hcnt = 0; ip; ip = ip->next) {
+        harray[hcnt++] = ip->this;
+    }
+
+    cnt = 0;
+    for (i = 1; i < ccount; i++) {
+        if (activeteeth[i]) cnt++;
+    }
+    if (!cnt) {
+        printf ("WARNING: generalized comb gets no teeth\n");
+        fflush (stdout);
+        goto CLEANUP;
+    }
+
+    if (cnt % 2 == 0) {
+        smalldelta = CCtsp_LP_MAXDOUBLE;
+        ismall = -1;
+        for (i = 1; i < ccount; i++) {
+            if (activeteeth[i]) {
+                rval = CCtsp_clique_delta (g, x, &c->cliques[i], &delta);
+                if (rval) {
+                    fprintf (stderr, "CCtsp_clique_delta failed\n");
+                     goto CLEANUP;
+                }
+                if (delta < smalldelta) {
+                    smalldelta = delta;
+                    ismall = i;
+                }
+            }
+        }
+        activeteeth[ismall] = 0;
+        cnt--;
+    }
+    cnt++;
+
+    d->cliques = CC_SAFE_MALLOC (cnt, CCtsp_lpclique);
+    if (!d->cliques) {
+        fprintf (stderr, "out of memory in clean_pseudocomb\n");
+        rval = 1; goto CLEANUP;
+    }
+    rval = CCtsp_array_to_lpclique (harray, hcnt, &d->cliques[0]);
+    if (rval) {
+        fprintf (stderr, "CCtsp_array_to_lpclique failed\n");
+        CC_FREE (d->cliques, CCtsp_lpclique);
+        goto CLEANUP;
+    }
+    for (i = 1, cnt = 1; i < ccount; i++) {
+        if (activeteeth[i]) {
+            rval = CCtsp_copy_lpclique (&c->cliques[i], &d->cliques[cnt++]);
+            if (rval) {
+                fprintf (stderr, "CCtsp_copy_lpclique failed\n");
+                for (j = 0; j < cnt; j++) {
+                    CCtsp_free_lpclique (&d->cliques[j]);
+                }
+                CC_FREE (d->cliques, CCtsp_lpclique);
+                goto CLEANUP;
+            }
+        }
+    }
+    d->cliquecount = cnt;
+    d->rhs = 3 * d->cliquecount - 2;
+    d->sense = 'G';
+
+CLEANUP:
+
+    CC_IFFREE (hmarks, int);
+    CC_IFFREE (activeteeth, int);
+    CC_IFFREE (cardteeth, int);
+    CC_IFFREE (harray, int);
+    if (inteeth) {
+        for (i = 1; i < ccount; i++) {
+            cl = &c->cliques[i];
+            for (j = 0; j < cl->segcount; j++) {
+                for (k = cl->nodes[j].lo; k <= cl->nodes[j].hi; k++) {
+                    if (inteeth[k]) {
+                        intptrfree_list (inteeth[k]);
+                        inteeth[k] = (intptr *) NULL;
+                    }
+                }
+            }
+        }
+        CC_FREE (inteeth, intptr *);
+    }
+    intptrfree_list (hlist);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void teething_free_world (void)
+#else
+static void teething_free_world ()
+#endif
+{
+    int total, onlist;
+
+    if (intptr_status (&total, &onlist)) {
+        printf ("Active Teething Intptrs: %d\n", total - onlist);
+        fflush (stdout);
+    } else {
+        if (intptr_check_leaks (&total, &onlist)) {
+            fprintf (stderr, "WARNING: %d outstanding intptrs in teething\n",
+                           total - onlist);
+        }
+        intptrfree_world ();
+    }
+
+    if (Rrecord_status (&total, &onlist)) {
+        printf ("Active Teething Rrecords: %d\n", total - onlist);
+        fflush (stdout);
+    } else {
+        if (Rrecord_check_leaks (&total, &onlist)) {
+            fprintf (stderr, "WARNING: %d outstanding Rrecords in teething\n",
+                           total - onlist);
+        }
+        Rrecordfree_world ();
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void identify_big_teeth (CCtsp_lpcut_in *cut, int handle, int *nbig,
+        CCtsp_lpclique **bigteeth)
+#else
+static void identify_big_teeth (cut, handle, nbig, bigteeth)
+CCtsp_lpcut_in *cut;
+int handle;
+int *nbig;
+CCtsp_lpclique **bigteeth;
+#endif
+{
+    int i, k;
+
+    /* teeth filled into positions 1 through nbig */
+
+    *nbig = 0;
+    for (i = 0; i < cut->cliquecount; i++) {
+        if (i != handle) {
+            CCtsp_clique_count (&(cut->cliques[i]), &k);
+            if (k >= 3) {
+                bigteeth[++(*nbig)] = &(cut->cliques[i]);
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_to_list (intptr **list, int item)
+#else
+static int add_to_list (list, item)
+intptr **list;
+int item;
+#endif
+{
+    intptr *ip;
+
+    ip = intptralloc ();
+    if (!ip) { fprintf (stderr, "intptralloc failed\n"); return 1; }
+    ip->this = item;
+    ip->next = *list;
+    *list = ip;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_to_record (Rrecord **R, int add0, int add1)
+#else
+static int add_to_record (R, add0, add1)
+Rrecord **R;
+int add0, add1;
+#endif
+{
+    Rrecord *p;
+
+    p = Rrecordalloc ();
+    if (!p) { fprintf (stderr, "Rrecordalloc failed\n"); return 1; }
+    p->add0 = add0;
+    p->add1 = add1;
+    p->next = *R;
+    *R = p;
+    return 0;
+}
diff --git a/contrib/blossom/concorde97/TSP/tighten.c b/contrib/blossom/concorde97/TSP/tighten.c
new file mode 100644
index 0000000000000000000000000000000000000000..5062cefc11b155b0c66aa9fb46018ffb606380ca
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/tighten.c
@@ -0,0 +1,878 @@
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+
+#undef  USE_INLINES
+#undef  TIGHTEN_NOTIEADD
+#undef  NOTIGHTEN
+
+#define EPS (1e-6)
+
+typedef struct tighten_node {
+    struct tighten_node *next;              /* to maintain atomlist */
+    struct tighten_node *prev;
+    struct tighten_node **atomlist;         /* alpha(v) */
+    struct qu_elem *moves;                  /* size ncliques */
+    struct tighten_node *next_initialized;  /* to maintain initialized_nodes */
+} tighten_node;
+
+typedef struct qu_elem {
+    double delta;
+    tighten_node *v;                        /* node to move */
+    int i;                                  /* clique to adjust */
+    int chi;                                /* 0==outside, last del tied */
+                                            /* 1==inside, 2 otherwise */
+    int queue_handle;
+} qu_elem;
+
+typedef union atomfind {
+    union atomfind *child[2];
+    tighten_node *nodelist;                 /* A(I) in writeup */
+    union atomfind *next;                   /* for freelist */
+} atomfind;
+
+typedef struct tighten_graph {
+    CCtsp_lpgraph *g;
+    struct tighten_node *nodes;
+    double *x;
+    int ncliques;
+    int nhandles;
+    int rhs;
+
+    atomfind *atomtree;
+    tighten_node *initialized_nodes;       /* Vstar in writeup */
+    CCpriority queue;
+} tighten_graph;
+
+#define NODE_IN_SINGLETON(v) ((v)->atomlist && (*((v)->atomlist))       \
+                              && (!(*((v)->atomlist))->next))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    add_to_atom (tighten_node *v),
+    delete_from_atom (tighten_node *v),
+    cleanup_atomfinder (atomfind *tree, int depth),
+    cleanup_graph (tighten_graph *tg);
+
+static int
+    update_queue (CCpriority *q, qu_elem *qe),
+    initialize_graph (CCtsp_lpgraph *g, double *x, tighten_graph *tg),
+    initialize_lpcut_in (tighten_graph *tg, CCtsp_lpcut_in *c),
+    initialize_lpcut (tighten_graph *tg, CCtsp_lpclique *cliques,
+        CCtsp_lpcut *c),
+    initialize_node (tighten_graph *tg, tighten_node *v, int add_atom),
+    process_qu_elem (tighten_graph *tg, qu_elem *q),
+    process_qu_elem_atom (tighten_graph *tg, tighten_node *v),
+    process_qu_elem_delta (tighten_graph *tg, qu_elem *q),
+    collect_new_cut (tighten_graph *tg, CCtsp_lpcut_in *cout),
+    tighten_cut (tighten_graph *tg, CCtsp_tighten_info *stats,
+        double *pimprove);
+
+static tighten_node
+  **find_atomlist (tighten_graph *tg, tighten_node *v, int add);
+
+#ifndef USE_INLINES
+static double
+    qu_elem_key (qu_elem *q);
+static int
+    qu_elem_is_active (qu_elem *q);
+#endif
+
+#else /* CC_PROTOTYPE_ANSI */
+
+static void
+    add_to_atom (),
+    delete_from_atom (),
+    cleanup_atomfinder (),
+    cleanup_graph ();
+
+static int
+    update_queue (),
+    initialize_graph (),
+    initialize_lpcut_in (),
+    initialize_lpcut (),
+    initialize_node (),
+    process_qu_elem (),
+    process_qu_elem_atom (),
+    process_qu_elem_delta (),
+    collect_new_cut (),
+    tighten_cut ();
+
+static tighten_node
+  **find_atomlist ();
+
+#ifndef USE_INLINES
+static double
+    qu_elem_key ();
+static int
+    qu_elem_is_active ();
+#endif
+
+#endif /* CC_PROTOTYPE_ANSI */
+
+CC_PTR_ALLOC_ROUTINE (atomfind, atomfind_alloc, chunklist, atomfind_freelist)
+CC_PTR_FREE_ROUTINE (atomfind, atomfind_free, atomfind_freelist)
+CC_PTR_FREE_WORLD_ROUTINE (atomfind, atomfind_freeworld, chunklist,
+        atomfind_freelist)
+CC_PTR_LEAKS_ROUTINE (atomfind, atomfind_leaks, chunklist, atomfind_freelist,
+        child[1], atomfind *)
+
+#ifdef USE_INLINES
+
+#define qu_elem_key(q) (((q)->delta > EPS) ? (-(3.0 + (q)->delta))        \
+                                         : (-((q)->chi + (q)->delta)))
+#ifdef TIGHTEN_NOTIEADD
+#define qu_elem_is_active(q) ((!NODE_IN_SINGLETON((q)->v))                \
+                            && ((q)->delta > EPS                          \
+                                || ((q)->delta >= 0.0 && (q)->chi == 1)))
+#else
+#define qu_elem_is_active(q) ((!NODE_IN_SINGLETON((q)->v))                \
+                            && ((q)->delta > EPS                          \
+                                || ((q)->delta >= 0.0 && (q)->chi > 0)))
+#endif
+
+#else /* USE_INLINES */
+
+#ifdef CC_PROTOTYPE_ANSI
+static double qu_elem_key (qu_elem *q)
+#else
+static double qu_elem_key (q)
+qu_elem *q;
+#endif
+{
+    double key;
+
+    if (q->delta > EPS) {
+        key = 3.0 + q->delta;
+    } else {
+        key = q->chi + q->delta;
+    }
+    return -key;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int qu_elem_is_active (qu_elem *q)
+#else
+static int qu_elem_is_active (q)
+qu_elem *q;
+#endif
+{
+#ifdef TIGHTEN_NOTIEADD
+    return ((!NODE_IN_SINGLETON(q->v))
+            && ((q->delta > EPS)
+                || ((q)->delta >= 0.0 && (q)->chi == 1)));
+#else
+    return ((!NODE_IN_SINGLETON(q->v))
+            && ((q->delta > EPS)
+                || ((q)->delta >= 0.0 && (q)->chi > 0)));
+#endif
+}
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static void add_to_atom (tighten_node *v)
+#else
+static void add_to_atom (v)
+tighten_node *v;
+#endif
+{
+    if (v->atomlist) {
+        v->next = *(v->atomlist);
+        if (v->next) v->next->prev = v;
+        v->prev = (tighten_node *) NULL;
+        *(v->atomlist) = v;
+    } else {
+        v->next = (tighten_node *) NULL;
+        v->prev = (tighten_node *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void delete_from_atom (tighten_node *v)
+#else
+static void delete_from_atom (v)
+tighten_node *v;
+#endif
+{
+    if (v->next) v->next->prev = v->prev;
+    if (v->prev) v->prev->next = v->next;
+    else if (v->atomlist) *(v->atomlist) = v->next;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int update_queue (CCpriority *q, qu_elem *qe)
+#else
+static int update_queue (q, qe)
+CCpriority *q;
+qu_elem *qe;
+#endif
+{
+    double newkey;
+    int handle;
+
+    if (qu_elem_is_active (qe)) {
+        newkey = qu_elem_key (qe);
+        if (qe->queue_handle >= 0) {
+            CCutil_priority_changekey (q, qe->queue_handle, newkey);
+        } else {
+            handle = CCutil_priority_insert (q, (void *) qe, newkey);
+            if (handle < 0) {
+                return handle;
+            }
+            qe->queue_handle = handle;
+        }
+    } else {
+        if (qe->queue_handle >= 0) {
+            CCutil_priority_delete (q, qe->queue_handle);
+            qe->queue_handle = -1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static tighten_node **find_atomlist (tighten_graph *tg, tighten_node *v,
+        int add)
+#else
+static tighten_node **find_atomlist (tg, v, add)
+tighten_graph *tg;
+tighten_node *v;
+int add;
+#endif
+{
+    atomfind *f = tg->atomtree;
+    atomfind **pf = &(tg->atomtree);
+    int i;
+    int dir;
+
+    for (i=0; i<tg->ncliques; i++) {
+        if (!f) {
+            if (add) {
+                (*pf) = f = atomfind_alloc();
+                if (!f) return (tighten_node **) NULL;
+                f->child[0] = (atomfind *) NULL;
+                f->child[1] = (atomfind *) NULL;
+            } else {
+                return (tighten_node **) NULL;
+            }
+        }
+
+        dir = v->moves[i].chi & 1;
+        pf = &(f->child[dir]);
+        f = f->child[dir];
+    }
+    if (!f) {
+        if (add) {
+            (*pf) = f = atomfind_alloc();
+            if (!f) return (tighten_node **) NULL;
+            f->nodelist = (tighten_node *) NULL;
+        } else {
+            return (tighten_node **) NULL;
+        }
+    }
+
+    return &(f->nodelist);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void cleanup_atomfinder (atomfind *tree, int depth)
+#else
+static void cleanup_atomfinder (tree, depth)
+atomfind *tree;
+int depth;
+#endif
+{
+    if (depth > 0) {
+        if (tree->child[0]) {
+            cleanup_atomfinder (tree->child[0], depth-1);
+        }
+        if (tree->child[1]) {
+            cleanup_atomfinder (tree->child[1], depth-1);
+        }
+    }
+    atomfind_free (tree);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int initialize_graph (CCtsp_lpgraph *g, double *x, tighten_graph *tg)
+#else
+static int initialize_graph (g, x, tg)
+CCtsp_lpgraph *g;
+double *x;
+tighten_graph *tg;
+#endif
+{
+    int rval;
+
+    tg->g = g;
+    tg->x = x;
+
+    tg->nodes = (tighten_node *) CC_SAFE_MALLOC (g->ncount, tighten_node);
+    if (!tg->nodes) return -1;
+
+    rval = CCutil_priority_init (&tg->queue, 1000);
+    if (rval) {
+        CC_FREE (tg->nodes, tighten_node);
+        return rval;
+    }
+
+    tg->initialized_nodes = (tighten_node *) NULL;
+    tg->atomtree = (atomfind *) NULL;
+    tg->ncliques = 0;
+    g->nodemarker++;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int initialize_lpcut_in (tighten_graph *tg, CCtsp_lpcut_in *c)
+#else
+static int initialize_lpcut_in (tg, c)
+tighten_graph *tg;
+CCtsp_lpcut_in *c;
+#endif
+{
+    int i,j,k,l,m;
+    CCtsp_lpgraph *g = tg->g;
+    CCtsp_lpclique *cl;
+    tighten_node *v;
+    int rval;
+
+    tg->ncliques = c->cliquecount;
+    tg->nhandles = c->handlecount;
+    tg->rhs = c->rhs;
+    for (i=0; i<tg->ncliques; i++) {
+        cl = &(c->cliques[i]);
+        for (j=0; j<cl->segcount; j++) {
+            for (k=cl->nodes[j].lo; k<=cl->nodes[j].hi; k++) {
+                if (g->nodes[k].mark < g->nodemarker) {
+                    rval = initialize_node (tg, &(tg->nodes[k]), 0);
+                    if (rval) return rval;
+                }
+                tg->nodes[k].moves[i].chi = 1;
+                for (l=0; l<g->nodes[k].deg; l++) {
+                    m = g->nodes[k].adj[l].to;
+                    if (g->nodes[m].mark < g->nodemarker) {
+                        rval = initialize_node (tg, &(tg->nodes[m]), 0);
+                        if (rval) return rval;
+                    }
+                }
+            }
+        }
+    }
+
+    for (v = tg->initialized_nodes; v; v = v->next_initialized) {
+        v->atomlist = find_atomlist (tg, v, 1);
+        if (!v->atomlist) {
+            return -1;
+        }
+        add_to_atom (v);
+    }
+
+    for (v = tg->initialized_nodes; v; v = v->next_initialized) {
+        k = v - tg->nodes;
+        for (l=0; l<g->nodes[k].deg; l++) {
+            m = g->nodes[k].adj[l].to;
+            if (g->nodes[m].mark == g->nodemarker) {
+                for (i=0; i<tg->ncliques; i++) {
+                    if (v->moves[i].chi != tg->nodes[m].moves[i].chi) {
+                        v->moves[i].delta += tg->x[g->nodes[k].adj[l].edge];
+                    }
+                }
+            }
+        }
+        for (i=0; i<tg->ncliques; i++) {
+            rval = update_queue (&tg->queue, &v->moves[i]);
+            if (rval) return rval;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int initialize_lpcut (tighten_graph *tg, CCtsp_lpclique *cliques,
+        CCtsp_lpcut *c)
+#else
+static int initialize_lpcut (tg, cliques, c)
+tighten_graph *tg;
+CCtsp_lpclique *cliques;
+CCtsp_lpcut *c;
+#endif
+{
+    int i,j,k,l,m;
+    CCtsp_lpgraph *g = tg->g;
+    CCtsp_lpclique *cl;
+    tighten_node *v;
+    int rval;
+
+    tg->ncliques = c->cliquecount;
+    tg->nhandles = c->handlecount;
+    tg->rhs = c->rhs;
+    for (i=0; i<tg->ncliques; i++) {
+        cl = &cliques[c->cliques[i]];
+        for (j=0; j<cl->segcount; j++) {
+            for (k=cl->nodes[j].lo; k<=cl->nodes[j].hi; k++) {
+                if (g->nodes[k].mark < g->nodemarker) {
+                    rval = initialize_node (tg, &(tg->nodes[k]), 0);
+                    if (rval) return rval;
+                }
+                tg->nodes[k].moves[i].chi = 1;
+                for (l=0; l<g->nodes[k].deg; l++) {
+                    m = g->nodes[k].adj[l].to;
+                    if (g->nodes[m].mark < g->nodemarker) {
+                        rval = initialize_node (tg, &(tg->nodes[m]), 0);
+                        if (rval) return rval;
+                    }
+                }
+            }
+        }
+    }
+
+    for (v = tg->initialized_nodes; v; v = v->next_initialized) {
+        v->atomlist = find_atomlist (tg, v, 1);
+        if (!v->atomlist) {
+            return -1;
+        }
+        add_to_atom (v);
+    }
+
+    for (v = tg->initialized_nodes; v; v = v->next_initialized) {
+        k = v - tg->nodes;
+        for (l=0; l<g->nodes[k].deg; l++) {
+            m = g->nodes[k].adj[l].to;
+            if (g->nodes[m].mark == g->nodemarker) {
+                for (i=0; i<tg->ncliques; i++) {
+                    if (v->moves[i].chi != tg->nodes[m].moves[i].chi) {
+                        v->moves[i].delta += tg->x[g->nodes[k].adj[l].edge];
+                    }
+                }
+            }
+        }
+        for (i=0; i<tg->ncliques; i++) {
+            rval = update_queue (&tg->queue, &v->moves[i]);
+            if (rval) return rval;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int initialize_node (tighten_graph *tg, tighten_node *v, int add_atom)
+#else
+static int initialize_node (tg, v, add_atom)
+tighten_graph *tg;
+tighten_node *v;
+int add_atom;
+#endif
+{
+    int i;
+
+    v->moves = CC_SAFE_MALLOC (tg->ncliques, qu_elem);
+    if (!v->moves) return -1;
+
+    for (i=0; i<tg->ncliques; i++) {
+        v->moves[i].v = v;
+        v->moves[i].i = i;
+        v->moves[i].delta = -1.0;
+        v->moves[i].chi = 2;
+        v->moves[i].queue_handle = -1;
+    }
+    if (add_atom) {
+        v->atomlist = find_atomlist (tg, v, 0);
+        if (v->atomlist) {
+            add_to_atom (v);
+        }
+    } else {
+        v->atomlist = (tighten_node **) NULL;
+    }
+
+    v->next_initialized = tg->initialized_nodes;
+    tg->initialized_nodes = v;
+
+    tg->g->nodes[v - tg->nodes].mark = tg->g->nodemarker;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int process_qu_elem (tighten_graph *tg, qu_elem *q)
+#else
+static int process_qu_elem (tg, q)
+tighten_graph *tg;
+qu_elem *q;
+#endif
+{
+    int rval;
+
+    if (q->chi == 1) {
+        if (q->delta <= EPS) {
+            q->chi = 0;
+        } else {
+            q->chi = 2;
+        }
+    } else {
+        q->chi = 1;
+    }
+    rval = process_qu_elem_atom (tg, q->v);
+    if (rval) return rval;
+    rval = process_qu_elem_delta (tg, q);
+    if (rval) return rval;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int process_qu_elem_atom (tighten_graph *tg, tighten_node *v)
+#else
+static int process_qu_elem_atom (tg, v)
+tighten_graph *tg;
+tighten_node *v;
+#endif
+{
+    tighten_node *w;
+    int j;
+    int rval;
+
+    if (v->atomlist) {
+        delete_from_atom (v);
+
+        if (NODE_IN_SINGLETON(v)) {
+            w = *(v->atomlist);
+            for (j=0; j<tg->ncliques; j++) {
+                rval = update_queue (&tg->queue, &w->moves[j]);
+                if (rval) return rval;
+            }
+        }
+    }
+
+    /* chi was updated before the call */
+    v->atomlist = find_atomlist (tg, v, 0);
+
+    if (v->atomlist) {
+        w = *(v->atomlist);
+
+        add_to_atom (v);
+
+        if (w->next == (tighten_node *) NULL) {
+            /* v->atomlist was the singleton w */
+            for (j=0; j<tg->ncliques; j++) {
+                rval = update_queue (&tg->queue, &w->moves[j]);
+                if (rval) return rval;
+            }
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int process_qu_elem_delta (tighten_graph *tg, qu_elem *q)
+#else
+static int process_qu_elem_delta (tg, q)
+tighten_graph *tg;
+qu_elem *q;
+#endif
+{
+    tighten_node *v = q->v;
+    int i = q->i;
+    tighten_node *w;
+    int j;
+    CCtsp_lpgraph *g = tg->g;
+    int nv = v - tg->nodes;
+    int nw;
+    int e;
+    int rval;
+
+    v->moves[i].delta = -v->moves[i].delta;
+    rval = update_queue (&tg->queue, &v->moves[i]);
+    if (rval) return rval;
+
+    for (j=0; j<g->nodes[nv].deg; j++) {
+        nw = g->nodes[nv].adj[j].to;
+        e = g->nodes[nv].adj[j].edge;
+        w = &tg->nodes[nw];
+        if (g->nodes[nw].mark < g->nodemarker) {
+            rval = initialize_node (tg, w, 1);
+            if (rval) return rval;
+        }
+
+        if ((v->moves[i].chi & 1) == (w->moves[i].chi & 1)) {
+            w->moves[i].delta -= tg->x[e];
+        } else {
+            w->moves[i].delta += tg->x[e];
+        }
+        rval = update_queue (&tg->queue, &w->moves[i]);
+        if (rval) return rval;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void cleanup_graph (tighten_graph *tg)
+#else
+static void cleanup_graph (tg)
+tighten_graph *tg;
+#endif
+{
+    tighten_node *v, *vnext;
+
+    for (v = tg->initialized_nodes; v; v = vnext) {
+        vnext = v->next_initialized;
+        CC_FREE (v->moves, qu_elem);
+    }
+    cleanup_atomfinder (tg->atomtree, tg->ncliques);
+
+#if 0
+    {
+        int total, onlist, leak;
+        if ((leak = atomfind_leaks(&total, &onlist))) {
+            fprintf (stderr, "TIGHTEN leaked %d atomfind's (total %d onlist %d)\n",
+                     leak, total, onlist);
+        }
+    }
+#endif
+
+    atomfind_freeworld();
+
+    CCutil_priority_free (&tg->queue);
+
+    CC_FREE (tg->nodes, tighten_node);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int collect_lpclique (tighten_graph *tg, int cnum, CCtsp_lpclique *c)
+#else
+static int collect_lpclique (tg, cnum, c)
+tighten_graph *tg;
+int cnum;
+CCtsp_lpclique *c;
+#endif
+{
+    tighten_node *v;
+    int cnt;
+    int *arr;
+    int rval;
+
+    cnt = 0;
+    for (v = tg->initialized_nodes; v; v = v->next_initialized) {
+        if (v->moves[cnum].chi == 1) cnt++;
+    }
+    arr = CC_SAFE_MALLOC (cnt, int);
+    if (!arr) return -1;
+
+    cnt = 0;
+    for (v = tg->initialized_nodes; v; v = v->next_initialized) {
+        if (v->moves[cnum].chi == 1) {
+            arr[cnt++] = v - tg->nodes;
+        }
+    }
+
+    rval = CCtsp_array_to_lpclique (arr, cnt, c);
+    CC_FREE (arr, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int collect_new_cut (tighten_graph *tg, CCtsp_lpcut_in *cout)
+#else
+static int collect_new_cut (tg, cout)
+tighten_graph *tg;
+CCtsp_lpcut_in *cout;
+#endif
+{
+    int i, j;
+    int rval;
+
+    cout->handlecount = tg->nhandles;
+    cout->cliquecount = tg->ncliques;
+    cout->rhs = tg->rhs;
+    cout->cliques = CC_SAFE_MALLOC (tg->ncliques, CCtsp_lpclique);
+    if (!cout->cliques) {
+        return -1;
+    }
+
+    for (i=0; i<tg->ncliques; i++) {
+        rval = collect_lpclique (tg, i, &(cout->cliques[i]));
+        if (rval) {
+            for (j=0; j<i; j++) {
+                CC_FREE (cout->cliques[i].nodes, CCtsp_segment);
+            }
+            CC_FREE (cout->cliques, CCtsp_lpclique);
+            return rval;
+        }
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int tighten_cut (tighten_graph *tg, CCtsp_tighten_info *stats,
+        double *pimprove)
+#else
+static int tighten_cut (tg, stats, pimprove)
+tighten_graph *tg;
+CCtsp_tighten_info *stats;
+double *pimprove;
+#endif
+{
+    qu_elem *q;
+    int rval;
+    double improve = 0.0;
+
+    while ((q = (qu_elem *) CCutil_priority_deletemin (&tg->queue,
+                                                       (double *) NULL))) {
+        if (q->v->moves[q->i].chi == 1) {
+            stats->ndel++;
+            stats->del_delta += q->delta;
+            if (q->delta <= EPS) stats->ndel_tied++;
+        } else {
+            stats->nadd++;
+            stats->add_delta += q->delta;
+            if (q->delta <= EPS) stats->nadd_tied++;
+        }
+        improve += q->delta;
+        q->queue_handle = -1;
+        rval = process_qu_elem (tg, q);
+        if (rval) return rval;
+    }
+    if (pimprove) *pimprove = improve;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_tighten_lpcut_in (CCtsp_lpgraph *g, CCtsp_lpcut_in *c, double *x,
+        CCtsp_lpcut_in *cout, CCtsp_tighten_info *stats, double *pimprove)
+#else
+int CCtsp_tighten_lpcut_in (g, c, x, cout, stats, pimprove)
+CCtsp_lpgraph *g;
+CCtsp_lpcut_in *c;
+double *x;
+CCtsp_lpcut_in *cout;
+CCtsp_tighten_info *stats;
+double *pimprove;
+#endif
+{
+    tighten_graph tg;
+    int rval = 0;
+    double szeit = CCutil_zeit ();
+
+    if (c->branch != 0) {
+        fprintf (stderr, "try to tighten a branch cut\n"); return 1;
+    }
+    if (c->sense != 'G') {
+        fprintf (stderr, "try to tighten a <= cut\n"); return 1;
+    }
+
+    rval = initialize_graph (g, x, &tg);
+    if (rval) return rval;
+
+    rval = initialize_lpcut_in (&tg, c);
+    if (rval) goto CLEANUP;
+
+#ifndef NOTIGHTEN
+    rval = tighten_cut (&tg, stats, pimprove);
+    if (rval) goto CLEANUP;
+#endif
+
+    rval = collect_new_cut (&tg, cout);
+    if (rval) goto CLEANUP;
+
+    cout->branch = c->branch;
+    cout->sense  = c->sense;
+
+CLEANUP:
+
+    stats->ncall++;
+    if (rval) stats->nfail++;
+    stats->time += CCutil_zeit () - szeit;
+    cleanup_graph (&tg);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_tighten_lpcut (CCtsp_lpgraph *g, CCtsp_lpclique *cliques,
+        CCtsp_lpcut *c, double *x, CCtsp_lpcut_in *cout,
+        CCtsp_tighten_info *stats, double *pimprove)
+#else
+int CCtsp_tighten_lpcut (g, cliques, c, x, cout, stats, pimprove)
+CCtsp_lpgraph *g;
+CCtsp_lpclique *cliques;
+CCtsp_lpcut *c;
+double *x;
+CCtsp_lpcut_in *cout;
+CCtsp_tighten_info *stats;
+double *pimprove;
+#endif
+{
+    tighten_graph tg;
+    int rval = 0;
+    double szeit = CCutil_zeit ();
+
+    if (c->branch != 0) {
+        fprintf (stderr, "try to tighten a branch cut\n"); return 1;
+    }
+    if (c->sense != 'G') {
+        fprintf (stderr, "try to tighten a <= cut\n"); return 1;
+    }
+
+    rval = initialize_graph (g, x, &tg);
+    if (rval) return rval;
+
+    rval = initialize_lpcut (&tg, cliques, c);
+    if (rval) goto CLEANUP;
+
+    rval = tighten_cut (&tg, stats, pimprove);
+    if (rval) goto CLEANUP;
+
+    rval = collect_new_cut (&tg, cout);
+    if (rval) goto CLEANUP;
+
+    cout->branch = c->branch;
+    cout->sense  = c->sense;
+
+CLEANUP:
+
+    stats->ncall++;
+    if (rval) stats->nfail++;
+    stats->time += CCutil_zeit () - szeit;
+    cleanup_graph (&tg);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_init_tighten_info (CCtsp_tighten_info *stats)
+#else
+void CCtsp_init_tighten_info (stats)
+CCtsp_tighten_info *stats;
+#endif
+{
+    stats->ncall = 0;
+    stats->nfail = 0;
+    stats->nadd = 0;
+    stats->nadd_tied = 0;
+    stats->ndel = 0;
+    stats->ndel_tied = 0;
+    stats->add_delta = 0.0;
+    stats->del_delta = 0.0;
+    stats->time = 0.0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_print_tighten_info (CCtsp_tighten_info *stats)
+#else
+void CCtsp_print_tighten_info (stats)
+CCtsp_tighten_info *stats;
+#endif
+{
+    printf ("TIGHTEN STATS: %d calls (%d failed), %.2f improvement, %.2f seconds\n",
+            stats->ncall, stats->nfail, stats->add_delta + stats->del_delta,
+            stats->time);
+    printf ("               %d adds, %d tied, %.2f improvement\n",
+            stats->nadd, stats->nadd_tied, stats->add_delta);
+    printf ("               %d dels, %d tied, %.2f improvement\n",
+            stats->ndel, stats->ndel_tied, stats->del_delta);
+    fflush (stdout);
+}
diff --git a/contrib/blossom/concorde97/TSP/tsp_lp.c b/contrib/blossom/concorde97/TSP/tsp_lp.c
new file mode 100644
index 0000000000000000000000000000000000000000..af143474e78ee126513fb82ce3fb86b153929cca
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/tsp_lp.c
@@ -0,0 +1,3691 @@
+/***************************************************************************/
+/*                                                                         */
+/*            ROUTINES TO BUILD LPS AND CALL THE LP SOLVER                 */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: September 26, 1995                                               */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    void CCtsp_init_tsp_lp_struct (CCtsp_lp *lp)                         */
+/*     INITIALIZES the CCtsp_lp struture with NULL values                  */
+/*                                                                         */
+/*    int CCtsp_init_lp (CCtsp_lp **lp, char *probname, int probnum,       */
+/*           char *probfilename, int ncount, CCdatagroup *dat, int ecount, */
+/*           int *elist, int *elen, int excount, int *exlist, int *exlen,  */
+/*           int exvalid, int *ptour, double initial_ub,                   */
+/*           CCtsp_lpcuts *pool)                                           */
+/*     BUILDS/READS the problem, and loads it into the LP solver. If       */
+/*      probnum < 0, init_lp will build an initial problem according to    */
+/*      edgegengroup; otherwise it will read the problem from disk. If     */
+/*      the problem is read from disk, then the elist is ignored.          */
+/*      -lp is a handle to the tsp lp (filled in by init_lp)               */
+/*      -probname is the name for the problem                              */
+/*      -probnum is the number for the problem                             */
+/*      -ncount is the number of nodes                                     */
+/*      -dat is a handle on the complete graph                             */
+/*      -plan says how to generate an initial edgeset                      */
+/*      -ecount, elist, elen specify an initial edge set (they can be      */
+/*       0, NULL, NULL); if a prob is read from a file, then this list     */
+/*       is ignored                                                        */
+/*      -excount, exlist, exlen specify an full edge set (they can be      */
+/*       0, NULL, NULL); if the probfile already has an full edge set,     */
+/*       then this values are ignored.                                     */
+/*      -exvalid indicates whether or not the edges specified in exlist    */
+/*       are a valid complete set of edges (0 no, 1 yes)                   */
+/*      -pool is a pointer to a cutpool (can be NULL)                      */
+/*     NOTE: If init_lp returns 2, then the LP is infeasible (even after   */
+/*      considering the full edge set).                                    */
+/*                                                                         */
+/*    int CCtsp_bb_init_lp (CCtsp_lp **lp, char *probname, int probnum,    */
+/*            int ncount, CCdatagroup *dat, int *ptour, double initial_ub, */
+/*            CCtsp_lpcuts *pool)                                          */
+/*      SHORT form of CCtsp_init_lp for use in the branch and bound.       */
+/*                                                                         */
+/*    int CCtsp_get_lp_result (CCtsp_lp *lp, double *lb, double *ub,       */
+/*            int *ecount, int **elist, double **x, double **rc,           */
+/*            double **node_pi, double **cut_pi)                           */
+/*     RETURNS a copy of the values cached in lp->result. However, it      */
+/*      allows a single point of locking for the threaded version. Any     */
+/*      return argument can be NULL.                                       */
+/*      -lp is a pointer to the tsp lp                                     */
+/*      -obj returns the location for the current objective value          */
+/*      -ecount returns the location for the number of nonzero edges       */
+/*      -elist returns the  location for the nonzero edges in end1 end2    */
+/*       format                                                            */
+/*      -x returns location for the edge values                            */
+/*      -rc returns location for the edge values                           */
+/*      -node_pi returns the values on the degree constraints              */
+/*      -cut_pi returns the dual values on the cuts                        */
+/*     NOTE: node_pi and cut_pi go to the LP to fetch the results.         */
+/*                                                                         */
+/*    int CCtsp_add_cut (CCtsp_lp *lp, CCtsp_lpcut_in *d, CCtsp_lprow *cr) */
+/*     ADDS cut d to the lp structure and to cr (a call to                 */
+/*      CCtsp_add_multiple will put the cut into the lp solver)            */
+/*                                                                         */
+/*    int CCtsp_add_multiple_rows (CCtsp_lp *lp, CCtsp_lprow *cr)          */
+/*     HANDS the cuts in cr to the lp solver.                              */
+/*                                                                         */
+/*    void CCtsp_add_cuts_to_queue (CCtsp_lp *lp, CCtsp_lpcut_in **clist)  */
+/*     ADDS clist to the queue of cuts to be processed by the lp solver;   */
+/*      clist will be set to NULL                                          */
+/*      -lp is a pointer to the tsp lp                                     */
+/*      -clist is the head of a NULL terminated linked list of cuts        */
+/*                                                                         */
+/*    int CCtsp_add_cut_to_cutlist (CCtsp_lpcuts *cuts, CCtsp_lpcut *c)    */
+/*                                                                         */
+/*    void CCtsp_delete_cut_from_cutlist (CCtsp_lpcuts *cuts, int ind)     */
+/*                                                                         */
+/*    int CCtsp_process_cuts (CCtsp_lp *lp, int *pnadded, int tighten)     */
+/*      -lp is a pointer to the tsp lp                                     */
+/*      -pnadded returns the location for the number of cuts added         */
+/*      -tighten is a flag to indicate whether or not the tighten routine  */
+/*       should be called for each cut before it is added to the LP        */
+/*     NOTE: process_cuts runs through all the cuts in the queue;          */
+/*      process_cuts also calls add_to_cutpool(). If process_cuts          */
+/*      returns 2, then the LP is infeasible, even after considering the   */
+/*      full edge set.                                                     */
+/*                                                                         */
+/*    int CCtsp_addbad_variables (CCtsp_lp *lp, struct edgegenerator *eg,  */
+/*            double *ppenalty, int *pnadded, double rcthresh,             */
+/*            double maxpenalty, int phase1, int *feasible)                */
+/*     ADDS negative reduced cost edges to the LP; if phase1 is nonzero    */
+/*      then the added edges attempt to make a feasible LP (in this        */
+/*      case the eg variable is ignored and the edges are taked either     */
+/*      from fulladj (if they are valid) or from dat)                      */
+/*      -lp is a pointer to the tsp lp                                     */
+/*      -eg is a generator for the edges to check                          */
+/*      -ppenalty is the penalty from the last pass of pricing             */
+/*      -pnadded is the number of negative reduced cost edges added        */
+/*      -rcthresh is the threshold on the reduced cost of edges to be      */
+/*       added (it should be something <= 0.0)                             */
+/*      -maxpenalty is the maximum sum of penalties that is permitted      */
+/*       before the rounds of pricing stop                                 */
+/*      -phase1 should be 0 for normal column generation, and nonzero      */
+/*       to try to fix an infeasible LP                                    */
+/*      -feasible can be NULL, otherwise it is set to 1 if phase 1         */
+/*       gets to a feasible LP and 0 if the LP really is infeasible        */
+/*                                                                         */
+/*    int CCtsp_eliminate_variables (CCtsp_lp *lp)                         */
+/*     SETS edges to 0 or 1 if possible, based on reduced costs            */
+/*      -lp is a pointer to the tsp lp                                     */
+/*                                                                         */
+/*    double CCtsp_cutprice (CCtsp_lpgraph *g, CCtsp_lpcut_in *c,          */
+/*            double *x)                                                   */
+/*     RETURNS the slack of cut c                                          */
+/*      -g is a pointer to an CCtsp_lpgraph that matches the vector x      */
+/*                                                                         */
+/*    int CCtsp_add_vars_to_lp (CCtsp_lp *lp, CCtsp_predge *prlist, int n) */
+/*     ADDS the columns to the lp.                                         */
+/*      -n the number of edges listed in prlist                            */
+/*                                                                         */
+/*    int CCtsp_update_result (CCtsp_lp *lp)                               */
+/*     UPDATES the solution information in the lp structure                */
+/*                                                                         */
+/*    int CCtsp_infeas_recover (CCtsp_lp *lp)                              */
+/*     TRIES to add columns to lp to regain feasibiblity                   */
+/*     NOTE: Returns 2 if the full lp is infeasible                        */
+/*                                                                         */
+/*    int CCtsp_build_lpgraph (CCtsp_lpgraph *g, int ncount,               */
+/*            int ecount, int *elist, int *elen)                           */
+/*     BUILDS the node and edge lists for the CCtsp_lpgraph pointed by g.  */
+/*      -elen contains the edge lengths (it can be NULL, in which case     */
+/*       the lengths are set to 0).                                        */
+/*                                                                         */
+/*    int CCtsp_build_lpadj (CCtsp_lpgraph *g, int estart, int eend)       */
+/*     BUILDS the incidence list for the graph *g                          */
+/*      -estart is the index of the first edge to include in the list      */
+/*      -eend is the index of the last edge + 1                            */
+/*                                                                         */
+/*    void CCtsp_init_lpgraph_struct (CCtsp_lpgraph *g)              */
+/*     INITIALIZES the CCtsp_lpgraph struct pointed to by g.               */
+/*                                                                         */
+/*    void CCtsp_free_lpgraph (CCtsp_lpgraph *g)                     */
+/*     FREES the fields in the CCtsp_lpgraph pointed to by g.              */
+/*                                                                         */
+/*    void CCtsp_free_lpcut_in (CCtsp_lpcut_in *c)                         */
+/*     FREES the fields in the CCtsp_lpcut pointed to by c.                */
+/*                                                                         */
+/*    CCtsp_free_lpclique (CCtsp_lpclique *c)                              */
+/*     FREES the fields in the CCtsp_lpclique pointed to by c.             */
+/*                                                                         */
+/*    int CCtsp_register_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut_in *c,   */
+/*            CCtsp_lpcut *new)                                            */
+/*     BUILDS the references to the cliques in c into the cut strucure     */
+/*     pointed to by cuts and creates an array of the indices of the       */
+/*     the cliques in CCtsp_lpcut new                                      */
+/*      -cuts is the structure holding the set of cuts                     */
+/*      -c describes the cut to be added to the structure                  */
+/*      -new returns the array of clique indices                           */
+/*                                                                         */
+/*    void CCtsp_unregister_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut *c)   */
+/*     REMOVES the references to the cliques in cut c (and deletes the     */
+/*      cliques if they have no more references) and frees the array       */
+/*      of clique indices in c                                             */
+/*      -cuts is the structure holding the set of cuts                     */
+/*      -c is the cut containing the cliques to be removed                 */
+/*                                                                         */
+/*    int CCtsp_inspect_full_edges (CCtsp_lp *lp)                          */
+/*     CHECKS that full edge set contains the current LP edge set; it      */
+/*      returns 0 if it is okay and 1 if some edge is not present          */
+/*      -lp is the CCtsp_lp                                                */
+/*                                                                         */
+/*    int CCtsp_read_probfile (CCtsp_lp *lp, char *fname, int ncount)      */
+/*     READS a tsp file and loads the results into lp                      */
+/*      -lp is an initialized lp (via a call to init_tsp_lp_struct; the    */
+/*       results are returned in this struct                               */
+/*      -fname is the tsp file                                             */
+/*      -ncount is the number of nodes; it is used as a check to see if    */
+/*       if the tsp file matches                                           */
+/*                                                                         */
+/*    int CCtsp_read_probfile_id (CCtsp_lp *lp, char *fname, int id,       */
+/*            int ncount)                                                  */
+/*     READS a tsp file and loads the results into lp, where the filename  */
+/*      is obtained by using the id.                                       */
+/*                                                                         */
+/*    int CCtsp_dump_x (CCtsp_lp *lp, char *fname)                         */
+/*     WRITES the lp solution to fname.                                    */
+/*     Note: The vector contains the original node names.                  */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+/*
+Known TODO:
+espace
+make sure all seg loops are <=
+change CCtsp_lpadj strategy - graph always complete graph, except for
+   build_lp_cols
+
+Remark:
+  Sparified cut is viewed as cut + CCtsp_sparser*stars (ie, a positive value
+  in the CCtsp_sparser means that the cut in the lp is the original cut + the
+  star for that node
+*/
+
+
+#include "machdefs.h"
+#include "util.h"
+#include "macrorus.h"
+#include "fmatch.h"
+#include "edgegen.h"
+#include "linkern.h"
+#include "tsp.h"
+#include "lp.h"
+#include "bigguy.h"
+#include "cut.h"
+
+/*
+   parameters for addbad_variables.  Addbad generates edges (x,y) with
+   len(x,y) - pi_ub[x] - pi_ub[y] < 0 in chunks of PRICE_GEN, computes
+   rc for that chunk, and adds those with rc(x,y) < CCtsp_PRICE_RCTHRESH to the
+   pool.  This continues until the pool contains more than PRICE_POOL edges,
+   at which point the worst PRICE_ADD edges are added to the lp, new reduced
+   are computed for the pool, and only edges with rc(x,y) <
+    CCtsp_PRICE_RCTHRESH are retained.  This overall process continues until
+   the total penalty for a full pass through the edges without adding any is
+   < CCtsp_PRICE_MAXPENALTY.
+*/
+
+/* Some of these should probably depend on the problem size */
+
+#define REALLOC_FACTOR    1.25
+#define PRICE_GEN         20000
+#define PRICE_GEN_FACTOR  3
+#define PRICE_POOL        1000     /* 10000 */
+#define PRICE_ADD         100
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    first_lp (CCtsp_lp *lp, char *probname, int ncount, int ecount, int *elist,
+        int *elen),
+    find_edge_full (CCtsp_lp *lp, int from, int to),
+    load_lp (CCtsp_lp *lp),
+    build_lp_cols (CCtsp_lpgraph *g, CCtsp_lpcuts *cuts, int estart, int eend,
+        int *pnzcnt, double **pobj, int **pmatbeg, int **pmatcnt,
+        int **pmatind, double **pmatval, double **plb, double **pub),
+    tsp_lpcut_nzlist (CCtsp_lpgraph *g, CCtsp_lpcut *c,
+        CCtsp_lpclique *cliques),
+    checkout_cut (CCtsp_lp *lp, CCtsp_lpcut_in *c, double *x, CCtsp_lprow *cr,
+        int tighten),
+    verify_lpcut_in (CCtsp_lpgraph *g, CCtsp_lpcut_in *d),
+    update_newcuts (CCtsp_lp *lp),
+    phase1_test_edge (int end1, int end2, double *node_piest),
+    phase1_generate_edges (CCtsp_lp *lp, double *node_piest, int nwant,
+        int *ngot, int *genlist, int *genlen, int start, int *ni, int *nj,
+        int *finished),
+    pricing_duals (CCtsp_lp *lp, double *node_pi,
+        double *node_piest, double *cut_pi, double *clique_pi),
+    price_list (CCtsp_lp *lp, int ecount, CCtsp_predge *elist,
+        double *node_pi, double *clique_pi, int phase1),
+    age_cuts (CCtsp_lp *lp, int *ndeleted),
+    age_edges (CCtsp_lp *lp, int *ndeleted),
+    get_pi (CCtsp_lp *lp, double *node_pi, double *cut_pi),
+    addrow_to_list (int nzcnt, double drhs, char sense,
+        int *rmatind, double *rmatval, CCtsp_lprow *cr),
+    lp_addcols (CCtsp_lp *lp, int ncols, int nzcnt,
+        double *obj, int *matbeg, int *matind, double *matval,
+        double *lb, double *ub),
+    lp_delete_cut_set (CCtsp_lp *lp, int *del),
+    lp_delete_var_set (CCtsp_lp *lp, int *del),
+    write_probfile (CCtsp_lp *lp, int saveit),
+    read_probfile (CCtsp_lp *lp, CCtsp_PROB_FILE *p, int ncount);
+
+static void
+    tsp_lpcut_nonzero_work (CCtsp_lpgraph *g, CCtsp_lpclique *c, int *pnzlist),
+    tsp_lpcut_nonzero_modify (CCtsp_lpgraph *g, int modcount,
+        CCtsp_sparser *mods, int *pnzlist),
+    clear_nzlist (CCtsp_lpgraph *g, int nzlist),
+    pr_select (int nsel, int n, CCtsp_predge *list),
+    add_cut_to_queue (CCtsp_lp *lp, CCtsp_lpcut_in *c);
+
+#else  /* CC_PROTOTYPE_ANSI */
+
+static int
+    first_lp (),
+    find_edge_full (),
+    load_lp (),
+    build_lp_cols (),
+    tsp_lpcut_nzlist (),
+    checkout_cut (),
+    verify_lpcut_in (),
+    update_newcuts (),
+    phase1_test_edge (),
+    phase1_generate_edges (),
+    pricing_duals (),
+    price_list (),
+    age_cuts (),
+    age_edges (),
+    get_pi (),
+    addrow_to_list (),
+    lp_addcols (),
+    lp_delete_cut_set (),
+    lp_delete_var_set (),
+    write_probfile (),
+    read_probfile ();
+
+static void
+    tsp_lpcut_nonzero_work (),
+    tsp_lpcut_nonzero_modify (),
+    clear_nzlist (),
+    pr_select (),
+    add_cut_to_queue ();
+
+#endif /* CC_PROTOTYPE_ANSI */
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_bb_init_lp (CCtsp_lp **lp, char *probname, int probnum, int ncount,
+        CCdatagroup *dat, int *ptour, double initial_ub, CCtsp_lpcuts *pool)
+#else
+int CCtsp_bb_init_lp (lp, probname, probnum, ncount, dat, ptour, initial_ub,
+        pool)
+CCtsp_lp **lp;
+char *probname;
+int probnum;
+int ncount;
+CCdatagroup *dat;
+int *ptour;
+double initial_ub;
+CCtsp_lpcuts *pool;
+#endif
+{
+    return CCtsp_init_lp (lp, probname, probnum, (char *) NULL,
+                  ncount, dat,
+                  0, (int *) NULL, (int *) NULL,       /* elist  */
+                  0, (int *) NULL, (int *) NULL, 0,    /* exlist */
+                  ptour, initial_ub, pool);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_init_lp (CCtsp_lp **lp, char *probname, int probnum,
+        char *probfilename, int ncount, CCdatagroup *dat,
+        int ecount, int *elist, int *elen, int excount,
+        int *exlist, int *exlen, int exvalid, int *ptour,
+        double initial_ub, CCtsp_lpcuts *pool)
+#else
+int CCtsp_init_lp (lp, probname, probnum, probfilename, ncount, dat, ecount,
+        elist, elen, excount, exlist, exlen, exvalid, ptour,
+        initial_ub, pool)
+CCtsp_lp **lp;
+char *probname;
+int probnum;
+char *probfilename;
+int ncount;
+CCdatagroup *dat;
+int ecount;
+int *elist, *elen;
+int excount;
+int *exlist, *exlen;
+int exvalid;
+int *ptour;
+double initial_ub;
+CCtsp_lpcuts *pool;
+#endif
+{
+    int rval = 0;
+    double tet;
+
+    if (!ptour) {
+        fprintf (stderr, "must have a permutation tour in CCtsp_init_lp\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    *lp = CC_SAFE_MALLOC (1, CCtsp_lp);
+    if ( !(*lp) ) {
+       rval = 1; goto CLEANUP;
+    }
+
+    CCtsp_init_tsp_lp_struct (*lp);
+    (*lp)->perm = ptour;
+    (*lp)->dat = dat;
+    (*lp)->pool = pool;
+
+    if (probfilename) {
+        rval = CCtsp_read_probfile (*lp, probfilename, ncount);
+        CCtsp_free_bigdual (&((*lp)->exact_dual));
+    } else if (probnum != -1) {
+        rval = CCtsp_read_probfile_id (*lp, probname, probnum, ncount);
+        CCtsp_free_bigdual (&((*lp)->exact_dual));
+    } else {
+        rval = first_lp (*lp, probname, ncount, ecount, elist, elen);
+    }
+    if (rval) {
+        fprintf (stderr, "CCtsp_read_probfile or first_lp failed\n");
+        CCtsp_free_tsp_lp_struct (lp);
+        rval = 1; goto CLEANUP;
+    }
+
+    if ((*lp)->fullcount == 0) {
+        if (excount) {
+            rval = CCtsp_edgelist_to_genadj (ncount, excount, exlist, exlen,
+                           &((*lp)->fulladj), &((*lp)->fulladjspace));
+            if (rval) {
+                fprintf (stderr, "CCtsp_edgelist_to_genadj failed\n");
+                CCtsp_free_tsp_lp_struct (lp);
+                rval = 1; goto CLEANUP;
+            }
+            (*lp)->fullcount = excount;
+            if (exvalid)
+                (*lp)->full_edges_valid = 1;
+        }
+    }
+
+    if (initial_ub < (*lp)->upperbound) {
+        printf ("Setting upperbound to the initial bound: %.2f\n", initial_ub);
+        fflush (stdout);
+        (*lp)->upperbound = initial_ub;
+    }
+
+    rval = CClp_init (&((*lp)->lp));
+    if (rval) {
+        fprintf (stderr, "CClp_init failed\n");
+        CCtsp_free_tsp_lp_struct (lp);
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = load_lp (*lp);
+    if (rval) {
+        fprintf (stderr, "load_lp failed\n");
+        CCtsp_free_tsp_lp_struct (lp);
+        rval = 1; goto CLEANUP;
+    }
+
+    if ((*lp)->basis) {
+        CClp_free_basis ((*lp)->basis);
+        CC_FREE ((*lp)->basis, CClpbasis);
+    }
+
+    (*lp)->edge_life = CCtsp_EDGE_LIFE;
+    (*lp)->cut_life  = CCtsp_CUT_LIFE;
+
+    rval = CCtsp_add_branchhistory_to_lp (*lp);
+    if (rval) {
+        fprintf (stderr, "CCtsp_add_branchhistory_to_lp failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    tet = CCutil_zeit ();
+    rval = CClp_opt (&((*lp)->lp), CClp_METHOD_DUAL);
+    printf ("Dual opt returned after %.2f seconds\n", CCutil_zeit () - tet);
+    fflush (stdout);
+    if (rval == 2) {
+        fprintf (stderr, "Initial lp infeasible\n");
+        goto CLEANUP;
+    } else if (rval) {
+        fprintf (stderr, "CClp_opt failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_update_result (*lp);
+    if (rval) {
+        fprintf (stderr, "CCtsp_update_result failed\n");
+        rval = 1; goto CLEANUP;
+    }
+
+CLEANUP:
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int first_lp (CCtsp_lp *lp, char *probname, int ncount,
+        int ecount, int *elist, int *elen)
+#else
+static int first_lp (lp, probname, ncount, ecount, elist, elen)
+CCtsp_lp *lp;
+char *probname;
+int ncount;
+int ecount;
+int *elist, *elen;
+#endif
+{
+    double v, szeit;
+    int *basis = (int *) NULL;
+    int *match = (int *) NULL;
+    int rval = 0;
+    int i;
+    int e;
+    CClpbasis *b = (CClpbasis *) NULL;
+
+
+    szeit = CCutil_zeit ();
+
+    rval = CCtsp_init_cliquehash (&lp->cuts, 2*ncount);
+    if (rval) goto CLEANUP;
+    rval = CCtsp_build_lpgraph (&lp->graph, ncount, ecount, elist, elen);
+    if (rval) goto CLEANUP;
+    rval = CCtsp_build_lpadj (&lp->graph, 0, ecount);
+    if (rval) goto CLEANUP;
+
+    lp->name = CC_SAFE_MALLOC (strlen (probname)+1, char);
+    if (!lp->name) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    strcpy (lp->name, probname);
+
+    lp->id = 0;
+    lp->parent_id = -1;
+    lp->full_edges_valid = 0;
+
+    basis = CC_SAFE_MALLOC (2 * ncount, int);
+    if (!basis) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    match = CC_SAFE_MALLOC ((6 * ncount) + 1, int);
+    if (!match) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    rval = CCfmatch_fractional_2match (ncount, ecount, elist, elen,
+                   (CCdatagroup *) NULL, &v, match, (int *) NULL, basis, 1);
+    if (rval) {
+        fprintf (stderr, "Fractional matching routine failed\n");
+        CC_FREE (basis, int);
+        CC_FREE (match, int);
+        return 0;
+    }
+
+    b = CC_SAFE_MALLOC (1, CClpbasis);
+    if (!b) {
+        fprintf (stderr, "out of memory in first_lp\n");
+        rval = 1; goto CLEANUP;
+    }
+    CClp_init_basis (b);
+
+    b->cstat = CC_SAFE_MALLOC (ecount, int);
+    b->rstat = CC_SAFE_MALLOC (ncount, int);
+    if (!b->cstat || !b->rstat) {
+        fprintf (stderr, "out of memory in first_lp\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i=0; i<ecount; i++) b->cstat[i] = 0;
+    for (i=0; i<ncount; i++) b->rstat[i] = 0;
+
+    for (i = 0; i < ncount; i++) {
+        e = CCtsp_find_edge (&lp->graph, basis[2*i], basis[2*i+1]);
+        if (e < 0) {
+            fprintf (stderr, "Basis contains edge %d,%d not in edgelist\n",
+                     basis[2*i],basis[2*i+1]);
+        } else {
+            b->cstat[e] = 1;
+        }
+    }
+
+    for (i=0; i <= 6*ncount && match[i] > -1; i += 3) {
+        e = CCtsp_find_edge (&lp->graph, match[i], match[i+1]);
+        if (e < 0) {
+            fprintf (stderr, "Matching contains edge %d,%d not in edgelist\n",
+                     match[i], match[i+1]);
+        } else {
+            if (b->cstat[e] == 0) {
+                if (match[i+2] == 1) {
+                    fprintf (stderr, "Edge at 0.5 not in basis\n");
+                }
+                b->cstat[e] = 2;
+            }
+        }
+    }
+
+    CC_FREE (basis, int);
+    CC_FREE (match, int);
+    lp->basis = b;
+
+    printf ("Total Time for first_lp: %.2f (seconds)\n",
+            CCutil_zeit () - szeit);
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (basis, int);
+    CC_IFFREE (match, int);
+    if (b) {
+        CClp_free_basis (b);
+        CC_FREE (b, CClpbasis);
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_build_lpgraph (CCtsp_lpgraph *g, int ncount, int ecount,
+        int *elist, int *elen)
+#else
+int CCtsp_build_lpgraph (g, ncount, ecount, elist, elen)
+CCtsp_lpgraph *g;
+int ncount;
+int ecount;
+int *elist;
+int *elen;
+#endif
+{
+    int i;
+    CCtsp_lpnode *n;
+    CCtsp_lpedge *e;
+
+    g->ncount = ncount;
+    g->ecount = ecount;
+    g->nodes = CC_SAFE_MALLOC (ncount, CCtsp_lpnode);
+    if (!g->nodes) {
+        return 1;
+    }
+    g->edges = CC_SAFE_MALLOC (ecount, CCtsp_lpedge);
+    if (!g->edges) {
+        CC_FREE (g->nodes, CCtsp_lpnode);
+        return 1;
+    }
+    g->espace = ecount;
+    n = g->nodes;
+    e = g->edges;
+
+    for (i = 0; i < ncount; i++) {
+        n[i].mark = 0;
+    }
+    for (i=0; i<ecount; i++) {
+        if (elist[2*i] < elist[2*i+1]) {
+            e[i].ends[0] = elist[2*i];
+            e[i].ends[1] = elist[2*i+1];
+        } else {
+            e[i].ends[0] = elist[2*i+1];
+            e[i].ends[1] = elist[2*i];
+        }
+        e[i].fixed = 0;
+        e[i].branch = 0;
+        e[i].age = 0;
+        if (elen) {
+            e[i].len = elen[i];
+        } else {
+            e[i].len = 0;
+        }
+        e[i].coefnext = -2;
+        e[i].coef = 0;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_build_lpadj (CCtsp_lpgraph *g, int estart, int eend)
+#else
+int CCtsp_build_lpadj (g, estart, eend)
+CCtsp_lpgraph *g;
+int estart;
+int eend;
+#endif
+{
+    CCtsp_lpadj *a;
+    CCtsp_lpnode *n = g->nodes;
+    CCtsp_lpedge *e = g->edges;
+    int i, j;
+
+    if (g->adjspace) {
+        if (g->adjstart == estart && g->adjend == eend) {
+            return 0;
+        } else {
+            CC_FREE (g->adjspace, CCtsp_lpadj);
+        }
+    }
+
+    if (estart >= eend) {
+        g->adjstart = estart;
+        g->adjend = eend;
+        for (i=0; i<g->ncount; i++) {
+            n[i].deg = 0;
+            n[i].adj = (CCtsp_lpadj *) NULL;
+        }
+        return 0;
+    }
+
+    g->adjspace = CC_SAFE_MALLOC ((eend - estart)*2, CCtsp_lpadj);
+    if (!g->adjspace) {
+        return 1;
+    }
+    a = g->adjspace;
+    for (i=0; i<g->ncount; i++) {
+        n[i].deg = 0;
+    }
+    for (i=estart; i<eend; i++) {
+        n[e[i].ends[0]].deg++;
+        n[e[i].ends[1]].deg++;
+    }
+    for (i=0; i<g->ncount; i++) {
+        n[i].adj = a;
+        a += n[i].deg;
+        n[i].deg = 0;
+    }
+    for (i=estart; i<eend; i++) {
+        j = e[i].ends[0];
+        a = &n[j].adj[n[j].deg];
+        a->to = e[i].ends[1];
+        a->edge = i;
+        n[j].deg++;
+        j = e[i].ends[1];
+        a = &n[j].adj[n[j].deg];
+        a->to = e[i].ends[0];
+        a->edge = i;
+        n[j].deg++;
+    }
+    g->adjstart = estart;
+    g->adjend = eend;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_find_edge (CCtsp_lpgraph *g, int from, int to)
+#else
+int CCtsp_find_edge (g, from, to)
+CCtsp_lpgraph *g;
+int from;
+int to;
+#endif
+{
+    int t;
+    int i;
+    CCtsp_lpnode *f;
+
+    if (from > to) {
+        CC_SWAP (from, to, t);
+    }
+
+    f = &g->nodes[from];
+    for (i=0; i<f->deg; i++) {
+        if (f->adj[i].to == to) {
+            return f->adj[i].edge;
+        }
+    }
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_edge_full (CCtsp_lp *lp, int from, int to)
+#else
+static int find_edge_full (lp, from, to)
+CCtsp_lp *lp;
+int from;
+int to;
+#endif
+{
+    int i;
+    CCtsp_genadjobj *a;
+
+    /* returns 1 if it is there */
+
+    if (!lp->fulladj)
+        return 0;
+
+    if (from > to) {
+        CC_SWAP (from, to, i);
+    }
+
+    a = lp->fulladj[from].list;
+    for (i = lp->fulladj[from].deg-1; i >= 0; i--) {
+        if (a[i].end == to) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_inspect_full_edges (CCtsp_lp *lp)
+#else
+int CCtsp_inspect_full_edges (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int i;
+    int ecount = lp->graph.ecount;
+    CCtsp_lpedge *edges = lp->graph.edges;
+
+    for (i = 0; i < ecount; i++) {
+        if (find_edge_full (lp, edges[i].ends[0], edges[i].ends[1]) == 0) {
+            printf ("edge (%d,%d) not in full list\n",
+                                 edges[i].ends[0], edges[i].ends[1]);
+            fflush (stdout);
+            return 1;
+        }
+    }
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_init_tsp_lp_struct (CCtsp_lp *lp)
+#else
+void CCtsp_init_tsp_lp_struct (lp)
+CCtsp_lp *lp;
+#endif
+{
+    CCtsp_init_lpgraph_struct (&(lp->graph));
+
+    lp->sparsifier = (CCtsp_qsparsegroup *) NULL;
+    lp->perm = (int *) NULL;
+    lp->dat = (CCdatagroup *) NULL;
+    CClp_init_struct (&lp->lp);
+
+    lp->cuts.cutcount = 0;
+    lp->cuts.cuts = (CCtsp_lpcut *) NULL;
+    lp->cuts.cutspace = 0;
+    lp->cuts.cliqueend = 0;
+    lp->cuts.cliques = (CCtsp_lpclique *) NULL;
+    lp->cuts.cliquespace = 0;
+    lp->cuts.cliquehash = (int *) NULL;
+    lp->cuts.cliquehashsize = 0;
+    lp->cuts.cuthash = (CCgenhash *) NULL;
+
+    lp->pool = (CCtsp_lpcuts *) NULL;
+
+    lp->fullcount = 0;
+    lp->fulladj = (CCtsp_genadj *) NULL;
+    lp->fulladjspace = (CCtsp_genadjobj *) NULL;
+    lp->fixededges = (int *) NULL;
+    lp->nfixededges = 0;
+    lp->name = (char *) NULL;
+    lp->id = -1;
+    lp->parent_id = -1;
+    lp->root = 0;
+    lp->upperbound =  CCtsp_LP_MAXDOUBLE;
+    lp->lowerbound = -CCtsp_LP_MAXDOUBLE;
+    lp->exact_lowerbound = CCbigguy_MINBIGGUY;
+    lp->exact_dual = (CCtsp_bigdual *) NULL;
+    lp->infeasible = 0;
+    lp->full_edges_valid = 0;
+    lp->basis = (CClpbasis *) NULL;
+
+    lp->cutqueue.cliquecount = 0;
+    lp->cutqueue.handlecount = 0;
+    lp->cutqueue.cliques = (CCtsp_lpclique *) NULL;
+    lp->cutqueue.next = &lp->cutqueue;
+    lp->cutqueue.prev = &lp->cutqueue;
+
+    lp->result.ub = 0.0;
+    lp->result.lb = 0.0;
+    lp->result.ecount = 0;
+    lp->result.elist = (int *) NULL;
+    lp->result.x = (double *) NULL;
+    lp->result.rc = (double *) NULL;
+
+    lp->branchhistory = (CCtsp_branchobj *) NULL;
+    lp->branchdepth   = 0;
+
+    CCtsp_init_tighten_info (&lp->tighten_stats);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_tsp_lp_struct (CCtsp_lp **lp)
+#else
+void CCtsp_free_tsp_lp_struct (lp)
+CCtsp_lp **lp;
+#endif
+{
+    int i;
+
+    if (!(*lp))  return;
+
+    CCtsp_free_lpgraph (&((*lp)->graph));
+
+    (*lp)->perm = (int *) NULL;      /* perm is owned by calling program */
+    if ((*lp)->sparsifier) {
+        CCtsp_free_qsparsify (&((*lp)->sparsifier));
+    }
+    (*lp)->dat = (CCdatagroup *) NULL; /* dat is owned by the calling program */
+    if ((*lp)->dat) {
+        CCutil_freedatagroup ((*lp)->graph.ncount, (*lp)->dat);
+        CC_FREE ((*lp)->dat, CCdatagroup);
+    }
+    if ((*lp)->fulladjspace) {
+        CC_FREE ((*lp)->fulladjspace, CCtsp_genadjobj);
+        CC_IFFREE ((*lp)->fulladj, CCtsp_genadj);
+    }
+    (*lp)->fullcount = 0;
+    CC_IFFREE ((*lp)->fixededges, int);
+    (*lp)->nfixededges = 0;
+
+    if ((*lp)->lp.lp_allocated) {
+        CClp_free (&((*lp)->lp));
+    }
+
+    if ((*lp)->cuts.cuts) {
+        for (i=0; i<(*lp)->cuts.cutcount; i++) {
+            CC_FREE ((*lp)->cuts.cuts[i].cliques, int);
+            CC_IFFREE ((*lp)->cuts.cuts[i].mods, CCtsp_sparser);
+        }
+        CC_FREE ((*lp)->cuts.cuts, CCtsp_lpcut);
+    }
+    if ((*lp)->cuts.cliques) {
+        for (i=0; i<(*lp)->cuts.cliqueend; i++) {
+            CC_IFFREE ((*lp)->cuts.cliques[i].nodes, CCtsp_segment);
+        }
+        CC_FREE ((*lp)->cuts.cliques, CCtsp_lpclique);
+    }
+
+    (*lp)->pool = (CCtsp_lpcuts *) NULL;  /* owned by calling routine */
+
+    if ((*lp)->exact_dual) {
+        CC_IFFREE ((*lp)->exact_dual->node_pi, CCbigguy);
+        CC_IFFREE ((*lp)->exact_dual->cut_pi, CCbigguy);
+        CC_FREE ((*lp)->exact_dual, CCtsp_bigdual);
+    }
+    CC_IFFREE ((*lp)->cuts.cliquehash, int);
+    CC_IFFREE ((*lp)->name, char);
+    if ((*lp)->basis) {
+        CClp_free_basis ((*lp)->basis);
+        CC_FREE ((*lp)->basis, CClpbasis);
+    }
+    CC_IFFREE ((*lp)->result.elist, int);
+    CC_IFFREE ((*lp)->result.x, double);
+    CC_IFFREE ((*lp)->result.rc, double);
+
+    if ((*lp)->branchhistory) {
+        for (i = 0; i < (*lp)->branchdepth; i++) {
+            CCtsp_free_branchobj (&((*lp)->branchhistory[i]));
+        }
+        CC_FREE ((*lp)->branchhistory, CCtsp_branchobj);
+        (*lp)->branchdepth = 0;
+    }
+
+    CC_IFFREE (*lp, CCtsp_lp);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_init_lpgraph_struct (CCtsp_lpgraph *g)
+#else
+void CCtsp_init_lpgraph_struct (g)
+CCtsp_lpgraph *g;
+#endif
+{
+    g->ncount = 0;
+    g->ecount = 0;
+    g->nodes = (CCtsp_lpnode *) NULL;
+    g->edges = (CCtsp_lpedge *) NULL;
+    g->adjspace = (CCtsp_lpadj *) NULL;
+    g->adjstart = 0;
+    g->adjend = 0;
+    g->nodemarker = 0;
+    g->espace = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_lpgraph (CCtsp_lpgraph *g)
+#else
+void CCtsp_free_lpgraph (g)
+CCtsp_lpgraph *g;
+#endif
+{
+    CC_IFFREE (g->nodes, CCtsp_lpnode);
+    CC_IFFREE (g->edges, CCtsp_lpedge);
+    CC_IFFREE (g->adjspace, CCtsp_lpadj);
+    g->espace = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int load_lp (CCtsp_lp *lp)
+#else
+static int load_lp (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int rval = 0;
+    int nzcnt;
+    int i, j;
+    int xrhs;
+    double sz = CCutil_zeit ();
+
+    double *obj    = (double *) NULL;
+    double *rhs    = (double *) NULL;
+    char   *sense  = (char *)   NULL;
+    int    *matbeg = (int *)    NULL;
+    int    *matcnt = (int *)    NULL;
+    int    *matind = (int *)    NULL;
+    double *matval = (double *) NULL;
+    double *lb     = (double *) NULL;
+    double *ub     = (double *) NULL;
+
+    printf ("Loading lp..."); fflush (stdout);
+
+    rhs      = CC_SAFE_MALLOC (lp->graph.ncount + lp->cuts.cutcount, double);
+    sense    = CC_SAFE_MALLOC (lp->graph.ncount + lp->cuts.cutcount, char);
+    if (!rhs || !sense ) {
+       fprintf (stderr, "not enough memory to load problem\n");
+       rval = 1;
+       goto CLEANUP;
+    }
+
+    rval = build_lp_cols (&lp->graph, &lp->cuts, 0, lp->graph.ecount,
+                          &nzcnt, &obj, &matbeg, &matcnt, &matind, &matval,
+                          &lb, &ub);
+    if (rval)  goto CLEANUP;
+
+    for (i = 0; i < lp->graph.ncount; i++) {
+        rhs[i] = 2.0;
+        sense[i] = 'E';
+    }
+    for (i = 0; i < lp->cuts.cutcount; i++) {
+        xrhs = lp->cuts.cuts[i].rhs;
+        for (j = 0; j < lp->cuts.cuts[i].modcount; j++) {
+            xrhs += 2*(((int) lp->cuts.cuts[i].mods[j].mult)-128);
+        }
+        rhs[lp->graph.ncount + i] = xrhs;
+        sense[lp->graph.ncount + i] = lp->cuts.cuts[i].sense;
+    }
+
+    rval = CClp_loadlp (&lp->lp, lp->name, lp->graph.ecount,
+                        lp->graph.ncount + lp->cuts.cutcount, 1,
+                        obj, rhs, sense, matbeg, matcnt, matind, matval,
+                        lb, ub);
+
+    if (rval) {
+        fprintf (stderr, "couldn't load problem\n");
+        goto CLEANUP;
+    }
+
+    if (lp->basis) {
+        rval = CClp_load_basis_and_norms (&lp->lp, lp->basis);
+        if (rval) {
+            fprintf (stderr, "Couln't load basis and norms\n");
+        }
+    } else {
+        fprintf (stderr, "No basis to load, stumbling on anyway\n");
+    }
+
+    printf ("done in %.2f seconds\n", CCutil_zeit () - sz); fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (obj, double);
+    CC_IFFREE (rhs, double);
+    CC_IFFREE (sense, char);
+    CC_IFFREE (matbeg, int);
+    CC_IFFREE (matcnt, int);
+    CC_IFFREE (matind, int);
+    CC_IFFREE (matval, double);
+    CC_IFFREE (lb, double);
+    CC_IFFREE (ub, double);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int build_lp_cols (CCtsp_lpgraph *g, CCtsp_lpcuts *cuts, int estart, int eend,
+                          int *pnzcnt, double **pobj, int **pmatbeg,
+                          int **pmatcnt, int **pmatind, double **pmatval,
+                          double **plb, double **pub)
+#else
+static int build_lp_cols (g, cuts, estart, eend, pnzcnt, pobj, pmatbeg,
+                          pmatcnt, pmatind, pmatval, plb, pub)
+CCtsp_lpgraph *g;
+CCtsp_lpcuts *cuts;
+int estart;
+int eend;
+int *pnzcnt;
+double **pobj;
+int **pmatbeg;
+int **pmatcnt;
+int **pmatind;
+double **pmatval;
+double **plb;
+double **pub;
+#endif
+{
+    int rval;
+    int nzcnt;
+    int ncols = eend - estart;
+    double *obj = (double *) NULL;
+    int *matbeg = (int *) NULL;
+    int *matcnt = (int *) NULL;
+    int *matind = (int *) NULL;
+    double *matval = (double *) NULL;
+    double *lb = (double *) NULL;
+    double *ub = (double *) NULL;
+    int i;
+    int nzlist, nznext;
+
+    if (estart >= eend) {
+        fprintf (stderr, "No columns for build_lp_cols to build\n");
+        return 1;
+    }
+
+    rval = CCtsp_build_lpadj (g, estart, eend);
+    if (rval) goto CLEANUP;
+
+    obj = CC_SAFE_MALLOC (ncols, double);
+    lb = CC_SAFE_MALLOC (ncols, double);
+    ub = CC_SAFE_MALLOC (ncols, double);
+    matbeg = CC_SAFE_MALLOC (ncols, int);
+    matcnt = CC_SAFE_MALLOC (ncols, int);
+    if (!obj || !lb || !ub || !matbeg || !matcnt) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ncols; i++) {
+        obj[i] = g->edges[i+estart].len;
+        if (g->edges[i+estart].fixed || g->edges[i+estart].branch > 0) {
+            lb[i] = 1.0;
+        } else {
+            lb[i] = 0.0;
+        }
+        if (g->edges[i+estart].branch < 0) {
+            ub[i] = 0.0;
+        } else {
+            ub[i] = 1.0;
+        }
+        matcnt[i] = 2;
+    }
+
+    for (i=0; i<cuts->cutcount; i++) {
+        nzlist = tsp_lpcut_nzlist (g, &cuts->cuts[i], cuts->cliques);
+        while (nzlist != -1) {
+            nznext = g->edges[nzlist].coefnext;
+            g->edges[nzlist].coefnext = -2;
+            if (g->edges[nzlist].coef) {
+                g->edges[nzlist].coef = 0;
+                matcnt[nzlist - estart]++;
+            }
+            nzlist = nznext;
+        }
+    }
+
+    nzcnt = 0;
+    for (i=0; i<ncols; i++) {
+        matbeg[i] = nzcnt;
+        nzcnt += matcnt[i];
+        matcnt[i] = 0;
+    }
+    matind = CC_SAFE_MALLOC (nzcnt, int);
+    matval = CC_SAFE_MALLOC (nzcnt, double);
+    if (!matind || !matval) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i=0; i<ncols; i++) {
+        matval[matbeg[i] + matcnt[i]] = 1.0;
+        matind[matbeg[i] + matcnt[i]] = g->edges[estart+i].ends[0];
+        matcnt[i]++;
+        matval[matbeg[i] + matcnt[i]] = 1.0;
+        matind[matbeg[i] + matcnt[i]] = g->edges[estart+i].ends[1];
+        matcnt[i]++;
+    }
+
+    for (i=0; i<cuts->cutcount; i++) {
+        nzlist = tsp_lpcut_nzlist (g, &cuts->cuts[i], cuts->cliques);
+        while (nzlist != -1) {
+            nznext = g->edges[nzlist].coefnext;
+            g->edges[nzlist].coefnext = -2;
+            if (g->edges[nzlist].coef) {
+                matval[matbeg[nzlist-estart] + matcnt[nzlist-estart]] =
+                                                      g->edges[nzlist].coef;
+                matind[matbeg[nzlist-estart] + matcnt[nzlist-estart]] =
+                                                      g->ncount + i;
+                matcnt[nzlist-estart]++;
+                g->edges[nzlist].coef = 0;
+            }
+            nzlist = nznext;
+        }
+    }
+
+    if (pnzcnt) *pnzcnt = nzcnt;
+    if (pobj) *pobj = obj;
+    else CC_FREE (obj, double);
+    if (pmatbeg) *pmatbeg = matbeg;
+    else CC_FREE (matbeg, int);
+    if (pmatcnt) *pmatcnt = matcnt;
+    else CC_FREE (matcnt, int);
+    if (pmatind) *pmatind = matind;
+    else CC_FREE (matind, int);
+    if (pmatval) *pmatval = matval;
+    else CC_FREE (matval, double);
+    if (plb) *plb = lb;
+    else CC_FREE (lb, double);
+    if (pub) *pub = ub;
+    else CC_FREE (ub, double);
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (obj, double);
+    CC_IFFREE (matbeg, int);
+    CC_IFFREE (matcnt, int);
+    CC_IFFREE (matind, int);
+    CC_IFFREE (matval, double);
+    CC_IFFREE (lb, double);
+    CC_IFFREE (ub, double);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_update_result (CCtsp_lp *lp)
+#else
+int CCtsp_update_result (lp)
+CCtsp_lp *lp;
+#endif
+{
+    CCtsp_lp_result new;
+    int i;
+
+    if (CClp_objval (&lp->lp, &new.lb)) {
+        return 1;
+    }
+    new.ub = lp->upperbound;
+    new.elist = CC_SAFE_MALLOC (lp->graph.ecount*2, int);
+    if (!new.elist) return 1;
+    new.x = CC_SAFE_MALLOC (lp->graph.ecount, double);
+    if (!new.x) {
+        CC_FREE (new.elist, int);
+        return 1;
+    }
+    new.rc = CC_SAFE_MALLOC (lp->graph.ecount, double);
+    if (!new.rc) {
+        CC_FREE (new.x, double);
+        CC_FREE (new.elist, int);
+        return 1;
+    }
+
+    if (CClp_x (&lp->lp, new.x)) {
+        CC_FREE (new.rc, double);
+        CC_FREE (new.x, double);
+        CC_FREE (new.elist, int);
+        return 1;
+    }
+
+    if (CClp_rc (&lp->lp, new.rc)) {
+        CC_FREE (new.rc, double);
+        CC_FREE (new.x, double);
+        CC_FREE (new.elist, int);
+        return 1;
+    }
+
+    new.ecount = lp->graph.ecount;
+    for (i=0; i<new.ecount; i++) {
+        new.elist[2*i] = lp->graph.edges[i].ends[0];
+        new.elist[2*i+1] = lp->graph.edges[i].ends[1];
+    }
+
+    CC_IFFREE (lp->result.elist, int);
+    CC_IFFREE (lp->result.x, double);
+    CC_IFFREE (lp->result.rc, double);
+
+    lp->result = new;
+
+    printf ("Optimized, val = %.6f\n", lp->result.lb);
+    fflush (stdout);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_get_lp_result (CCtsp_lp *lp, double *lb, double *ub, int *ecount,
+        int **elist, double **x, double **rc, double **node_pi,
+        double **cut_pi)
+#else
+int CCtsp_get_lp_result (lp, lb, ub, ecount, elist, x, rc, node_pi, cut_pi)
+CCtsp_lp *lp;
+double *lb;
+double *ub;
+int *ecount;
+int **elist;
+double **x;
+double **rc;
+double **node_pi;
+double **cut_pi;
+#endif
+{
+    int *myelist = (int *) NULL;
+    double *myx = (double *) NULL;
+    double *myrc = (double *) NULL;
+    double *mynode_pi = (double *) NULL;
+    double *mycut_pi = (double *) NULL;
+    int i;
+    int rval = 0;
+
+    if ((elist || x || rc) && lp->result.ecount == 0){
+       fprintf (stderr, "lp->result is not initialized\n");
+       return 1;
+    }
+
+    if (elist) {
+        myelist = CC_SAFE_MALLOC (2*lp->result.ecount, int);
+        if (!myelist) {
+            fprintf (stderr, "out of memory in CCtsp_get_lp_result\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (x) {
+        myx = CC_SAFE_MALLOC (lp->result.ecount, double);
+        if (!myx) {
+            fprintf (stderr, "out of memory in CCtsp_get_lp_result\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (rc) {
+        myrc = CC_SAFE_MALLOC (lp->result.ecount, double);
+        if (!myrc) {
+            fprintf (stderr, "out of memory in CCtsp_get_lp_result\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (node_pi) {
+        mynode_pi = CC_SAFE_MALLOC (lp->graph.ncount, double);
+        if (!mynode_pi) {
+            fprintf (stderr, "out of memory in CCtsp_get_lp_result\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+    if (cut_pi && lp->cuts.cutcount) {
+        mycut_pi = CC_SAFE_MALLOC (lp->cuts.cutcount, double);
+        if (!mycut_pi) {
+            fprintf (stderr, "out of memory in CCtsp_get_lp_result\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    if (elist) {
+        for (i=0; i<2*lp->result.ecount; i++) {
+            myelist[i] = lp->result.elist[i];
+        }
+        *elist = myelist;
+    }
+    if (x) {
+        for (i=0; i<lp->result.ecount; i++) {
+            myx[i] = lp->result.x[i];
+        }
+        *x = myx;
+    }
+    if (rc) {
+        for (i=0; i<lp->result.ecount; i++) {
+            myrc[i] = lp->result.rc[i];
+        }
+        *rc = myrc;
+    }
+    if (node_pi || cut_pi) {
+        rval = get_pi (lp, mynode_pi, mycut_pi);
+        if (rval) {
+            fprintf (stderr, "get_pi failed\n");
+            goto CLEANUP;
+        }
+        *node_pi = mynode_pi;
+        *cut_pi = mycut_pi;
+    }
+    if (lb) *lb = lp->result.lb;
+    if (ub) *ub = lp->result.ub;
+    if (ecount) *ecount = lp->result.ecount;
+
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (myelist, int);
+    CC_IFFREE (myx, double);
+    CC_IFFREE (myrc, double);
+    CC_IFFREE (mynode_pi, double);
+    CC_IFFREE (mycut_pi, double);
+
+    return rval;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_add_cuts_to_queue (CCtsp_lp *lp, CCtsp_lpcut_in **clist)
+#else
+void CCtsp_add_cuts_to_queue (lp, clist)
+CCtsp_lp *lp;
+CCtsp_lpcut_in **clist;
+#endif
+{
+    CCtsp_lpcut_in *c, *cnext;
+
+    for (c = *clist; c; c = cnext) {
+        cnext = c->next;
+        add_cut_to_queue (lp, c);
+    }
+    *clist = (CCtsp_lpcut_in *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void add_cut_to_queue (CCtsp_lp *lp, CCtsp_lpcut_in *c)
+#else
+static void add_cut_to_queue (lp, c)
+CCtsp_lp *lp;
+CCtsp_lpcut_in *c;
+#endif
+{
+    assert (c->sense == 'G' || c->branch != 0);
+    c->next = &lp->cutqueue;
+    c->prev = lp->cutqueue.prev;
+    c->next->prev = c;
+    c->prev->next = c;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+double CCtsp_cutprice (CCtsp_lpgraph *g, CCtsp_lpcut_in *c, double *x)
+#else
+double CCtsp_cutprice (g, c, x)
+CCtsp_lpgraph *g;
+CCtsp_lpcut_in *c;
+double *x;
+#endif
+{
+    double slack;
+    int nzlist, nznext;
+
+    slack =  (double) -(c->rhs);
+
+    nzlist = CCtsp_lpcut_in_nzlist (g, c);
+
+    while (nzlist != -1) {
+        nznext = g->edges[nzlist].coefnext;
+        g->edges[nzlist].coefnext = -2;
+        slack += g->edges[nzlist].coef * x[nzlist];
+        g->edges[nzlist].coef = 0;
+        nzlist = nznext;
+    }
+    return slack;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_lpcut_in_nzlist (CCtsp_lpgraph *g, CCtsp_lpcut_in *c)
+#else
+int CCtsp_lpcut_in_nzlist (g, c)
+CCtsp_lpgraph *g;
+CCtsp_lpcut_in *c;
+#endif
+{
+    int nzlist = -1;
+    int i;
+
+    for (i = 0; i < c->cliquecount; i++) {
+        tsp_lpcut_nonzero_work (g, &c->cliques[i], &nzlist);
+    }
+    return nzlist;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int tsp_lpcut_nzlist (CCtsp_lpgraph *g, CCtsp_lpcut *c,
+        CCtsp_lpclique *cliques)
+#else
+static int tsp_lpcut_nzlist (g, c, cliques)
+CCtsp_lpgraph *g;
+CCtsp_lpcut *c;
+CCtsp_lpclique *cliques;
+#endif
+{
+    int nzlist = -1;
+    int i;
+
+    for (i = 0; i < c->cliquecount; i++) {
+        tsp_lpcut_nonzero_work (g, &cliques[c->cliques[i]], &nzlist);
+    }
+    tsp_lpcut_nonzero_modify (g, c->modcount, c->mods, &nzlist);
+    return nzlist;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void tsp_lpcut_nonzero_work (CCtsp_lpgraph *g, CCtsp_lpclique *c,
+        int *pnzlist)
+#else
+static void tsp_lpcut_nonzero_work (g, c, pnzlist)
+CCtsp_lpgraph *g;
+CCtsp_lpclique *c;
+int *pnzlist;
+#endif
+{
+    int nzlist = *pnzlist;
+    int nodemarker;
+    CCtsp_lpadj *a;
+    int e;
+    int j, k, l;
+
+    g->nodemarker++;
+    nodemarker = g->nodemarker;
+
+    for (j=0; j<c->segcount; j++) {
+        for (k=c->nodes[j].lo; k<=c->nodes[j].hi; k++) {
+            g->nodes[k].mark = nodemarker;
+        }
+    }
+
+    for (j=0; j<c->segcount; j++) {
+        for (k=c->nodes[j].lo; k<=c->nodes[j].hi; k++) {
+            a = g->nodes[k].adj;
+            for (l=0; l<g->nodes[k].deg; l++) {
+                if (g->nodes[a[l].to].mark != nodemarker) {
+                    e = a[l].edge;
+                    if (g->edges[e].coefnext == -2) {
+                        g->edges[e].coefnext = nzlist;
+                        nzlist = e;
+                    }
+                    g->edges[e].coef++;
+                }
+            }
+        }
+    }
+    *pnzlist = nzlist;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void tsp_lpcut_nonzero_modify (CCtsp_lpgraph *g, int modcount,
+        CCtsp_sparser *mods, int *pnzlist)
+#else
+static void tsp_lpcut_nonzero_modify (g, modcount, mods, pnzlist)
+CCtsp_lpgraph *g;
+int modcount;
+CCtsp_sparser *mods;
+int *pnzlist;
+#endif
+{
+    int nzlist = *pnzlist;
+    int i,j,k,l;
+    CCtsp_lpadj *a;
+    int e;
+
+    for (i=0; i<modcount; i++) {
+        k = mods[i].node;
+        j = ((int) mods[i].mult) - 128;
+        a = g->nodes[k].adj;
+        for (l=0; l<g->nodes[k].deg; l++) {
+            e = a[l].edge;
+            if (g->edges[e].coefnext == -2) {
+                g->edges[e].coefnext = nzlist;
+                nzlist = e;
+            }
+            g->edges[e].coef += j;
+        }
+    }
+    *pnzlist = nzlist;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_process_cuts (CCtsp_lp *lp, int *pnadded, int tighten)
+#else
+int CCtsp_process_cuts (lp, pnadded, tighten)
+CCtsp_lp *lp;
+int *pnadded;
+int tighten;
+#endif
+{
+    int nadded = 0;
+    int addpiece = 0;
+    CCtsp_lpcut_in *c = (CCtsp_lpcut_in *) NULL;
+    double *x = (double *) NULL;
+    int ecount_save;
+    int rval;
+    CCtsp_lprow cr;
+
+    *pnadded = 0;
+    CCtsp_init_lprow (&cr);
+    ecount_save = lp->graph.ecount;
+    x = CC_SAFE_MALLOC (ecount_save, double);
+    if (!x) {
+        return 1;
+    }
+
+    rval = CClp_x (&lp->lp, x);
+    if (rval) {
+        CC_FREE (x, double);
+        return rval;
+    }
+
+    nadded = 0;
+    addpiece = 0;
+    while (lp->cutqueue.next != &lp->cutqueue) {
+        c = lp->cutqueue.next;
+        c->next->prev = c->prev;
+        c->prev->next = c->next;
+        rval = checkout_cut (lp, c, x, &cr, tighten);
+        if (rval > 1) {
+            rval = 1;
+            goto CLEANUP;
+        } else if (rval == 1) {
+            nadded++;
+            addpiece++;
+            if (cr.rowcnt >= CCtsp_STORE_BATCH) {
+                if (cr.rowcnt > 0) {
+                    rval = CCtsp_add_multiple_rows (lp, &cr);
+                    if (rval) {
+                        fprintf (stderr, "CCtsp_add_multiple_rows failed\n");
+                        goto CLEANUP;
+                    }
+                    CCtsp_free_lprow (&cr);
+                }
+            }
+            if (addpiece >= CCtsp_CUT_BATCH) {
+                if (cr.rowcnt > 0) {
+                    rval = CCtsp_add_multiple_rows (lp, &cr);
+                    if (rval) {
+                        fprintf (stderr, "CCtsp_add_multiple_rows failed\n");
+                        goto CLEANUP;
+                    }
+                    CCtsp_free_lprow (&cr);
+                }
+                rval = update_newcuts (lp);
+                if (rval == 2) {
+                    printf ("LP is really infeasible (processs_cuts)\n");
+                    fflush (stdout);
+                    goto CLEANUP;
+                } else if (rval) {
+                    goto CLEANUP;
+                }
+                if (lp->graph.ecount != ecount_save) {
+                    CC_FREE (x, double);
+                    ecount_save = lp->graph.ecount;
+                    x = CC_SAFE_MALLOC (ecount_save, double);
+                    if (!x) {
+                        rval = 1;
+                        goto CLEANUP;
+                    }
+                }
+                rval = CClp_x (&lp->lp, x);
+                if (rval) {
+                    goto CLEANUP;
+                }
+                addpiece = 0;
+            }
+        }
+        CCtsp_free_lpcut_in (c);
+        CC_FREE (c, CCtsp_lpcut_in);
+    }
+    if (addpiece > 0) {
+        if (cr.rowcnt > 0) {
+            rval = CCtsp_add_multiple_rows (lp, &cr);
+            if (rval) {
+                fprintf (stderr, "CCtsp_add_multiple_rows failed\n");
+                goto CLEANUP;
+            }
+            CCtsp_free_lprow (&cr);
+        }
+        rval = update_newcuts (lp);
+        if (rval == 2) {
+            printf ("LP is really infeasible (processs_cuts)\n");
+            fflush (stdout);
+            goto CLEANUP;
+        } else if (rval) {
+            goto CLEANUP;
+        }
+    }
+    CC_FREE (x, double);
+    *pnadded = nadded;
+
+    rval = CCtsp_update_result (lp);
+    if (rval) goto CLEANUP;
+
+    return 0;
+
+CLEANUP:
+
+    CCtsp_free_lprow (&cr);
+    if (c) {
+        CCtsp_free_lpcut_in (c);
+        CC_FREE (c, CCtsp_lpcut_in);
+    }
+    CC_IFFREE (x, double);
+    *pnadded = nadded;
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_init_lprow (CCtsp_lprow *cr)
+#else
+void CCtsp_init_lprow (cr)
+CCtsp_lprow *cr;
+#endif
+{
+    cr->rowcnt = 0;
+    cr->nzcnt = 0;
+    cr->sense = (char *) NULL;
+    cr->rhs = (double *) NULL;
+    cr->begin = (int *) NULL;
+    cr->indexspace = 0;
+    cr->indices = (int *) NULL;
+    cr->entryspace = 0;
+    cr->entries = (double *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_lprow (CCtsp_lprow *cr)
+#else
+void CCtsp_free_lprow (cr)
+CCtsp_lprow *cr;
+#endif
+{
+    if (cr) {
+        cr->rowcnt = 0;
+        cr->nzcnt = 0;
+        CC_IFFREE (cr->sense, char);
+        CC_IFFREE (cr->rhs, double);
+        CC_IFFREE (cr->begin, int);
+        CC_IFFREE (cr->indices, int);
+        cr->indexspace = 0;
+        CC_IFFREE (cr->entries, double);
+        cr->entryspace = 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkout_cut (CCtsp_lp *lp, CCtsp_lpcut_in *c, double *x,
+        CCtsp_lprow *cr, int tighten)
+#else
+static int checkout_cut (lp, c, x, cr, tighten)
+CCtsp_lp *lp;
+CCtsp_lpcut_in *c;
+double *x;
+CCtsp_lprow *cr;
+int tighten;
+#endif
+{
+    int rval;
+    CCtsp_lpcut_in d;
+    double slack;
+    CCtsp_lpgraph *g = &lp->graph;
+
+    if (tighten) {
+        rval = CCtsp_tighten_lpcut_in (g, c, x, &d, &lp->tighten_stats,
+                                       (double *) NULL);
+        if (rval) {
+            fprintf (stderr, "CCtsp_tighten_lpcut_in failed\n");
+            return 2;
+        }
+    } else {
+        rval = CCtsp_copy_lpcut_in (c, &d);
+        if (rval) {
+            fprintf (stderr, "CCtsp_copy_lpcut_in failed\n");
+            return 2;
+        }
+    }
+
+    slack = CCtsp_cutprice (g, &d, x);
+    if (slack >= -CCtsp_MIN_VIOL) {
+        CCtsp_free_lpcut_in (&d);
+        return 0;
+    }
+
+    rval = verify_lpcut_in (g, &d);
+    if (rval) {
+        fprintf (stderr, "Discarding invalid cut\n");
+        CCtsp_print_lpcut_in (&d);
+        CCtsp_free_lpcut_in (&d);
+        return 2;
+    }
+
+    rval = CCtsp_add_cut (lp, &d, cr);
+    if (rval) {
+        CCtsp_free_lpcut_in (&d);
+        return 2;
+    }
+    CCtsp_free_lpcut_in (&d);
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_lpcut_in (CCtsp_lpcut_in *c)
+#else
+void CCtsp_free_lpcut_in (c)
+CCtsp_lpcut_in *c;
+#endif
+{
+    int i;
+
+    if (c) {
+        for (i = 0; i < c->cliquecount; i++) {
+            CCtsp_free_lpclique (&c->cliques[i]);
+        }
+        CC_IFFREE (c->cliques, CCtsp_lpclique);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_free_lpclique (CCtsp_lpclique *c)
+#else
+void CCtsp_free_lpclique (c)
+CCtsp_lpclique *c;
+#endif
+{
+    if (c) {
+        CC_IFFREE (c->nodes, CCtsp_segment);
+        c->segcount = 0;
+        c->hashnext = 0;
+        c->refcount = 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int verify_lpcut_in (CCtsp_lpgraph *g, CCtsp_lpcut_in *d)
+#else
+static int verify_lpcut_in (g, d)
+CCtsp_lpgraph *g;
+CCtsp_lpcut_in *d;
+#endif
+{
+    /* Verify not yet written. */
+
+    if (!d || !g) return 1;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int update_newcuts (CCtsp_lp *lp)
+#else
+static int update_newcuts (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int rval;
+    int ndeleted;
+
+    rval = CClp_opt (&lp->lp, CClp_METHOD_DUAL);
+    if (rval == 2) {
+        rval = CCtsp_infeas_recover (lp);
+        if (rval == 2) {
+            printf ("Problem is really infeasible (update_newcuts)\n");
+            return 2;
+        } else if (rval) {
+            return 1;
+        }
+    } else if (rval) {
+        fprintf (stderr, "CClp_opt failed\n");
+        return 1;
+    }
+    rval = age_cuts (lp, &ndeleted);
+    if (rval) {
+        fprintf (stderr, "age_cuts failed\n");
+        return 1;
+    }
+    rval = CClp_opt (&lp->lp, CClp_METHOD_DUAL);
+    if (rval) {
+        fprintf (stderr, "CClp_opt failed\n");
+        return 1;
+    }
+
+    ndeleted = 0;
+    rval = age_edges (lp, &ndeleted);
+    if (rval) {
+        fprintf (stderr, "age_edges failed\n");
+        return 1;
+    }
+    rval = CClp_opt (&lp->lp, CClp_METHOD_DUAL);
+    if (rval) {
+        fprintf (stderr, "CClp_opt failed\n");
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_infeas_recover (CCtsp_lp *lp)
+#else
+int CCtsp_infeas_recover (lp)
+CCtsp_lp *lp;
+#endif
+{
+    double penalty;
+    int nadded, feasible;
+    int rval;
+
+    printf ("infeas_recover ...\n"); fflush (stdout);
+
+    rval = CCtsp_addbad_variables (lp, (CCtsp_edgegenerator *) NULL, &penalty,
+                   &nadded, CCtsp_PHASE1_RCTHRESH, CCtsp_PHASE1_MAXPENALTY,
+                   1, &feasible);
+    if (rval) {
+        fprintf (stderr, "CCtsp_addbad_variables failed\n");
+        return 1;
+    }
+
+    if (feasible) {
+        printf ("Recovered a feasible LP\n");
+        fflush (stdout);
+        return 0;
+    } else {
+        printf ("Could not recover a feasible LP\n");
+        fflush (stdout);
+        return 2;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_cut (CCtsp_lp *lp, CCtsp_lpcut_in *d, CCtsp_lprow *cr)
+#else
+int CCtsp_add_cut (lp, d, cr)
+CCtsp_lp *lp;
+CCtsp_lpcut_in *d;
+CCtsp_lprow *cr;
+#endif
+{
+    int nzlist;
+    CCtsp_lpgraph *g = &lp->graph;
+    int saved;
+    CCtsp_lpcut new;
+    int rval;
+    int newloc;
+    int rhs;
+    int i;
+
+    assert (d->sense == 'G' || d->branch != 0);
+
+    new.rhs         = d->rhs;
+    new.sense       = d->sense;
+    new.branch      = d->branch;
+    new.modcount    = 0;
+    new.mods        = (CCtsp_sparser *) NULL;
+    new.cliquecount = 0;
+    new.handlecount = 0;
+    new.cliques     = (int *) NULL;
+    rval = CCtsp_register_cliques (&lp->cuts, d, &new);
+    if (rval) {
+        return rval;
+    }
+    nzlist = CCtsp_lpcut_in_nzlist (g, d);
+    rval = CCtsp_qsparsify (&lp->sparsifier, g, &nzlist, &new.modcount,
+                      &new.mods, &saved);
+    if (rval) {
+        CCtsp_unregister_cliques (&lp->cuts, &new);
+        CC_IFFREE (new.mods, CCtsp_sparser);
+        clear_nzlist (g, nzlist);
+        return rval;
+    }
+    new.age = CCtsp_NEWCUT_AGE;
+    newloc = CCtsp_add_cut_to_cutlist (&lp->cuts, &new);
+    if (newloc == -1) {
+        CCtsp_unregister_cliques (&lp->cuts, &new);
+        CC_IFFREE (new.mods, CCtsp_sparser);
+        clear_nzlist (g, nzlist);
+        return 1;
+    }
+    rhs = new.rhs;
+    for (i=0; i<new.modcount; i++) {
+        rhs += 2*(((int) new.mods[i].mult) - 128);
+    }
+    rval = CCtsp_add_nzlist_to_lp (lp, nzlist, rhs, new.sense, cr);
+    if (rval) {
+        fprintf (stderr, "CCtsp_add_nzlist_to_lp failed\n");
+        CCtsp_delete_cut_from_cutlist (&lp->cuts, newloc);
+        return rval;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_register_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut_in *c,
+        CCtsp_lpcut *new)
+#else
+int CCtsp_register_cliques (cuts, c, new)
+CCtsp_lpcuts *cuts;
+CCtsp_lpcut_in *c;
+CCtsp_lpcut *new;
+#endif
+{
+    int i, j;
+
+    new->cliques = CC_SAFE_MALLOC (c->cliquecount, int);
+    if (!new->cliques) return 1;
+    new->handlecount = c->handlecount;
+    new->cliquecount = c->cliquecount;
+    for (i = 0; i < c->cliquecount; i++) {
+        new->cliques[i] = CCtsp_register_clique (cuts, &c->cliques[i]);
+        if (new->cliques[i] == -1) {
+            for (j=0; j<i; j++) {
+                CCtsp_unregister_clique (cuts, new->cliques[j]);
+            }
+            CC_FREE (new->cliques, int);
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_unregister_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut *c)
+#else
+void CCtsp_unregister_cliques (cuts, c)
+CCtsp_lpcuts *cuts;
+CCtsp_lpcut *c;
+#endif
+{
+    int i;
+
+    for (i = 0; i < c->cliquecount; i++) {
+        CCtsp_unregister_clique (cuts, c->cliques[i]);
+    }
+    CC_FREE (c->cliques, int);
+    c->cliquecount = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_cut_to_cutlist (CCtsp_lpcuts *cuts, CCtsp_lpcut *c)
+#else
+int CCtsp_add_cut_to_cutlist (cuts, c)
+CCtsp_lpcuts *cuts;
+CCtsp_lpcut *c;
+#endif
+{
+    if (cuts->cutcount >= cuts->cutspace) {
+        if (CCutil_reallocrus_scale ((void **) &cuts->cuts, &cuts->cutspace,
+                         cuts->cutcount + 1, 1.3, sizeof (CCtsp_lpcut))) {
+            return -1;
+        }
+    }
+    cuts->cuts[cuts->cutcount] = *c;
+    return cuts->cutcount++;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_nzlist_to_lp (CCtsp_lp *lp, int nzlist, int rhs, char sense,
+        CCtsp_lprow *cr)
+#else
+int CCtsp_add_nzlist_to_lp (lp, nzlist, rhs, sense, cr)
+CCtsp_lp *lp;
+int nzlist;
+int rhs;
+char sense;
+CCtsp_lprow *cr;
+#endif
+{
+    int nzcnt;
+    int i;
+    CCtsp_lpgraph *g = &lp->graph;
+    int *rmatind = (int *) NULL;
+    double *rmatval = (double *) NULL;
+    double drhs = (double) rhs;
+    int rval;
+
+    nzcnt = 0;
+    for (i=nzlist; i != -1; i = g->edges[i].coefnext) {
+        if (g->edges[i].coef) nzcnt++;
+    }
+
+    if (nzcnt != 0) {
+        rmatind = CC_SAFE_MALLOC (nzcnt, int);
+        if (!rmatind) {
+            clear_nzlist (g, nzlist);
+            return 1;
+        }
+        rmatval = CC_SAFE_MALLOC (nzcnt, double);
+        if (!rmatval) {
+            CC_FREE (rmatind, int);
+            clear_nzlist (g, nzlist);
+            return 1;
+        }
+        for (nzcnt = 0; nzlist != -1; nzlist = i) {
+            i = g->edges[nzlist].coefnext;
+            g->edges[nzlist].coefnext = -2;
+            if (g->edges[nzlist].coef) {
+                rmatind[nzcnt] = nzlist;
+                rmatval[nzcnt] = g->edges[nzlist].coef;
+                g->edges[nzlist].coef = 0;
+                nzcnt++;
+            }
+        }
+    } else {
+        printf ("WARNING: Adding an empty cut to the LP\n");
+        fflush (stdout);
+    }
+
+    rval = addrow_to_list (nzcnt, drhs, sense, rmatind, rmatval, cr);
+
+    CC_FREE (rmatind, int);
+    CC_FREE (rmatval, double);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCtsp_delete_cut_from_cutlist (CCtsp_lpcuts *cuts, int ind)
+#else
+void CCtsp_delete_cut_from_cutlist (cuts, ind)
+CCtsp_lpcuts *cuts;
+int ind;
+#endif
+{
+    int i;
+
+    CCtsp_unregister_cliques (cuts, &cuts->cuts[ind]);
+    CC_IFFREE (cuts->cuts[ind].mods, CCtsp_sparser);
+    for (i = ind+1; i < cuts->cutcount; i++) {
+        cuts->cuts[i-1] = cuts->cuts[i];
+    }
+    cuts->cutcount--;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clear_nzlist (CCtsp_lpgraph *g, int nzlist)
+#else
+static void clear_nzlist (g, nzlist)
+CCtsp_lpgraph *g;
+int nzlist;
+#endif
+{
+    int nznext;
+
+    while (nzlist != -1) {
+        nznext = g->edges[nzlist].coefnext;
+        g->edges[nzlist].coefnext = -2;
+        g->edges[nzlist].coef = 0;
+        nzlist = nznext;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_addbad_variables (CCtsp_lp *lp, struct CCtsp_edgegenerator *eg,
+        double *ppenalty, int *pnadded, double rcthresh, double maxpenalty,
+        int phase1, int *feasible)
+#else
+int CCtsp_addbad_variables (lp, eg, ppenalty, pnadded, rcthresh, maxpenalty,
+        phase1, feasible)
+CCtsp_lp *lp;
+struct CCtsp_edgegenerator *eg;
+double *ppenalty;
+int *pnadded;
+double rcthresh, maxpenalty;
+int phase1;
+int *feasible;
+#endif
+{
+    int nadded;
+    double penalty;
+    int finished;
+    CCtsp_edgehash eh;
+    int rval;
+    int *genlist = (int *) NULL;
+    int *genlen = (int *) NULL;
+    int gencount;
+    CCtsp_predge *inlist = (CCtsp_predge *) NULL;
+    int incount;
+    CCtsp_predge *prlist = (CCtsp_predge *) NULL;
+    int prcount;
+    double *node_pi = (double *) NULL;
+    double *node_piest = (double *) NULL;
+    double *clique_pi = (double *) NULL;
+    double *cut_pi = (double *) NULL;
+    int i, iend, n;
+    int start = 0, ni, nj;
+    int ngen = PRICE_GEN + PRICE_GEN_FACTOR * lp->graph.ncount;
+
+    if (phase1) {
+        printf ("phase 1 addbad_variables\n"); fflush (stdout);
+    }
+
+    if (feasible)
+        *feasible = 0;
+
+    rval = CCtsp_edgehash_init (&eh, (int) (ngen * 1.5));
+    if (rval) return rval;
+
+    gencount = 0;
+    incount = 0;
+    prcount = 0;
+
+    genlist    = CC_SAFE_MALLOC (ngen*2, int);
+    genlen     = CC_SAFE_MALLOC (ngen, int);
+    inlist     = CC_SAFE_MALLOC (ngen, CCtsp_predge);
+    prlist     = CC_SAFE_MALLOC (PRICE_POOL + ngen, CCtsp_predge);
+    node_pi    = CC_SAFE_MALLOC (lp->graph.ncount, double);
+    node_piest = CC_SAFE_MALLOC (lp->graph.ncount, double);
+    if (!genlist || !genlen || !inlist || !prlist || !node_pi || !node_piest) {
+        fprintf (stderr, "out of memory in CCtsp_addbad_variables\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    if (lp->cuts.cliqueend) {
+        clique_pi = CC_SAFE_MALLOC (lp->cuts.cliqueend, double);
+        if (!clique_pi) {
+            fprintf (stderr, "out of memory in CCtsp_addbad_variables\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+    if (lp->cuts.cutcount) {
+        cut_pi = CC_SAFE_MALLOC (lp->cuts.cutcount, double);
+        if (!cut_pi) {
+            fprintf (stderr, "out of memory in CCtsp_addbad_variables\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    *pnadded = 0;
+    rval = pricing_duals (lp, node_pi, node_piest, cut_pi, clique_pi);
+    if (rval) {
+        fprintf (stderr, "pricing_duals failed\n");
+        goto CLEANUP;
+    }
+    if (phase1) {
+        start = ni = 0;
+        nj = (lp->full_edges_valid ? 0 : start + 1);
+    } else {
+        rval = CCtsp_reset_edgegenerator (eg, node_piest);
+        if (rval) goto CLEANUP;
+    }
+    finished = 0;
+    nadded = 0;
+    penalty = 0.0;
+    while (!finished) {
+        if (phase1) {
+            rval = phase1_generate_edges (lp, node_piest, ngen,
+                 &gencount, genlist, genlen, start, &ni, &nj, &finished);
+            if (rval) {
+                fprintf (stderr, "phase1_generate_edges failed\n");
+                goto CLEANUP;
+            }
+        } else {
+            rval = CCtsp_generate_edges (eg, ngen, &gencount, genlist, genlen,
+                                   &finished);
+            if (rval) {
+                fprintf (stderr, "CCtsp_generate_edges failed\n");
+                goto CLEANUP;
+            }
+        }
+
+        for (i = 0, incount = 0; i < gencount; i++) {
+            if (CCtsp_edgehash_find (&eh, genlist[2*i], genlist[2*i+1]) == -1
+             && CCtsp_find_edge (&lp->graph, genlist[2*i],
+                                             genlist[2*i+1]) == -1) {
+                CCtsp_edgehash_add (&eh, genlist[2*i], genlist[2*i+1], 1);
+                if (genlist[2*i] < genlist[2*i+1]) {
+                    inlist[incount].ends[0] = genlist[2*i];
+                    inlist[incount].ends[1] = genlist[2*i+1];
+                } else {
+                    inlist[incount].ends[0] = genlist[2*i+1];
+                    inlist[incount].ends[1] = genlist[2*i];
+                }
+                inlist[incount].len = genlen[i];
+                incount++;
+            }
+        }
+        rval = price_list (lp, incount, inlist, node_pi, clique_pi, phase1);
+        if (rval) goto CLEANUP;
+        for (i=0; i<incount; i++) {
+            if (inlist[i].rc < 0.0) penalty += inlist[i].rc;
+            if (inlist[i].rc < rcthresh) {
+                prlist[prcount++] = inlist[i];
+            } else {
+                rval = CCtsp_edgehash_del (&eh, inlist[i].ends[0],
+                                                inlist[i].ends[1]);
+                if (rval) goto CLEANUP;
+            }
+        }
+        nadded = 0;
+        while ((!finished && prcount >= PRICE_POOL) ||
+                (finished && penalty < -maxpenalty && prcount > 0)) {
+            n = PRICE_ADD;
+            if (n >= prcount) {
+                n = prcount;
+            } else {
+                pr_select (prcount - n, prcount, prlist);
+            }
+            printf ("Add %d\n", n); fflush (stdout);
+            rval = CCtsp_add_vars_to_lp (lp, prlist + prcount - n, n);
+            if (rval) goto CLEANUP;
+            nadded += n;
+            *pnadded += n;
+            prcount -= n;
+            rval = CClp_opt (&lp->lp, CClp_METHOD_DUAL);
+            if (phase1) {
+                if (rval == 0) {
+                    printf ("LP is now feasible\n"); fflush (stdout);
+                    if (feasible) *feasible = 1;
+                    goto DONE;
+                } else if (rval != 2) {
+                    fprintf (stderr, "CClp_opt failed\n");
+                    goto CLEANUP;
+                }
+            } else {
+                if (rval == 2) {
+                    fprintf (stderr, "Adding variables made LP infeasible!\n");
+                    rval = 1;
+                    goto CLEANUP;
+                } else if (rval) {
+                    fprintf (stderr, "CClp_opt failed\n");
+                    goto CLEANUP;
+                }
+            }
+            rval = pricing_duals (lp, node_pi, node_piest, cut_pi,
+                                  clique_pi);
+            if (rval) {
+                fprintf (stderr, "pricing_duals failed\n");
+                goto CLEANUP;
+            }
+            rval = price_list (lp, prcount, prlist, node_pi, clique_pi, phase1);
+            if (rval) {
+                fprintf (stderr, "price_list failed\n");
+                goto CLEANUP;
+            }
+            penalty = 0.0;
+            for (i=0, iend = prcount, prcount = 0; i<iend; i++) {
+                if (prlist[i].rc < 0.0) penalty += prlist[i].rc;
+                if (prlist[i].rc < rcthresh &&
+                    CCtsp_find_edge (&lp->graph, prlist[i].ends[0],
+                                               prlist[i].ends[1]) == -1) {
+                    prlist[prcount++] = prlist[i];
+                }
+            }
+        }
+        if (nadded > 0) {
+            if (phase1) {
+                start = ni;
+                nj = (lp->full_edges_valid ? 0 : start + 1);
+            } else {
+                rval = CCtsp_reset_edgegenerator (eg, node_piest);
+                if (rval) goto CLEANUP;
+            }
+            finished = 0;
+            CCtsp_edgehash_delall (&eh);
+            for (i = 0; i < prcount; i++) {
+                CCtsp_edgehash_add (&eh, prlist[i].ends[0],
+                                         prlist[i].ends[1], 1);
+            }
+        }
+    }
+
+DONE:
+
+    *ppenalty = penalty;
+    if (!phase1 || (feasible && *feasible))
+        rval = CCtsp_update_result (lp);
+
+CLEANUP:
+
+    CC_IFFREE (cut_pi, double);
+    CC_IFFREE (clique_pi, double);
+    CC_IFFREE (node_piest, double);
+    CC_IFFREE (node_pi, double);
+    CC_IFFREE (prlist, CCtsp_predge);
+    CC_IFFREE (inlist, CCtsp_predge);
+    CC_IFFREE (genlen, int);
+    CC_IFFREE (genlist, int);
+    CCtsp_edgehash_free (&eh);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int phase1_generate_edges (CCtsp_lp *lp, double *node_piest, int nwant,
+        int *ngot, int *genlist, int *genlen, int start, int *ni, int *nj,
+        int *finished)
+#else
+static int phase1_generate_edges (lp, node_piest, nwant, ngot, genlist, genlen,
+       start, ni, nj, finished)
+CCtsp_lp *lp;
+double *node_piest;
+int nwant;
+int *ngot, *genlist, *genlen;
+int start;
+int *ni, *nj, *finished;
+#endif
+{
+    int i = *ni;
+    int j = *nj;
+    CCtsp_genadj *adj;
+    CCdatagroup *dat;
+    int cnt = 0;
+    int ncount = lp->graph.ncount;
+
+    *ngot = 0;
+    *finished = 0;
+
+    if (!lp->dat && !lp->full_edges_valid) {
+        fprintf (stderr, "no source of edges to generate\n");
+        return 1;
+    }
+
+    if (i >= ncount) {
+        i = 0;
+        j = (lp->full_edges_valid ? 0 : i + 1);
+    }
+
+    if (lp->full_edges_valid) {
+        adj = lp->fulladj;
+        for (; j < adj[i].deg; j++) {
+            if (phase1_test_edge (i, adj[i].list[j].end, node_piest)) {
+                genlist[2*cnt] = i;
+                genlist[2*cnt+1] = adj[i].list[j].end;
+                genlen[cnt] = adj[i].list[j].len;
+                cnt++;
+                if (cnt == nwant) {
+                    goto NOT_FINISHED;
+                }
+            }
+        }
+        while ((i = (i+1) % ncount) != start) {
+            for (j = 0; j < adj[i].deg; j++) {
+                if (phase1_test_edge (i, adj[i].list[j].end, node_piest)) {
+                    genlist[2*cnt] = i;
+                    genlist[2*cnt+1] = adj[i].list[j].end;
+                    genlen[cnt] = adj[i].list[j].len;
+                    cnt++;
+                    if (cnt == nwant) {
+                        goto NOT_FINISHED;
+                    }
+                }
+            }
+        }
+    } else {
+        dat = lp->dat;
+        for (; j < ncount; j++) {
+            if (phase1_test_edge (i, j, node_piest)) {
+                genlist[2*cnt] = i;
+                genlist[2*cnt+1] = j;
+                genlen[cnt] = CCutil_dat_edgelen (i, j, dat);
+                cnt++;
+                if (cnt == nwant) {
+                    goto NOT_FINISHED;
+                }
+            }
+        }
+        while ((i = (i+1) % ncount) != start) {
+            for  (j = i + 1; j < ncount; j++) {
+                if (phase1_test_edge (i, j, node_piest)) {
+                    genlist[2*cnt] = i;
+                    genlist[2*cnt+1] = j;
+                    genlen[cnt] = CCutil_dat_edgelen (i, j, dat);
+                    cnt++;
+                    if (cnt == nwant) {
+                        goto NOT_FINISHED;
+                    }
+                }
+            }
+        }
+    }
+
+    *finished = 1;
+    return 0;
+
+NOT_FINISHED:
+
+    *finished = 0;
+    *ngot = cnt;
+    *ni = i; *nj = j + 1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int phase1_test_edge (int end1, int end2, double *node_piest)
+#else
+static int phase1_test_edge (end1, end2, node_piest)
+int end1, end2;
+double *node_piest;
+#endif
+{
+    return (node_piest[end1] + node_piest[end2] > 0.0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_eliminate_variables (CCtsp_lp *lp)
+#else
+int CCtsp_eliminate_variables (lp)
+CCtsp_lp *lp;
+#endif
+{
+    int i, j, k;
+    int rval;
+    CCbigguy ub;
+
+    /* This function should not create an infeasible LP */
+
+    if (lp->upperbound == CCtsp_LP_MAXDOUBLE ||
+            CCbigguy_cmp (lp->exact_lowerbound, CCbigguy_MINBIGGUY) == 0) {
+        printf ("Can't elmininate without upper and lower bounds\n");
+        fflush (stdout);
+        return 0;
+    }
+
+    ub = CCbigguy_dtobigguy (lp->upperbound - 1.0);
+    if (CCbigguy_cmp (lp->exact_lowerbound, ub) > 0) {
+        printf ("No need for elimination, bounds are optimal\n");
+        fflush (stdout);
+        return 0;
+    }
+
+    assert (lp->infeasible == 0);
+
+    rval = CCtsp_edge_elimination (lp);
+    if (rval) {
+        fprintf (stderr, "tsp_edge_elimination failed\n");
+        return rval;
+    }
+
+    assert (lp->infeasible == 0);
+
+    for (i = 0; i < lp->nfixededges; i++) {
+        k = CCtsp_find_edge (&(lp->graph), lp->fixededges[2*i],
+                                           lp->fixededges[2*i+1]);
+        if (k != -1) {
+            rval = CClp_setbnd (&lp->lp, k, 'L', 1.0);
+            lp->graph.edges[k].fixed = 1;
+        } else {
+            printf ("WARNING: Fixed edge is not in LP\n");
+            fflush (stdout);
+        }
+    }
+
+    CC_IFFREE (lp->graph.adjspace, CCtsp_lpadj);
+    for (i = lp->graph.ecount - 1; i >= 0; i--) {
+        if (!find_edge_full (lp, lp->graph.edges[i].ends[0],
+                                 lp->graph.edges[i].ends[1])) {
+            if (!lp->graph.edges[i].fixed && !lp->graph.edges[i].branch) {
+                rval = CClp_delete_column (&lp->lp, i);
+                if (rval) {
+                    fprintf (stderr, "CClp_delete_column failed\n");
+                    return rval;
+                }
+                lp->graph.edges[i].ends[0] = 0;
+                lp->graph.edges[i].ends[1] = 0;
+            } else {
+                printf ("WARNING: Tried to eliminate a fixed/branch edge\n");
+                fflush (stdout);
+            }
+        }
+    }
+    for (i = 0, j = 0; i < lp->graph.ecount; i++) {
+        if (lp->graph.edges[i].ends[1] != 0 ||
+            lp->graph.edges[i].ends[0] != 0) {
+            lp->graph.edges[j] = lp->graph.edges[i];
+            j++;
+        }
+    }
+    printf ("Eliminated %d LP edges\n", lp->graph.ecount - j);
+    fflush (stdout);
+
+    assert (lp->infeasible == 0);
+
+    lp->graph.ecount = j;
+    rval = CCtsp_build_lpadj (&lp->graph, 0, lp->graph.ecount);
+    if (rval) {
+        fprintf (stderr, "CCtsp_build_lpadj failed\n");
+        return rval;
+    }
+
+    rval = CClp_opt (&lp->lp, CClp_METHOD_DUAL);
+    if (rval == 2) {
+        fprintf (stderr, "ERROR: edge_elimination created an infeasible LP\n");
+        return 1;
+    } else if (rval) {
+        fprintf (stderr, "CClp_opt failed\n");
+        return rval;
+    }
+    rval = CCtsp_update_result (lp);
+    if (rval) {
+        fprintf (stderr, "CCtsp_update_result failed\n");
+        return rval;
+    }
+
+    assert (lp->infeasible == 0);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int pricing_duals (CCtsp_lp *lp, double *node_pi,
+        double *node_piest, double *cut_pi, double *clique_pi)
+#else
+static int pricing_duals (lp, node_pi, node_piest, cut_pi, clique_pi)
+CCtsp_lp *lp;
+double *node_pi;
+double *node_piest;
+double *cut_pi;
+double *clique_pi;
+#endif
+{
+    double x;
+    int i, j, k;
+    int rval;
+
+    rval = get_pi (lp, node_pi, cut_pi);
+    if (rval) {
+        fprintf (stderr, "get_pi failed\n");
+        return rval;
+    }
+
+    for (i = 0; i < lp->cuts.cliqueend; i++) {
+        clique_pi[i] = 0.0;
+    }
+
+    for (i = 0; i < lp->cuts.cutcount; i++) {
+        x = cut_pi[i];
+        for (j = 0; j < lp->cuts.cuts[i].modcount; j++) {
+            node_pi[lp->cuts.cuts[i].mods[j].node] += x *
+                (((int) lp->cuts.cuts[i].mods[j].mult) - 128);
+        }
+        for (j = 0; j < lp->cuts.cuts[i].cliquecount; j++) {
+            clique_pi[lp->cuts.cuts[i].cliques[j]] += x;
+        }
+    }
+
+    for (i = 0; i < lp->graph.ncount; i++) {
+        node_piest[i] = node_pi[i];
+    }
+
+    for (i = 0; i < lp->cuts.cliqueend; i++) {
+        x = clique_pi[i];
+        if (x > 0.0) {
+            for (j = 0; j < lp->cuts.cliques[i].segcount; j++) {
+                for (k = lp->cuts.cliques[i].nodes[j].lo;
+                     k <= lp->cuts.cliques[i].nodes[j].hi; k++) {
+                    node_pi[k] += x;
+                    node_piest[k] += x;
+                }
+            }
+        } else if (x < 0.0) {
+            for (j = 0; j < lp->cuts.cliques[i].segcount; j++) {
+                for (k = lp->cuts.cliques[i].nodes[j].lo;
+                     k <= lp->cuts.cliques[i].nodes[j].hi; k++) {
+                    node_pi[k] += x;
+                }
+            }
+        }
+    }
+
+    /* For now, no munching of edges.  To do in future, just add
+       loop here for each edge clique, (if find_edge,)? zero the edge
+       clique's pi */
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int price_list (CCtsp_lp *lp, int ecount, CCtsp_predge *elist,
+        double *node_pi, double *clique_pi, int phase1)
+#else
+static int price_list (lp, ecount, elist, node_pi, clique_pi, phase1)
+CCtsp_lp *lp;
+int ecount;
+CCtsp_predge *elist;
+double *node_pi;
+double *clique_pi;
+int phase1;
+#endif
+{
+    CCtsp_lpadj *adjspace = (CCtsp_lpadj *) NULL;
+    CCtsp_lpnode *n = (CCtsp_lpnode *) NULL;
+    int i, j, k, l;
+    CCtsp_lpadj *a;
+    int marker = 0;
+    double x;
+    int ncount = lp->graph.ncount;
+    int ccount = lp->cuts.cliqueend;
+    CCtsp_lpclique *c = lp->cuts.cliques;
+
+    if (ecount == 0) return 0;
+
+    n = CC_SAFE_MALLOC (ncount, CCtsp_lpnode);
+    if (!n) return 1;
+    adjspace = CC_SAFE_MALLOC (2*ecount, CCtsp_lpadj);
+    if (!adjspace) {
+        CC_FREE (n, CCtsp_lpnode);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        n[i].deg = 0;
+        n[i].mark = 0;
+    }
+    for (i = 0; i < ecount; i++) {
+        if (phase1) {
+            elist[i].rc = - node_pi[elist[i].ends[0]]
+                          - node_pi[elist[i].ends[1]];
+
+        } else {
+            elist[i].rc = elist[i].len
+                          - node_pi[elist[i].ends[0]]
+                          - node_pi[elist[i].ends[1]];
+        }
+
+        n[elist[i].ends[0]].deg++;
+        n[elist[i].ends[1]].deg++;
+    }
+    a = adjspace;
+    for (i = 0; i < ncount; i++) {
+        n[i].adj = a;
+        a += n[i].deg;
+        n[i].deg = 0;
+    }
+    for (i=0; i<ecount; i++) {
+        j = elist[i].ends[0];
+        n[j].adj[n[j].deg].to = elist[i].ends[1];
+        n[j].adj[n[j].deg].edge = i;
+        n[j].deg++;
+        j = elist[i].ends[1];
+        n[j].adj[n[j].deg].to = elist[i].ends[0];
+        n[j].adj[n[j].deg].edge = i;
+        n[j].deg++;
+    }
+
+    for (i = 0; i < ccount; i++) {
+        if (clique_pi[i]) {
+            x = clique_pi[i] * 2;
+            marker++;
+            for (j = 0; j < c[i].segcount; j++) {
+                for (k = c[i].nodes[j].lo; k <= c[i].nodes[j].hi; k++) {
+                    a = n[k].adj;
+                    for (l = 0; l < n[k].deg; l++) {
+                        if (n[a[l].to].mark == marker) {
+                            elist[a[l].edge].rc += x;
+                            /* We could test if rc>0, and delete e from adj*/
+                        }
+                    }
+                    n[k].mark = marker;
+                }
+            }
+        }
+    }
+    CC_FREE (n, CCtsp_lpnode);
+    CC_FREE (adjspace, CCtsp_lpadj);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void pr_select (int nsel, int n, CCtsp_predge *list)
+#else
+static void pr_select (nsel, n, list)
+int nsel;
+int n;
+CCtsp_predge *list;
+#endif
+{
+    double s1, s2, s3, s;
+    int i, j, k, l;
+    CCtsp_predge t;
+
+    s1 = list[n/4].rc;
+    s2 = list[n/2].rc;
+    s3 = list[3*n/4].rc;
+    if (s1 < s2) {
+        if (s2 < s3) s = s2;
+        else if (s1 < s3) s = s3;
+        else s = s1;
+    } else {
+        if (s1 < s3) s = s1;
+        else if (s2 < s3) s = s3;
+        else s = s2;
+    }
+
+    /* 0 <= x < i ==> r[i] == s
+     * i <= x < j ==> r[i] > s
+     * j <= x <= k ==> r[i] unknown
+     * k < x <= l ==> r[i] < s
+     * l < x < n ==> r[i] == s
+     */
+
+    i = j = 0;
+    k = l = n-1;
+    while (j <= k) {
+        while (j <= k && list[j].rc >= s) {
+            if (list[j].rc == s) {
+                CC_SWAP (list[i], list[j], t);
+                i++;
+            }
+            j++;
+        }
+        while (j <= k && list[k].rc <= s) {
+            if (list[k].rc == s) {
+                CC_SWAP (list[l], list[k], t);
+                l--;
+            }
+            k--;
+        }
+        if (j <= k) {
+            CC_SWAP (list[j], list[k], t);
+            j++;
+            k--;
+        }
+    }
+    while (i > 0) {
+        i--;
+        j--;
+        CC_SWAP (list[i], list[j], t);
+    }
+    while (l < n-1) {
+        k++;
+        l++;
+        CC_SWAP (list[k], list[l], t);
+    }
+    /* 0 <= x < j ==> r[i] > s
+     * j <= x <= k ==> r[i] == s
+     * k < x < n ==> r[i] < s
+     */
+    if (nsel < j) {
+        pr_select (nsel, j, list);
+    } else if (nsel > k) {
+        pr_select (nsel - (k+1), n - (k+1), list + (k+1));
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_vars_to_lp (CCtsp_lp *lp, CCtsp_predge *prlist, int n)
+#else
+int CCtsp_add_vars_to_lp (lp, prlist, n)
+CCtsp_lp *lp;
+CCtsp_predge *prlist;
+int n;
+#endif
+{
+    int i;
+    CCtsp_lpedge *e;
+    int rval;
+    int nzcnt;
+    double *obj;
+    int *matbeg;
+    int *matind;
+    double *matval;
+    double *lb;
+    double *ub;
+
+    while (lp->graph.ecount + n > lp->graph.espace) {
+        if (CCutil_reallocrus_scale ((void **) &lp->graph.edges,
+                &lp->graph.espace,
+                lp->graph.ecount + n, 1.3, sizeof (CCtsp_lpedge))) {
+            return 1;
+        }
+    }
+    e = lp->graph.edges + lp->graph.ecount;
+    for (i = 0; i < n; i++) {
+        e[i].ends[0] = prlist[i].ends[0];
+        e[i].ends[1] = prlist[i].ends[1];
+        e[i].fixed = 0;
+        e[i].branch = 0;
+        e[i].age = 0;
+        e[i].len = prlist[i].len;
+        e[i].coefnext = -2;
+        e[i].coef = 0;
+    }
+
+    rval = build_lp_cols (&lp->graph, &lp->cuts, lp->graph.ecount,
+                          lp->graph.ecount + n, &nzcnt, &obj, &matbeg,
+                          (int **) NULL, &matind, &matval, &lb, &ub);
+    if (rval) return rval;
+
+    rval = lp_addcols (lp, n, nzcnt, obj, matbeg, matind, matval,
+                          lb, ub);
+    if (rval) goto CLEANUP;
+
+    lp->graph.ecount += n;
+    rval = CCtsp_build_lpadj (&lp->graph, 0, lp->graph.ecount);
+    if (rval) goto CLEANUP;
+    rval = 0;
+
+CLEANUP:
+
+    CC_IFFREE (obj, double);
+    CC_IFFREE (matbeg, int);
+    CC_IFFREE (matind, int);
+    CC_IFFREE (matval, double);
+    CC_IFFREE (lb, double);
+    CC_IFFREE (ub, double);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int age_cuts (CCtsp_lp *lp, int *ndeleted)
+#else
+static int age_cuts (lp, ndeleted)
+CCtsp_lp *lp;
+int *ndeleted;
+#endif
+{
+    int *rstat = (int *) NULL;
+    int *cutstat = (int *) NULL;
+    int *del = (int *) NULL;
+    double *cut_pi = (double *) NULL;
+    int ncount = lp->graph.ncount;
+    int rval;
+    int i, j;
+
+    *ndeleted = 0;
+
+    rstat = CC_SAFE_MALLOC (ncount + lp->cuts.cutcount, int);
+    if (!rstat) {
+        return 1;
+    }
+    rval = CClp_basis (&lp->lp, (int *) NULL, rstat);
+    if (rval) {
+        CC_FREE (rstat, int);
+        return rval;
+    }
+    cutstat = rstat + ncount;
+    if (lp->cuts.cutcount) {
+        cut_pi = CC_SAFE_MALLOC (lp->cuts.cutcount, double);
+        if (!cut_pi) {
+            CC_FREE (rstat, int);
+            return 1;
+        }
+    }
+    rval = get_pi (lp, (double *) NULL, cut_pi);
+    if (rval) {
+        fprintf (stderr, "get_pi failed\n");
+        CC_IFFREE (cut_pi, double);
+        CC_FREE (rstat, int);
+        return rval;
+    }
+
+    for (i = lp->cuts.cutcount-1; i >= 0; i--) {
+        if (lp->cuts.cuts[i].branch == 0) {
+            if (cut_pi[i]) {
+                if (lp->cuts.cuts[i].age == CCtsp_NEWCUT_AGE) {
+                    rval = CCtsp_add_to_cutpool (lp->pool, &lp->cuts,
+                                                 &lp->cuts.cuts[i]);
+                    if (rval) {
+                        fprintf (stderr, "add_to_cutpool failed\n");
+                        CC_FREE (cut_pi, double);
+                        CC_FREE (rstat, int);
+                        return rval;
+                    }
+                }
+                lp->cuts.cuts[i].age = 0;
+            } else {
+                if (lp->cuts.cuts[i].age != CCtsp_NEWCUT_AGE) {
+                    lp->cuts.cuts[i].age++;
+                }
+                if (cutstat[i] == 1 &&
+                    (lp->cuts.cuts[i].age == CCtsp_NEWCUT_AGE ||
+                     lp->cuts.cuts[i].age >= lp->cut_life)) {
+                    CCtsp_unregister_cliques (&lp->cuts, &lp->cuts.cuts[i]);
+                    CC_IFFREE (lp->cuts.cuts[i].mods, CCtsp_sparser);
+                    lp->cuts.cuts[i].handlecount = 0;
+                    lp->cuts.cuts[i].cliquecount = 0;
+                    lp->cuts.cuts[i].modcount = 0;
+                }
+            }
+        }
+    }
+    CC_FREE (rstat, int);
+    CC_IFFREE (cut_pi, double);
+
+    del = CC_SAFE_MALLOC (lp->cuts.cutcount, int);
+    if (!del) {
+        fprintf (stderr, "out of memory in age_cuts\n");
+        return 1;
+    }
+    for (i = 0, j = 0; i < lp->cuts.cutcount; i++) {
+        if (lp->cuts.cuts[i].cliquecount) {
+            lp->cuts.cuts[j] = lp->cuts.cuts[i];
+            j++;
+            del[i] = 0;
+        } else {
+            del[i] = 1;
+        }
+    }
+    if (j < lp->cuts.cutcount) {
+        rval = lp_delete_cut_set (lp, del);
+        if (rval) {
+            fprintf (stderr, "lp_delete_cut_set failed\n");
+            CC_FREE (del, int);
+            return rval;
+        }
+    }
+    CC_FREE (del, int);
+
+    *ndeleted = lp->cuts.cutcount - j;
+    lp->cuts.cutcount = j;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int age_edges (CCtsp_lp *lp, int *ndeleted)
+#else
+static int age_edges (lp, ndeleted)
+CCtsp_lp *lp;
+int *ndeleted;
+#endif
+{
+    int *cstat = (int *) NULL;
+    int *del = (int *) NULL;
+    int rval;
+    int i, j;
+
+    *ndeleted = 0;
+
+    cstat = CC_SAFE_MALLOC (lp->graph.ecount, int);
+    if (!cstat) {
+        fprintf (stderr, "out of memory in age_edges\n");
+        return 1;
+    }
+    rval = CClp_basis (&lp->lp, cstat, (int *) NULL);
+    if (rval) {
+        CC_FREE (cstat, int);
+        return rval;
+    }
+
+    CC_IFFREE (lp->graph.adjspace, CCtsp_lpadj);
+
+    for (i = lp->graph.ecount-1; i >= 0; i--) {
+        if (cstat[i] == 0) {
+            lp->graph.edges[i].age++;
+            if (lp->graph.edges[i].age >= lp->edge_life &&
+                !lp->graph.edges[i].fixed && !lp->graph.edges[i].branch) {
+                lp->graph.edges[i].ends[0] = 0;
+                lp->graph.edges[i].ends[1] = 0;
+            }
+        } else {
+            lp->graph.edges[i].age = 0;
+        }
+    }
+    CC_FREE (cstat, int);
+
+    del = CC_SAFE_MALLOC (lp->graph.ecount, int);
+    if (!del) {
+        fprintf (stderr, "out of memory in age_edges\n");
+        return 1;
+    }
+    for (i = 0, j = 0; i < lp->graph.ecount; i++) {
+        if (lp->graph.edges[i].ends[1] != 0 ||
+            lp->graph.edges[i].ends[0] != 0) {
+            lp->graph.edges[j] = lp->graph.edges[i];
+            j++;
+            del[i] = 0;
+        } else {
+            del[i] = 1;
+        }
+    }
+    if (j < lp->graph.ecount) {
+        rval = lp_delete_var_set (lp, del);
+        if (rval) {
+            fprintf (stderr, "lp_delete_var_set failed\n");
+            CC_FREE (del, int);
+            return rval;
+        }
+    }
+    CC_FREE (del, int);
+
+    *ndeleted = lp->graph.ecount - j;
+    lp->graph.ecount = j;
+    rval = CCtsp_build_lpadj (&lp->graph, 0, lp->graph.ecount);
+    if (rval) {
+        fprintf (stderr, "CCtsp_build_lpadj failed\n");
+        return rval;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int get_pi (CCtsp_lp *lp, double *node_pi, double *cut_pi)
+#else
+static int get_pi (lp, node_pi, cut_pi)
+CCtsp_lp *lp;
+double *node_pi;
+double *cut_pi;
+#endif
+{
+    int rval;
+
+    if (node_pi) {
+        rval = CClp_pi_range (&lp->lp, node_pi, 0, lp->graph.ncount-1);
+        if (rval) {
+            fprintf (stderr, "CClp_pi_range failed\n");
+            return 1;
+        }
+    }
+    if (cut_pi) {
+        rval = CClp_pi_range (&lp->lp, cut_pi, lp->graph.ncount,
+                              lp->graph.ncount + lp->cuts.cutcount - 1);
+        if (rval) {
+            fprintf (stderr, "CClp_pi_range failed\n");
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_add_multiple_rows (CCtsp_lp *lp, CCtsp_lprow *cr)
+#else
+int CCtsp_add_multiple_rows (lp, cr)
+CCtsp_lp *lp;
+CCtsp_lprow *cr;
+#endif
+{
+    int rval = 0;
+
+    if (!cr->rowcnt)
+        return 0;
+
+    rval = CClp_addrows (&lp->lp, cr->rowcnt, cr->nzcnt, cr->rhs, cr->sense,
+                         cr->begin, cr->indices, cr->entries);
+    if (rval) {
+        fprintf (stderr, "Couldn't add rows into LP\n");
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int addrow_to_list (int nzcnt, double drhs, char sense,
+        int *rmatind, double *rmatval, CCtsp_lprow *cr)
+#else
+static int addrow_to_list (nzcnt, drhs, sense, rmatind, rmatval, cr)
+int nzcnt;
+double drhs;
+char sense;
+int *rmatind;
+double *rmatval;
+CCtsp_lprow *cr;
+#endif
+{
+    int i, rval;
+    int *ip;
+    double *dp;
+    double rhs = drhs; /* copy to work around problem with sun cc -dalign */
+
+    rval = CCutil_reallocrus_count ((void **) &(cr->sense), cr->rowcnt + 1,
+                             sizeof (char));
+    if (rval) goto CLEANUP;
+    rval = CCutil_reallocrus_count ((void **) &(cr->rhs), cr->rowcnt + 1,
+                             sizeof (double));
+    if (rval) goto CLEANUP;
+    rval = CCutil_reallocrus_count ((void **) &(cr->begin), cr->rowcnt + 1,
+                             sizeof (int));
+    if (rval) goto CLEANUP;
+
+    if (nzcnt + cr->nzcnt > cr->indexspace) {
+        rval = CCutil_reallocrus_scale ((void **) &(cr->indices),
+               &(cr->indexspace), nzcnt + cr->nzcnt, 1.3, sizeof (int));
+        if (rval) goto CLEANUP;
+    }
+    if (nzcnt + cr->nzcnt > cr->entryspace) {
+        rval = CCutil_reallocrus_scale ((void **) &(cr->entries),
+               &(cr->entryspace), nzcnt + cr->nzcnt, 1.3, sizeof (double));
+        if (rval) goto CLEANUP;
+    }
+
+    cr->sense[cr->rowcnt] = sense;
+    cr->rhs[cr->rowcnt] = rhs;
+    cr->begin[cr->rowcnt] = cr->nzcnt;
+    cr->rowcnt++;
+
+    ip = cr->indices + cr->nzcnt;
+    dp = cr->entries + cr->nzcnt;
+    for (i = 0; i < nzcnt; i++) {
+        ip[i] = rmatind[i];
+        dp[i] = rmatval[i];
+    }
+    cr->nzcnt += nzcnt;
+
+    return 0;
+
+CLEANUP:
+
+    fprintf (stderr, "out of memory in addrow_to_list\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lp_addcols (CCtsp_lp *lp, int ncols, int nzcnt,
+        double *obj, int *matbeg, int *matind, double *matval,
+        double *lb, double *ub)
+#else
+static int lp_addcols (lp, ncols, nzcnt, obj, matbeg, matind, matval, lb, ub)
+CCtsp_lp *lp;
+int ncols;
+int nzcnt;
+double *obj;
+int *matbeg;
+int *matind;
+double *matval;
+double *lb;
+double *ub;
+#endif
+{
+    int rval = 0;
+
+    rval = CClp_addcols (&lp->lp, ncols, nzcnt, obj,
+                         matbeg, matind, matval, lb, ub);
+    if (rval) {
+        fprintf (stderr, "Couldn't add columns into LP\n");
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_delete_cut (CCtsp_lp *lp, int i)
+#else
+int CCtsp_delete_cut (lp, i)
+CCtsp_lp *lp;
+int i;
+#endif
+{
+    int rval = 0;
+    rval = CClp_delete_row(&lp->lp, lp->graph.ncount + i);
+    if (rval) fprintf (stderr, "CClp_delete_row failed\n");
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lp_delete_cut_set (CCtsp_lp *lp, int *del)
+#else
+static int lp_delete_cut_set (lp, del)
+CCtsp_lp *lp;
+int *del;
+#endif
+{
+    int i, rval = 0;
+    int *delstat = (int *) NULL;
+    int ncount = lp->graph.ncount;
+    int cutcount = lp->cuts.cutcount;
+
+    delstat = CC_SAFE_MALLOC (ncount + cutcount, int);
+    if (!delstat) {
+        fprintf (stderr, "out of memory in lp_delete_cut_set\n");
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        delstat[i] = 0;
+    for (i = 0; i < cutcount; i++)
+        delstat[i + ncount] = del[i];
+
+    rval = CClp_delete_set_of_rows (&lp->lp, delstat);
+    if (rval) {
+        fprintf (stderr, "CClp_delete_set_of_rows failed\n");
+    }
+
+    CC_FREE (delstat, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int lp_delete_var_set (CCtsp_lp *lp, int *del)
+#else
+static int lp_delete_var_set (lp, del)
+CCtsp_lp *lp;
+int *del;
+#endif
+{
+    int rval = 0;
+
+    rval = CClp_delete_set_of_columns (&lp->lp, del);
+    if (rval) {
+        fprintf (stderr, "CClp_delete_set_of_columns failed\n");
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_write_probfile_sav (CCtsp_lp *lp)
+#else
+int CCtsp_write_probfile_sav (lp)
+CCtsp_lp *lp;
+#endif
+{
+    return write_probfile (lp, 1);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_write_probfile_id (CCtsp_lp *lp)
+#else
+int CCtsp_write_probfile_id (lp)
+CCtsp_lp *lp;
+#endif
+{
+    return write_probfile (lp, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int write_probfile (CCtsp_lp *lp, int saveit)
+#else
+static int write_probfile (lp, saveit)
+CCtsp_lp *lp;
+int saveit;  /* set to 1 to write to prob.sav */
+#endif
+{
+    CCtsp_PROB_FILE *p = (CCtsp_PROB_FILE *) NULL;
+    char fname[1024];
+    int len;
+
+    if (!lp) {
+        fprintf (stderr, "CCtsp_write_probfile called without an lp\n");
+        return 1;
+    }
+    if (!lp->graph.ecount) {
+        fprintf (stderr, "CCtsp_write_probfile called with an edgeset\n");
+        return 1;
+    }
+
+    if (saveit) {
+        len = strlen (lp->name);
+        if (len + 40 > 1024) {
+            sprintf (fname, "probfile.sav");
+        } else {
+            sprintf (fname, "%s.sav", lp->name);
+        }
+
+        p = CCtsp_prob_write_name (fname, lp->name);
+        if (!p) {
+            fprintf (stderr, "CCtsp_prob_write_name failed\n");
+            return 1;
+        }
+    } else {
+        p = CCtsp_prob_write (lp->name, lp->id);
+        if (!p) {
+            fprintf (stderr, "CCtsp_prob_write failed\n");
+            return 1;
+        }
+    }
+
+    if (CCtsp_prob_putname (p, lp->name)) goto CLEANUP;
+    if (CCtsp_prob_putid (p, lp->id)) goto CLEANUP;
+    if (CCtsp_prob_putparent (p, lp->parent_id)) goto CLEANUP;
+    if (CCtsp_prob_putnnodes (p, lp->graph.ncount)) goto CLEANUP;
+    if (CCtsp_prob_putub (p, lp->upperbound)) goto CLEANUP;
+    if (CCtsp_prob_putlb (p, lp->lowerbound)) goto CLEANUP;
+    if (CCtsp_prob_putexactlb (p, lp->exact_lowerbound)) goto CLEANUP;
+    if (CCtsp_prob_putinfeasible (p, lp->infeasible)) goto CLEANUP;
+
+    {
+        int *elist = (int *) NULL;
+        int *elen = (int *) NULL;
+        int ecount = lp->graph.ecount;
+        int i;
+
+        elist = CC_SAFE_MALLOC (2 * ecount, int);
+        elen = CC_SAFE_MALLOC (ecount, int);
+
+        if (!elist || !elen) {
+            fprintf (stderr, "out of memory in CCtsp_write_probfile\n");
+            CC_IFFREE (elist, int);
+            CC_IFFREE (elen, int);
+            goto CLEANUP;
+        }
+
+        for (i = 0; i < ecount; i++) {
+            elist[2*i]     = lp->graph.edges[i].ends[0];
+            elist[2*i + 1] = lp->graph.edges[i].ends[1];
+            elen[i]        = lp->graph.edges[i].len;
+        }
+
+        if (CCtsp_prob_putedges (p, ecount, elist, elen)) {
+            CC_FREE (elist, int);
+            CC_FREE (elen, int);
+            goto CLEANUP;
+        }
+        CC_FREE (elist, int);
+        CC_FREE (elen, int);
+    }
+
+    if (CCtsp_prob_putcuts (p, (CC_SFILE *) NULL, &(lp->cuts))) goto CLEANUP;
+
+    {
+        CClpbasis b;
+        int ccount = lp->graph.ecount;
+        int rcount = lp->graph.ncount + lp->cuts.cutcount;
+
+        CClp_init_basis (&b);
+
+        if (CClp_get_basis_and_norms (&lp->lp, &b)) {
+            printf ("No basis/norms to add to probfile\n");
+            fflush (stdout);
+        } else {
+            if (CCtsp_prob_putbasis (p, ccount, rcount, b.cstat, b.rstat)) {
+                CClp_free_basis (&b);
+                goto CLEANUP;
+            }
+            if (CCtsp_prob_putnorms (p, rcount, b.dnorm)) {
+                CClp_free_basis (&b);
+                goto CLEANUP;
+            }
+        }
+        CClp_free_basis (&b);
+    }
+
+    if (lp->nfixededges > 0) {
+        if (CCtsp_prob_putfixed (p, lp->nfixededges, lp->fixededges)) {
+            fprintf (stderr, "CCtsp_prob_putfixed failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (lp->fullcount > 0 && lp->full_edges_valid) {
+        if (CCtsp_prob_putfulladj (p, lp->graph.ncount, lp->fullcount,
+                              lp->fulladj)) {
+            fprintf (stderr, "CCtsp_prob_putfulladj failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (lp->exact_dual) {
+        if (CCtsp_prob_putexactdual (p, lp->exact_dual, lp->graph.ncount)) {
+            fprintf (stderr, "CCtsp_prob_putexact_dual failed\n");
+            goto CLEANUP;
+        }
+    }
+
+    if (CCtsp_prob_puthistory (p, lp->branchdepth, lp->branchhistory)) {
+        fprintf (stderr, "CCtsp_prob_puthistory failed\n");
+        goto CLEANUP;
+    }
+
+    if (CCtsp_prob_wclose (p)) {
+        fprintf (stderr, "CCtsp_prob_wclose failed\n");
+        return 1;
+    }
+
+    return 0;
+
+CLEANUP:
+
+    fprintf (stderr, "CCtsp_write_probfile failed\n");
+
+    if (p)
+        CCtsp_prob_wclose (p);
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_read_probfile (CCtsp_lp *lp, char *fname, int ncount)
+#else
+int CCtsp_read_probfile (lp, fname, ncount)
+CCtsp_lp *lp;
+char *fname;
+int ncount;
+#endif
+{
+    CCtsp_PROB_FILE *p = (CCtsp_PROB_FILE *) NULL;
+
+    p = CCtsp_prob_read_name (fname);
+    if (!p) {
+        fprintf (stderr, "could not open %s for reading\n", fname);
+        return 1;
+    }
+
+    return read_probfile (lp, p, ncount);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_read_probfile_id (CCtsp_lp *lp, char *name, int id, int ncount)
+#else
+int CCtsp_read_probfile_id (lp, name, id, ncount)
+CCtsp_lp *lp;
+char *name;
+int id;
+int ncount;
+#endif
+{
+    CCtsp_PROB_FILE *p = (CCtsp_PROB_FILE *) NULL;
+
+    p = CCtsp_prob_read (name, id);
+    if (!p) {
+        fprintf (stderr, "could not open %s for reading\n", name);
+        return 1;
+    }
+
+    return read_probfile (lp, p, ncount);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int read_probfile (CCtsp_lp *lp, CCtsp_PROB_FILE *p, int ncount)
+#else
+static int read_probfile (lp, p, ncount)
+CCtsp_lp *lp;
+CCtsp_PROB_FILE *p;
+int ncount;
+#endif
+{
+    int tncount, ecount, ccount, rcount;
+    int *elist = (int *) NULL;
+    int *elen = (int *) NULL;
+    int i, k;
+    int rval = 0;
+    CClpbasis *b = (CClpbasis *) NULL;
+
+    rval = CCtsp_init_cliquehash (&lp->cuts, 2*ncount);
+    if (rval) return rval;
+
+    lp->name = CC_SAFE_MALLOC (CCtsp_PROB_FILE_NAME_LEN, char);
+    if (!lp->name) {
+        fprintf (stderr, "out of memory in read_probfile\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+    rval = CCtsp_prob_getname (p, lp->name);
+    if (rval == -1) goto CLEANUP;
+    printf ("Prob Name: %s\n", lp->name); fflush (stdout);
+
+    rval = CCtsp_prob_getid (p, &(lp->id));
+    if (rval == -1) goto CLEANUP;
+    printf ("Prob ID: %d\n", lp->id); fflush (stdout);
+
+    rval = CCtsp_prob_getparent (p, &(lp->parent_id));
+    if (rval == -1) goto CLEANUP;
+    printf ("Prob Parent ID: %d\n", lp->parent_id); fflush (stdout);
+
+    rval = CCtsp_prob_getub (p, &(lp->upperbound));
+    if (rval == -1) goto CLEANUP;
+    rval = CCtsp_prob_getlb (p, &(lp->lowerbound));
+    if (rval == -1) goto CLEANUP;
+    printf ("Prob Bounds: (%f, %f)\n", lp->lowerbound, lp->upperbound);
+    fflush (stdout);
+
+    rval = CCtsp_prob_getexactlb (p, &(lp->exact_lowerbound));
+    if (rval == -1) goto CLEANUP;
+    if (CCbigguy_cmp (lp->exact_lowerbound, CCbigguy_MINBIGGUY) != 0) {
+        printf ("Prob Exact Lowerbound: %f\n",
+                             CCbigguy_bigguytod (lp->exact_lowerbound));
+        fflush (stdout);
+    }
+
+    rval = CCtsp_prob_getinfeasible (p, &(lp->infeasible));
+    if (rval == -1) goto CLEANUP;
+    if (lp->infeasible) {
+        printf ("Prob stored is tagged as infeasible\n");
+        fflush (stdout);
+    }
+
+    rval = CCtsp_prob_getnnodes (p, &tncount);
+    if (rval == -1) goto CLEANUP;
+    if (!rval) {
+        if (tncount != ncount) {
+            fprintf (stderr, "node counts differ in probfile and input\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_prob_getcuts (p, (CC_SFILE *) NULL, &(lp->cuts));
+    if (rval == -1) goto CLEANUP;
+
+    rval = CCtsp_prob_getedges (p, &ecount, &elist, &elen);
+    if (rval == -1) goto CLEANUP;
+    if (!rval) {
+        rval = CCtsp_build_lpgraph (&lp->graph, ncount, ecount, elist, elen);
+        if (rval) goto CLEANUP;
+        rval = CCtsp_build_lpadj (&lp->graph, 0, ecount);
+        if (rval) goto CLEANUP;
+        CC_FREE (elist, int);
+        CC_FREE (elen, int);
+    }
+
+    rval = CCtsp_prob_getfixed (p, &(lp->nfixededges), &(lp->fixededges));
+    if (rval == -1) goto CLEANUP;
+    if (!rval) {
+        printf ("Read %d LP fixed edges\n", lp->nfixededges); fflush (stdout);
+        for (i = 0; i < lp->nfixededges; i++) {
+            k = CCtsp_find_edge (&(lp->graph), lp->fixededges[2*i],
+                                               lp->fixededges[2*i+1]);
+            if (k != -1) {
+                lp->graph.edges[k].fixed = 1;
+            } else {
+                printf ("WARNING: File want's to fix a non-lp edge\n");
+                fflush (stdout);
+            }
+        }
+    }
+
+    b = CC_SAFE_MALLOC (1, CClpbasis);
+    if (!b) {
+        fprintf (stderr, "out of memory in read_probfile\n");
+        rval = 1; goto CLEANUP;
+    }
+    CClp_init_basis (b);
+    lp->basis = b;
+
+    rval = CCtsp_prob_getbasis (p, &ccount, &rcount, &b->cstat, &b->rstat);
+    if (rval == -1) goto CLEANUP;
+    if (!rval) {
+        if (ccount !=  lp->graph.ecount) {
+            fprintf (stderr, "column counts differs in basis probfile\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+        if (rcount != lp->graph.ncount + lp->cuts.cutcount) {
+            fprintf (stderr, "rcount differs in basis probfile\n");
+            rval = 1;
+            goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_prob_getnorms (p, &rcount, &b->dnorm);
+    if (rval == -1) goto CLEANUP;
+    if (!rval) {
+        if (rcount != lp->graph.ncount + lp->cuts.cutcount) {
+            fprintf (stderr, "rcount differs in norms probfile\n");
+            rval = 1; goto CLEANUP;
+        }
+    }
+
+    rval = CCtsp_prob_getfulladj (p, ncount, &(lp->fullcount),
+                             &(lp->fulladj), &(lp->fulladjspace));
+    if (rval == -1) {
+        fprintf (stderr, "CCtsp_prob_getfulladj failed\n");
+        goto CLEANUP;
+    }
+    if (!rval) {
+        printf ("Read LP full adj\n"); fflush (stdout);
+        if (lp->fullcount) {
+            lp->full_edges_valid = 1;
+        }
+    }
+
+    rval = CCtsp_prob_getexactdual (p, ncount, &(lp->exact_dual));
+    if (rval == -1) {
+        fprintf (stderr, "CCtsp_prob_getexactdual failed\n");
+        goto CLEANUP;
+    }
+    if (!rval) {
+        printf ("Read LP exact dual values\n"); fflush (stdout);
+    }
+
+    rval = CCtsp_prob_gethistory (p, &lp->branchdepth, &lp->branchhistory);
+    if (rval == -1) {
+        fprintf (stderr, "CCtsp_prob_gethistory failed\n");
+        goto CLEANUP;
+    }
+    if (!rval) {
+        CCtsp_print_branchhistory (lp);
+    }
+
+    rval = 0;
+
+
+CLEANUP:
+
+    if (CCtsp_prob_rclose (p)) {
+        fprintf (stderr, "CCtsp_prob_rclose failed\n");
+        return 1;
+    }
+
+    printf ("Done with read_probfile\n"); fflush (stdout);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_dump_x (CCtsp_lp *lp, char *fname)
+#else
+int CCtsp_dump_x (lp, fname)
+CCtsp_lp *lp;
+char *fname;
+#endif
+{
+    int i, xcount;
+    int nonzero = 0;
+    int *xlist = (int *) NULL;
+    double *x  = (double *) NULL;
+    FILE *out;
+    int rval = 0;
+
+    printf ("Dumping the x vector to %s ... ", fname); fflush (stdout);
+
+    rval = CCtsp_get_lp_result (lp, (double *) NULL, (double *) NULL, &xcount,
+             &xlist, &x, (double **) NULL, (double **) NULL, (double **) NULL);
+    if (rval) {
+        fprintf (stderr, "CCtsp_get_lp_result failed\n"); return rval;
+    }
+
+    for (i = 0; i < xcount; i++) {
+        if (x[i] > CCtsp_INTTOL) {
+            nonzero++;
+        }
+    }
+
+    out = fopen (fname, "w");
+    if (out == (FILE *) NULL) {
+        fprintf (stderr, "could not open %s for writing\n", fname);
+        rval = 1; goto CLEANUP;
+    }
+
+    fprintf (out, "%d %d\n", lp->graph.ncount, nonzero);
+    for (i = 0; i < xcount; i++) {
+        if (x[i] > CCtsp_INTTOL) {
+            fprintf (out, "%d %d %f\n", lp->perm[xlist[2*i]],
+                                        lp->perm[ xlist[2*i+1]],
+                                        x[i]);
+        }
+    }
+    fclose (out);
+    printf ("DONE\n"); fflush (stdout);
+
+CLEANUP:
+
+    CC_IFFREE (xlist, int);
+    CC_IFFREE (x, double);
+    return rval;
+}
+
diff --git a/contrib/blossom/concorde97/TSP/xtour.c b/contrib/blossom/concorde97/TSP/xtour.c
new file mode 100644
index 0000000000000000000000000000000000000000..be77224864e183e12383bc49e04c2ab9397119ce
--- /dev/null
+++ b/contrib/blossom/concorde97/TSP/xtour.c
@@ -0,0 +1,234 @@
+/***************************************************************************/
+/*                                                                         */
+/*              ROUTINES FOR CONSTRUCTING TOURS FROM x-VECTORS             */
+/*                                                                         */
+/*                               TSP CODE                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: July 21, 1997                                                    */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCtsp_x_greedy_tour (CCdatagroup *dat, int ncount, int ecount,   */
+/*            int *elist, double *x, int *cyc, double *val)                */
+/*     FINDS a tour by adding in edges by nonincreasing x-value.           */
+/*      -cyc should be an array of length at least ncount                  */
+/*      -val returns the length of the tour                                */
+/*                                                                         */
+/*    int CCtsp_x_greedy_tour_lk (CCdatagroup *dat, int ncount, int ecount,*/
+/*            int *elist, double *x, int *cyc, double *val)                */
+/*     FINDS the x-greedy tour then calls a short LK.                      */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "edgegen.h"
+#include "linkern.h"
+#include "tsp.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    update_tail (int *tail, int a, int b);
+
+#else
+
+static void
+    update_tail ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_x_greedy_tour_lk (CCdatagroup *dat, int ncount, int ecount,
+        int *elist, double *x, int *cyc, double *val)
+#else
+int CCtsp_x_greedy_tour_lk (dat, ncount, ecount, elist, x, cyc, val)
+CCdatagroup *dat;
+int ncount, ecount;
+int *elist;
+double *x;
+int *cyc;
+double *val;
+#endif
+{
+    int rval = 0;
+    int *gcyc = (int *) NULL;
+    int *tlist = (int *) NULL;
+    int tcount;
+    double gval;
+    CCedgegengroup plan;
+
+    *val = 1e30;
+    if (!dat) {
+        fprintf (stderr, "no dat in CCtsp_x_greedy_tour_lk\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    gcyc = CC_SAFE_MALLOC (ncount, int);
+    if (!gcyc) {
+        fprintf (stderr, "out of memory in CCtsp_x_greedy_tour_lk\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    rval = CCtsp_x_greedy_tour (dat, ncount, ecount, elist, x, gcyc,
+                 &gval);
+    if (rval) {
+        fprintf (stderr, "CCtsp_x_greedy_tour failed\n"); goto CLEANUP;
+    }
+
+    CCedgegen_init_edgegengroup (&plan);
+    plan.quadnearest = 2;
+
+    rval = CCedgegen_edges (&plan, ncount, dat, (double *) NULL, &tcount,
+                            &tlist);
+    if (rval) {
+        fprintf (stderr, "CCedgegen_edges failed\n"); goto CLEANUP;
+    }
+
+    rval = CClinkern_tour (ncount, dat, tcount, tlist, ncount,
+             ncount > 1000 ? 500 : ncount/2, gcyc, cyc, val, 0, 0.0,
+             0.0, (char *) NULL);
+    if (rval) {
+        fprintf (stderr, "CClinkern_tour failed\n"); goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (tlist, int);
+    CC_IFFREE (gcyc, int);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCtsp_x_greedy_tour (CCdatagroup *dat, int ncount, int ecount, int *elist,
+        double *x, int *cyc, double *val)
+#else
+int CCtsp_x_greedy_tour (dat, ncount, ecount, elist, x, cyc, val)
+CCdatagroup *dat;
+int ncount, ecount;
+int *elist;
+double *x;
+int *cyc;
+double *val;
+#endif
+{
+    int rval = 0;
+    int tcount = 0;
+    int i, a, b;
+    double szeit = CCutil_zeit ();
+    double len;
+    int *perm    = (int *) NULL;
+    int *tail    = (int *) NULL;
+    int *tcyc    = (int *) NULL;
+    char *degree = (char *) NULL;
+
+    printf ("CCtsp_x_greedy_tour ...\n"); fflush (stdout);
+
+    *val = 1e30;
+    if (!dat) {
+        fprintf (stderr, "no dat in CCtsp_x_greedy_tour\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    perm     = CC_SAFE_MALLOC (ecount, int);
+    degree   = CC_SAFE_MALLOC (ncount, char);
+    tail     = CC_SAFE_MALLOC (ncount, int);
+    tcyc     = CC_SAFE_MALLOC (2 * ncount, int);
+    if (!perm || !degree || !tail || !tcyc) {
+        fprintf (stderr, "out of memory in CCtsp_x_greedy_tour\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        degree[i] = 0;
+        tail[i]   = -1;
+    }
+    for (i = 0; i < ecount; i++) {
+        perm[i] = i;
+    }
+
+    CCutil_double_perm_quicksort (perm, x, ecount);
+    len = 0;
+    for (i = ecount - 1; i >= 0; i--) {
+        a = elist[2*perm[i]];
+        b = elist[(2*perm[i]) + 1];
+        if (degree[a] != 2 && degree[b] != 2 && tail[a] != b) {
+            /* add (a, b) to the tour */
+            tcyc[tcount++] = a;
+            tcyc[tcount++] = b;
+            len += (double) CCutil_dat_edgelen (a, b, dat);
+            degree[a]++;
+            degree[b]++;
+            update_tail (tail, a, b);
+        }
+    }
+
+    printf ("%d edges in x-tour\n", tcount / 2); fflush (stdout);
+    a = 0;
+    b = 0;
+    while (tcount < (2*ncount - 2)) {
+        for (; degree[a] == 2; a++);
+        for (b = a + 1; degree[b] == 2 || tail[a] == b; b++);
+        tcyc[tcount++] = a;
+        tcyc[tcount++] = b;
+        degree[a]++;
+        degree[b]++;
+        update_tail (tail, a, b);
+        len += (double) CCutil_dat_edgelen (a, b, dat);
+    }
+
+    if (tcount < 2*ncount) {
+        for (a = 0; degree[a] != 1; a++);
+        for (b = a + 1; degree[b] != 1; b++);
+        tcyc[tcount++] = a;
+        tcyc[tcount++] = b;
+        len += (double) CCutil_dat_edgelen (a, b, dat);
+    }
+
+    printf ("tour length: %.2f (%.2f seconds)\n", len, CCutil_zeit () - szeit);
+    fflush (stdout);
+    *val = len;
+
+    rval = CCutil_edge_to_cycle (ncount, tcyc, cyc);
+    if (rval) {
+        fprintf (stderr, "CCutil_edge_to_cycle failed\n");
+        goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (perm, int);
+    CC_IFFREE (tail, int);
+    CC_IFFREE (tcyc, int);
+    CC_IFFREE (degree, char);
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void update_tail (int *tail, int a, int b)
+#else
+static void update_tail (tail, a, b)
+int *tail;
+int a, b;
+#endif
+{
+    if (tail[a] == -1) {
+        if (tail[b] == -1) {
+            tail[a] = b;
+            tail[b] = a;
+        } else {
+            tail[a] = tail[b];
+            tail[tail[b]] = a;
+        }
+    } else if (tail[b] == -1) {
+        tail[tail[a]] = b;
+        tail[b] = tail[a];
+    } else {
+        tail[tail[a]] = tail[b];
+        tail[tail[b]] = tail[a];
+    }
+}
diff --git a/contrib/blossom/concorde97/UTIL/Makefile b/contrib/blossom/concorde97/UTIL/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..eafa97131db72be6209dff6d7329b82c7fd7ae53
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/Makefile
@@ -0,0 +1,40 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=util.a
+LIBSRCS=allocrus.c bgetopt.c  dheaps_i.c edg2cyc.c  edgelen.c  fastread.c \
+        getdata.c  safe_io.c  sortrus.c  urandom.c  util.c     zeit.c     \
+        genhash.c  priority.c
+ALLSRCS=$(LIBSRCS)
+
+all: $(LIB)
+
+clean:
+	-rm -f *.$o $(LIB)
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+allocrus.$o: allocrus.c $(I)/machdefs.h $(I)/util.h     
+bgetopt.$o:  bgetopt.c  $(I)/machdefs.h $(I)/util.h     
+dheaps_i.$o: dheaps_i.c $(I)/machdefs.h $(I)/util.h     
+edg2cyc.$o:  edg2cyc.c  $(I)/machdefs.h $(I)/util.h     
+edgelen.$o:  edgelen.c  $(I)/machdefs.h $(I)/util.h     
+fastread.$o: fastread.c $(I)/machdefs.h $(I)/util.h     
+genhash.$o:  genhash.c  $(I)/machdefs.h $(I)/util.h     
+getdata.$o:  getdata.c  $(I)/machdefs.h $(I)/util.h     
+priority.$o: priority.c $(I)/machdefs.h $(I)/util.h     
+safe_io.$o:  safe_io.c  $(I)/machdefs.h $(I)/util.h     
+sortrus.$o:  sortrus.c  $(I)/machdefs.h $(I)/util.h     
+urandom.$o:  urandom.c  $(I)/machdefs.h $(I)/util.h     
+util.$o:     util.c     $(I)/machdefs.h $(I)/macrorus.h $(I)/util.h     
+zeit.$o:     zeit.c     $(I)/machdefs.h $(I)/util.h     
diff --git a/contrib/blossom/concorde97/UTIL/allocrus.c b/contrib/blossom/concorde97/UTIL/allocrus.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f800b4804ffbf328dc12b6b71d5ae62c9322a15
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/allocrus.c
@@ -0,0 +1,400 @@
+/***************************************************************************/
+/*                                                                         */
+/*                   MEMORY ALLOCATION MACROS                              */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 2, 1995 (cofeb16)                                       */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    void *CCutil_allocrus (unsigned int size)                            */
+/*         RETURNS a pointer to an allocated block of "size" memory.       */
+/*                                                                         */
+/*    void CCutil_freerus (void *ptr)                                      */
+/*         FREES ptr.                                                      */
+/*                                                                         */
+/*    void *CCutil_reallocrus (void *ptr, unsigned int size)               */
+/*         REALLOCS ptr to size bytes.                                     */
+/*                                                                         */
+/*    int CCutil_reallocrus_scale (void **pptr, int *pnnum, int count,     */
+/*            double scale, unsigned int size)                             */
+/*         void **pptr (a reference to the pointer to the allocated space) */
+/*         int *pnnum (a reference to the number of objects in the         */
+/*                     allocated space)                                    */
+/*         int count (a minimum value for the new nnum)                    */
+/*         double scale (a scale factor to apply to nnum)                  */
+/*         int size (the size of objects to be realloced)                  */
+/*         RETURNS 0 if *pptr was successfully changed to point to at      */
+/*                 least max(*pnnum*scale, *pnnum+1000, count) objects.    */
+/*                 *pnnum is changed to the new object count.              */
+/*                 Otherwise, prints an error message, leaves *pptr and    */
+/*                 *pnnum alone, and returns nonzero.                      */
+/*                                                                         */
+/*    int CCutil_reallocrus_count (void **pptr, int count,                 */
+/*            unsigned int size)                                           */
+/*         void **pptr (a reference to the pointer to the allocated space) */
+/*         int count (number of objects to be realloced)                   */
+/*         int size (the size of the objects to be realloced)              */
+/*         RETURNS 0 is successful, and 1 if the realloc failed.           */
+/*                                                                         */
+/*                                                                         */
+/*    CCbigchunkptr *CCutil_bigchunkalloc (void)                           */
+/*         RETURNS a CCbigchunkptr with the "this" field loaded with a     */
+/*                 a pointer to a bigchunk of memory.                      */
+/*    CCutil_bigchunkfree (CCbigchunkptr *bp)                              */
+/*         ACTION: Gives the CCbigchunkptr back to the global supply.      */
+/*    int CCutil_bigchunk_free_world (void)                                */
+/*         ACTION: Gives the global supply of CCbigchunkptrs and bigchunks */
+/*                 back to the system. It returns a nonzero value if there */
+/*                 was an error.                                           */
+/*                                                                         */
+/*    NOTES:                                                               */
+/*       Functions prototyped in allocrus.h.                               */
+/*       The idea is to use bigchunks (the size of a bigchunk is defined   */
+/*       by BIGCHUNK in allocrus.h) to supply local routines with memory   */
+/*       for ptrs, so the memory can be shared with other local routines.  */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+static CCbigchunkptr *local_bigchunk_list = (CCbigchunkptr *) NULL;
+static CCbigchunkptr *bigchunk_list = (CCbigchunkptr *) NULL;
+static CCbigchunkptr *bigchunk_freelist = (CCbigchunkptr *) NULL;
+static CCbigchunkptr *bigchunkptr_freelist = (CCbigchunkptr *) NULL;
+
+static int bigchunktotal = 0;
+static int bigchunkreserve = 0;
+static int bigchunkptrtotal = 0;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    bigchunkptrfree (CCbigchunkptr *bp);
+
+static CCbigchunkptr
+    *bigchunkptralloc (void);
+
+#else
+
+static void
+    bigchunkptrfree ();
+
+static CCbigchunkptr
+    *bigchunkptralloc ();
+
+#endif
+
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void *CCutil_allocrus (unsigned int size)
+#else
+void *CCutil_allocrus (size)
+unsigned int size;
+#endif
+{
+    void *mem = (void *) NULL;
+
+    if (size == 0) {
+        fprintf (stderr, "Warning: 0 bytes allocated\n");
+    }
+
+    mem = (void *) malloc (size);
+    if (mem == (void *) NULL) {
+        fprintf (stderr, "Out of memory. Asked for %d bytes\n", size);
+    }
+    return mem;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_freerus (void *p)
+#else
+void CCutil_freerus (p)
+void *p;
+#endif
+{
+    if (!p) {
+        fprintf (stderr, "Warning: null pointer freed\n");
+        return;
+    }
+
+    free (p);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void *CCutil_reallocrus (void *ptr, unsigned int size)
+#else
+void *CCutil_reallocrus (ptr, size)
+void *ptr;
+unsigned int size;
+#endif
+{
+    void *newptr;
+
+    if (!ptr) {
+        return CCutil_allocrus (size);
+    } else {
+        newptr = (void *) realloc (ptr, size);
+        if (!newptr) {
+            fprintf (stderr, "Out of memory.  Tried to grow %d bytes\n", size);
+        }
+        return newptr;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_reallocrus_scale (void **pptr, int *pnnum, int count, double scale,
+        unsigned int size)
+#else
+int CCutil_reallocrus_scale (pptr, pnnum, count, scale, size)
+void **pptr;
+int *pnnum;
+int count;
+double scale;
+unsigned int size;
+#endif
+{
+    int newsize = (int) (((double) *pnnum) * scale);
+    void *p;
+
+    if (newsize < *pnnum+1000) newsize = *pnnum+1000;
+    if (newsize < count) newsize = count;
+    p = CCutil_reallocrus (*pptr, newsize * size);
+    if (!p) {
+        return 1;
+    } else {
+        *pptr = p;
+        *pnnum = newsize;
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_reallocrus_count (void **pptr, int count, unsigned int size)
+#else
+int CCutil_reallocrus_count (pptr, count, size)
+void **pptr;
+int count;
+unsigned int size;
+#endif
+{
+    void *p = CCutil_reallocrus (*pptr, count * size);
+
+    if (!p) {
+        return 1;
+    } else {
+        *pptr = p;
+        return 0;
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+CCbigchunkptr *CCutil_bigchunkalloc (void)
+#else
+CCbigchunkptr *CCutil_bigchunkalloc ()
+#endif
+{
+    void *p;
+    CCbigchunkptr *bp, *cp;
+
+    if (!bigchunk_freelist) {
+        p = (void *) CCutil_allocrus (CC_BIGCHUNK);
+        if (!p)
+            return (CCbigchunkptr *) NULL;
+        bp = bigchunkptralloc ();
+        if (!bp) {
+            CC_FREE (p, void);
+            return (CCbigchunkptr *) NULL;
+        }
+        cp = bigchunkptralloc ();
+        if (!cp) {
+            CC_FREE (p, void);
+            bigchunkptrfree (bp);
+            return (CCbigchunkptr *) NULL;
+        }
+        bp->this = p;
+        cp->this = p;
+        cp->next = bigchunk_list;
+        bigchunk_list = cp;
+        bigchunktotal++;
+        return bp;
+    } else {
+        bp = bigchunk_freelist;
+        bigchunk_freelist = bp->next;
+        bigchunkreserve--;
+        return bp;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_bigchunkfree (CCbigchunkptr *bp)
+#else
+void CCutil_bigchunkfree (bp)
+CCbigchunkptr *bp;
+#endif
+{
+    bp->next = bigchunk_freelist;
+    bigchunk_freelist = bp;
+    bigchunkreserve++;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_bigchunkquery (int *total, int *reserve)
+#else
+void CCutil_bigchunkquery (total, reserve)
+int *total, *reserve;
+#endif
+{
+    *total = bigchunktotal;
+    *reserve = bigchunkreserve;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_bigchunk_free_world (void)
+#else
+int CCutil_bigchunk_free_world ()
+#endif
+{
+    int duplicates = 0, localcount, bpcount, i;
+    void **tosslist;
+    CCbigchunkptr *bp, *bpnext;
+
+    /* First some checking, to see that the routines were used properly */
+
+    if (bigchunkreserve != bigchunktotal) {
+        fprintf (stderr, "WARNING: %d outstanding bigchunks\n",
+                 bigchunktotal - bigchunkreserve);
+    }
+    for (bp = bigchunk_freelist; bp; bp = bp->next)
+        bp->this = (void *) NULL;
+    for (bp = bigchunk_freelist; bp; bp = bp->next) {
+        if (bp->this == (void *) 1)
+            duplicates++;
+        else
+            bp->this = (void *) 1;
+    }
+    if (duplicates) {
+        fprintf (stderr, "WARNING: %d duplicate bigchunks returned",
+                 duplicates);
+    }
+
+    /* Now free the global bigchunks */
+
+    for (bp = bigchunk_list; bp; bp = bpnext) {
+        bpnext = bp->next;
+        CC_FREE (bp->this, void);
+        bigchunkptrfree (bp);
+    }
+    for (bp = bigchunk_freelist; bp; bp = bpnext) {
+        bpnext = bp->next;
+        bigchunkptrfree (bp);
+    }
+
+    /* Record the local bigchunks used by the bigchunkptrs */
+
+    localcount = 0;
+    for (bp = local_bigchunk_list; bp; bp = bp->next)
+        localcount++;
+    if (!localcount)
+        return 0;  /* We haven't allocated anything */
+
+    tosslist = CC_SAFE_MALLOC(localcount, void *);
+    if (!tosslist)
+        return 1;
+    localcount = 0;
+    for (bp = local_bigchunk_list; bp; bp = bpnext) {
+        bpnext = bp->next;
+        tosslist[localcount++] = bp->this;
+        bigchunkptrfree (bp);
+    }
+
+    /* Check that the bigchunkptrs were used correctly */
+
+    bpcount = 0;
+    for (bp = bigchunkptr_freelist; bp; bp = bp->next) {
+        bp->this = (void *) NULL;
+        bpcount++;
+    }
+    if (bpcount != bigchunkptrtotal) {
+        fprintf (stderr, "WARNING: %d outstanding bigchunkptrs\n",
+                 bigchunkptrtotal - bpcount);
+    }
+    duplicates = 0;
+    for (bp = bigchunkptr_freelist; bp; bp = bp->next) {
+        if (bp->this == (void *) 1)
+            duplicates++;
+        else
+            bp->this = (void *) 1;
+    }
+    if (duplicates) {
+        fprintf (stderr, "WARNING: %d duplicate bigchunksptrs returned",
+                 duplicates);
+    }
+
+    /* And free the space used by the bigchunkptrs */
+
+    for (i = 0; i < localcount; i++) {
+        CC_FREE (tosslist[i], void);
+    }
+    CC_FREE (tosslist, void *);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static CCbigchunkptr *bigchunkptralloc (void)
+#else
+static CCbigchunkptr *bigchunkptralloc ()
+#endif
+{
+    CCbigchunkptr *bp;
+
+    if (!bigchunkptr_freelist) {
+        int count = CC_BIGCHUNK / sizeof(CCbigchunkptr);
+        void *p;
+
+        /* Grab a new bigchunk of memory */
+
+        p = (void *) CCutil_allocrus (CC_BIGCHUNK);
+        if (!p)
+            return (CCbigchunkptr *) NULL;
+
+        /* Split it up into linked bigchunkptrs */
+
+        bigchunkptr_freelist = (CCbigchunkptr *) p;
+        for (bp = bigchunkptr_freelist + count -2;
+             bp >= bigchunkptr_freelist; bp--) {
+            bp->next = bp+1;
+        }
+        bigchunkptr_freelist[count - 1].next = (CCbigchunkptr *) NULL;
+        bigchunkptrtotal += count;
+
+        /* And attach the bigchunk to the local bigchunklist */
+
+        bp = bigchunkptr_freelist;
+        bigchunkptr_freelist = bp->next;
+        bp->this = p;
+        bp->next = local_bigchunk_list;
+        local_bigchunk_list = bp;
+    }
+    bp = bigchunkptr_freelist;
+    bigchunkptr_freelist = bp->next;
+    return bp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void bigchunkptrfree (CCbigchunkptr *bp)
+#else
+static void bigchunkptrfree (bp)
+CCbigchunkptr *bp;
+#endif
+{
+    bp->next = bigchunkptr_freelist;
+    bigchunkptr_freelist = bp;
+}
diff --git a/contrib/blossom/concorde97/UTIL/bgetopt.c b/contrib/blossom/concorde97/UTIL/bgetopt.c
new file mode 100644
index 0000000000000000000000000000000000000000..7cc9db3425112d512c0ff6976981e4f768378fb5
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/bgetopt.c
@@ -0,0 +1,80 @@
+/***************************************************************************/
+/*                                                                         */
+/*                        PORTABLE GETOPT                                  */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: 1993 (?) (fmfeb02)                                               */
+/*  Modified: 15 February 1995 (bico)  - added warning                     */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:  Parses command-line strings                       */
+/*    int CCutil_bix_getopt (int ac, char **av, char *def)                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+int CCutil_bix_optind = 1;
+char *CCutil_bix_optarg = (char *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_bix_getopt (int ac, char **av, char *def)
+#else
+int CCutil_bix_getopt (ac, av, def)
+int ac;
+char **av;
+char *def;
+#endif
+{
+    int c;
+    char *sp = av[CCutil_bix_optind];
+    char bwarn[2];
+
+    if (CCutil_bix_optind < 1 || CCutil_bix_optind >= ac) {
+        CCutil_bix_optind = ac;
+        return (EOF);
+    }
+    if ((int) *sp != (int) '-')
+        return (EOF);
+    if ((int) *(sp + 1) == (int) '-') {
+        CCutil_bix_optind++;
+        return (EOF);
+    }
+    (av[CCutil_bix_optind])++;
+    sp++;
+    while ((int) *sp != (int) *def && (int) *def != (int) '\0')
+            def++;
+    if ((int) *def == (int) '\0') {
+        CCutil_bix_optind = ac;
+        bwarn[0] = *sp;                          /* Bico: February 8, 1995 */
+        bwarn[1] = '\0';
+        printf ("Illegal option: -%s\n", bwarn);
+        return CC_BIX_GETOPT_UNKNOWN;
+    }
+    if ((int) *(def + 1) != (int) ':') {
+        c = *sp;
+        if ((int) *(sp + 1) != (int) '\0')
+            *sp = '-';
+        else
+            CCutil_bix_optind++;
+        return (c);
+    } else {
+        if ((int) *(sp + 1) != (int) '\0') {
+            CCutil_bix_optarg = sp + 1;
+            c = *sp;
+            CCutil_bix_optind++;
+            return (c);
+        } else if (CCutil_bix_optind >= ac - 1) {
+            CCutil_bix_optind = ac;
+            return (EOF);
+        } else {
+            CCutil_bix_optarg = av[CCutil_bix_optind + 1];
+            c = *sp;
+            CCutil_bix_optind += 2;
+            return (c);
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/UTIL/dheaps_i.c b/contrib/blossom/concorde97/UTIL/dheaps_i.c
new file mode 100644
index 0000000000000000000000000000000000000000..26dde4c023b1f3bd0c871ca1beb31370f4d0ed4a
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/dheaps_i.c
@@ -0,0 +1,299 @@
+/***************************************************************************/
+/*                                                                         */
+/*                           DHEAP ROUTINES                                */
+/*                                                                         */
+/*                                                                         */
+/*                              TSP CODE                                   */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 9, 1995                                                 */
+/*  Reference: R.E. Tarjan, Data Structures and Network Algorithms         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCutil_dheap_init (CCdheap *h, int k)                            */
+/*      -h should point to a CCdheap struct.                               */
+/*      -k the max number of elements in the dheap.                        */
+/*    void CCutil_dheap_free (CCdheap *h)                                  */
+/*      -frees the spaces allocated by CCdheap_init                        */
+/*    int CCutil_dheap_resize (CCdheap *h, int newsize)                    */
+/*      -REALLOCs h so it can contain newsize elements.                    */
+/*      -returns -1 if it can't resize the heap.                           */
+/*    int CCutil_dheap_findmin (CCdheap *h)                                */
+/*      -returns the index of the element with min value h->key[i]         */
+/*      -returns -1 if no elements in heap.                                */
+/*    void CCutil_dheap_insert (CCdheap *h, int i)                         */
+/*      -inserts the element with index i (so its key should be loaded     */
+/*       beforehand in h->key[i]).                                         */
+/*    void CCutil_dheap_delete (CCdheap *h, int i)                         */
+/*      -deletes the element with index i.                                 */
+/*    int  CCutil_dheap_deletemin (CCdheap *h)                             */
+/*      -returns the min element in the heap, and deletes the min element  */
+/*      -returns -1 if no elements in heap.                                */
+/*    void CCutil_dheap_changekey (CCdheap *h, int i, double newkey)       */
+/*      -changes the key of the element with index i to newkey.            */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      A k-element heap will malloc 16k bytes of memory. If memory is     */
+/*  tight, using integer keys (instead of doubles), brings it down to      */
+/*  12k bytes, and if arbitrary deletions are not required, with a little  */
+/*  rewriting, the h->loc field can be eliminated, bring the space down    */
+/*  to 8k bytes.                                                           */
+/*      These routines work with indices into the h->key array, so in      */
+/*  some cases, you will need to maintain a separate names array to know   */
+/*  what element belongs to index i. For an example, see the k_nearest     */
+/*  code in kdnear.c.                                                      */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#define HEAP_D 3
+#define HEAP_UP(x) (((x)-1)/HEAP_D)
+#define HEAP_DOWN(x) (((x)*HEAP_D)+1)
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    dheap_siftup (CCdheap *h, int i, int x),
+    dheap_siftdown (CCdheap *h, int i, int x);
+
+static int
+    dheap_minchild (int x, CCdheap *h);
+
+#else
+
+static void
+    dheap_siftup (),
+    dheap_siftdown ();
+
+static int
+    dheap_minchild ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_dheap_init (CCdheap *h, int k)
+#else
+int CCutil_dheap_init (h, k)
+CCdheap *h;
+int k;
+#endif
+{
+    h->loc = (int *) NULL;
+    h->key = (double *) NULL;
+    h->entry = CC_SAFE_MALLOC (k, int);
+    if (!h->entry)
+        return 1;
+    h->loc = CC_SAFE_MALLOC (k, int);
+    if (!h->loc) {
+        CC_FREE (h->entry, int);
+        return 1;
+    }
+    h->key = CC_SAFE_MALLOC (k, double);
+    if (!h->key) {
+        CC_FREE (h->entry, int);
+        CC_FREE (h->loc, int);
+        return 1;
+    }
+    h->total_space = k;
+    h->size = 0;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_dheap_free (CCdheap *h)
+#else
+void CCutil_dheap_free (h)
+CCdheap *h;
+#endif
+{
+    CC_IFFREE (h->entry, int);
+    CC_IFFREE (h->loc, int);
+    CC_IFFREE (h->key, double);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_dheap_resize (CCdheap *h, int newsize)
+#else
+int CCutil_dheap_resize (h, newsize)
+CCdheap *h;
+int newsize;
+#endif
+{
+    if (newsize < h->size || newsize < h->total_space) return 0;
+    if (CCutil_reallocrus_count ((void **) &(h->key), newsize,
+                                 sizeof (double))) {
+        return -1;
+    }
+    if (CCutil_reallocrus_count ((void **) &(h->entry), newsize,
+                                 sizeof (int))) {
+        return -1;
+    }
+    if (CCutil_reallocrus_count ((void **) &(h->loc), newsize,
+                                 sizeof (int))) {
+        return -1;
+    }
+    h->total_space = newsize;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_dheap_findmin (CCdheap *h)
+#else
+int CCutil_dheap_findmin (h)
+CCdheap *h;
+#endif
+{
+    if (h->size == 0)
+        return -1;
+    else
+        return h->entry[0];
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_dheap_insert (CCdheap *h, int i)
+#else
+void CCutil_dheap_insert (h, i)
+CCdheap *h;
+int i;
+#endif
+{
+    assert (h->size < h->total_space);
+    h->size++;
+    dheap_siftup (h, i, h->size - 1);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_dheap_delete (CCdheap *h, int i)
+#else
+void CCutil_dheap_delete (h, i)
+CCdheap *h;
+int i;
+#endif
+{
+    int j;
+
+    h->size--;
+    j = h->entry[h->size];
+    h->entry[h->size] = -1;
+
+    if (j != i) {
+        if (h->key[j] <= h->key[i]) {
+            dheap_siftup (h, j, h->loc[i]);
+        } else {
+            dheap_siftdown (h, j, h->loc[i]);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_dheap_deletemin (CCdheap *h)
+#else
+int CCutil_dheap_deletemin (h)
+CCdheap *h;
+#endif
+{
+    int i;
+
+    if (h->size == 0)
+        return -1;
+    else {
+        i = h->entry[0];
+        CCutil_dheap_delete (h, i);
+        return i;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_dheap_changekey (CCdheap *h, int i, double newkey)
+#else
+void CCutil_dheap_changekey (h, i, newkey)
+CCdheap *h;
+int i;
+double newkey;
+#endif
+{
+    if (h->key[i] < newkey) {
+        h->key[i] = newkey;
+        dheap_siftup (h, i, h->loc[i]);
+    } else if (h->key[i] > newkey) {
+        h->key[i] = newkey;
+        dheap_siftdown (h, i, h->loc[i]);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dheap_siftup (CCdheap *h, int i, int x)
+#else
+static void dheap_siftup (h, i, x)
+CCdheap *h;
+int i;
+int x;
+#endif
+{
+    int p;
+
+    p = HEAP_UP (x);
+    while (x && h->key[h->entry[p]] > h->key[i]) {
+        h->entry[x] = h->entry[p];
+        h->loc[h->entry[p]] = x;
+        x = p;
+        p = HEAP_UP (p);
+    }
+    h->entry[x] = i;
+    h->loc[i] = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dheap_siftdown (CCdheap *h, int i, int x)
+#else
+static void dheap_siftdown (h, i, x)
+CCdheap *h;
+int i;
+int x;
+#endif
+{
+    int c;
+
+    c = dheap_minchild (x, h);
+
+    while (c >= 0 && h->key[h->entry[c]] < h->key[i]) {
+        h->entry[x] = h->entry[c];
+        h->loc[h->entry[c]] = x;
+        x = c;
+        c = dheap_minchild (c, h);
+    }
+    h->entry[x] = i;
+    h->loc[i] = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int dheap_minchild (int x, CCdheap *h)
+#else
+static int dheap_minchild (x, h)
+int x;
+CCdheap *h;
+#endif
+{
+    int c = HEAP_DOWN (x);
+    int cend;
+    double minval;
+    int minloc;
+
+    if (c >= h->size)
+        return -1;
+    minval = h->key[h->entry[c]];
+    minloc = c;
+    cend = c + HEAP_D;
+    if (h->size < cend)
+        cend = h->size;
+    for (c++; c < cend; c++) {
+        if (h->key[h->entry[c]] < minval) {
+            minval = h->key[h->entry[c]];
+            minloc = c;
+        }
+    }
+    return minloc;
+}
diff --git a/contrib/blossom/concorde97/UTIL/edg2cyc.c b/contrib/blossom/concorde97/UTIL/edg2cyc.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a122a16b65604f7de7c01fc62ba97e29256859e
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/edg2cyc.c
@@ -0,0 +1,110 @@
+/**************************************************************************/
+/*                                                                        */
+/*                CONVERT AN EDGE LIST TO A CYCLE ARRAY                   */
+/*                                                                        */
+/*                              TSP CODE                                  */
+/*                                                                        */
+/*  Written by: Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 8, 1995                                                */
+/*                                                                        */
+/*  EXPORTED FUNCTION:                                                    */
+/*      int CCutil_edge_to_cycle (int ncount, int *elist, int *cyc)       */
+/*        elist - edgelist in end1 end2 format                            */
+/*        cyc - returns the cycle in node node node format                */
+/*              (the calling routine should allocate cyc)                 */
+/*        Returns a nonzero value if there was and error.                 */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_edge_to_cycle (int ncount, int *elist, int *cyc)
+#else
+int CCutil_edge_to_cycle (ncount, elist, cyc)
+int ncount;
+int *elist, *cyc;
+#endif
+{
+    int *Lside, *Rside;
+    int i, k, end1, end2, prev, this, next, start, okfirst, first = 0;
+
+    Lside = CC_SAFE_MALLOC (ncount, int);
+    if (!Lside)
+        return 1;
+    Rside = CC_SAFE_MALLOC (ncount, int);
+    if (!Rside) {
+        CC_FREE (Lside, int);
+        return 1;
+    }
+    for (i = 0; i < ncount; i++) {
+        Lside[i] = Rside[i] = -1;
+    }
+
+    for (i = 0, k = 0; i < ncount; i++) {
+        end1 = elist[k++];
+        end2 = elist[k++];
+        if (Lside[end1] == -1)
+            Lside[end1] = end2;
+        else
+            Rside[end1] = end2;
+        if (Lside[end2] == -1)
+            Lside[end2] = end1;
+        else
+            Rside[end2] = end1;
+    }
+
+    for (i = 0, k = 0; i < ncount; i++) {
+        end1 = elist[k++];
+        end2 = elist[k++];
+        if (Lside[end1] == -1 || Rside[end1] == -1 ||
+            Lside[end2] == -1 || Rside[end2] == -1) {
+            fprintf (stderr, "Error in circuit\n");
+            CC_FREE (Lside, int);
+            CC_FREE (Rside, int);
+            return  1;
+        }
+    }
+    start = elist[0];
+    prev = -2;
+    this = start;
+    k = 0;
+    okfirst = 0;
+    do {
+        if (this == first)
+           okfirst = 1;
+        if (Lside[this] != prev)
+            next = Lside[this];
+        else
+            next = Rside[this];
+        prev = this;
+        this = next;
+        k++;
+    } while (next != start && k < ncount);
+
+    if (k != ncount || !okfirst) {
+        fprintf (stderr, "Error in circuit\n");
+        CC_FREE (Lside, int);
+        CC_FREE (Rside, int);
+        return 1;
+    }
+
+    start = first;
+    prev = -2;
+    this = start;
+    k = 0;
+    do {
+        cyc[k++] = this;
+        if (Lside[this] != prev)
+            next = Lside[this];
+        else
+            next = Rside[this];
+        prev = this;
+        this = next;
+    } while (next != start && k < ncount);
+
+    CC_FREE (Lside, int);
+    CC_FREE (Rside, int);
+    return 0;
+}
diff --git a/contrib/blossom/concorde97/UTIL/edgelen.c b/contrib/blossom/concorde97/UTIL/edgelen.c
new file mode 100644
index 0000000000000000000000000000000000000000..6692f7f8cf8917d82b8031cb437e310d16031b8d
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/edgelen.c
@@ -0,0 +1,439 @@
+/***************************************************************************/
+/*                                                                         */
+/*       FUNCTIONS FOR COMPUTING EDGE LENGTHS FOR GEOMETRIC PROBLEMS       */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: Summer 1994                                                      */
+/*        Modified - March 2, 1995                                         */
+/*                 - October 5, 1995 (Bico)                                */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int                                                                  */
+/*        CCutil_init_dat_edgelen (CCdatagroup *dat)                       */
+/*    int                                                                  */
+/*      (*CCutil_dat_edgelen) (int i, int j, CCdatagroup *dat)             */
+/*    void                                                                 */
+/*        CCutil_dsjrand_init (int maxdist, int seed)                      */
+/*    void                                                                 */
+/*        CCutil_freedata (int ncount, CCdatagroup *dat)                   */
+/*                                                                         */
+/*    NOTES:                                                               */
+/*        Supported norms (with defs in edgelen.h) are:                    */
+/*            MAXNORM  -  the L-infinity norm                              */
+/*            EUCLIDEAN_CEIL - the norm for the plaXXXX problems           */
+/*            EUCLIDEAN - rounded L-2 norm                                 */
+/*            EUCLIDEAN_3d - rounded L-2 norm in 3 space                   */
+/*            IBM - a norm for drilling problems in Bonn                   */
+/*            GEOGRAPHIC - distances on a sphere (Groetshel and Holland)   */
+/*            ATT - pseudo-Euclidean norm for att532                       */
+/*            MATRIXNORM - complete graph (lower + diagonal matrix)        */
+/*            DSJRAND - random edgelengths                                 */
+/*            CRYSTAL - Bland-Shallcross xray norm                         */
+/*                    - The coordinates generated for CRYSTAL problems     */
+/*               (in getdata.c) have been diveded by the motor speeds      */
+/*               (this makes the edgelen function faster) and scaled by    */
+/*               CRYSTAL_SCALE (currently 10000) and rounded to the        */
+/*               nearest integer (this lets the edgelen function produce   */
+/*               integer lengths without further rounding). The result is  */
+/*               a closer approximation to the Bland - Shallcrosss         */
+/*               floating point length function than that given in         */
+/*               TSPLIB_1.2.                                               */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static double
+    dtrunc (double);
+
+#else
+
+static double
+    dtrunc ();
+
+#endif
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int (*CCutil_dat_edgelen) (int, int, CCdatagroup *);
+#else
+int (*CCutil_dat_edgelen) ();
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_init_dat_edgelen (CCdatagroup *dat)
+#else
+int CCutil_init_dat_edgelen (dat)
+CCdatagroup *dat;
+#endif
+{
+    switch (dat->norm) {
+    case CC_EUCLIDEAN_CEIL:
+        CCutil_dat_edgelen = CCutil_euclid_ceiling_edgelen;
+        break;
+    case CC_EUCLIDEAN:
+        CCutil_dat_edgelen = CCutil_euclid_edgelen;
+        break;
+    case CC_MAXNORM:
+        CCutil_dat_edgelen = CCutil_max_edgelen;
+        break;
+    case CC_EUCLIDEAN_3D:
+        CCutil_dat_edgelen = CCutil_euclid3d_edgelen;
+        break;
+    case CC_IBM:
+        CCutil_dat_edgelen = CCutil_ibm_edgelen;
+        break;
+    case CC_GEOGRAPHIC:
+        CCutil_dat_edgelen = CCutil_geographic_edgelen;
+        break;
+    case CC_ATT:
+        CCutil_dat_edgelen = CCutil_att_edgelen;
+        break;
+    case CC_MATRIXNORM:
+        CCutil_dat_edgelen = CCutil_matrix_edgelen;
+        break;
+    case CC_DSJRANDNORM:
+        CCutil_dat_edgelen = CCutil_dsjrand_edgelen;
+        break;
+    case CC_CRYSTAL:
+        CCutil_dat_edgelen = CCutil_crystal_edgelen;
+        break;
+    default:
+        fprintf (stderr, "ERROR:  Unknown NORM %d.\n", dat->norm);
+        return 1;
+    }
+    return 0;
+}
+
+/* Several variables that would normally be called y1 and y2 are called
+   yy1 and yyy2 to avoid conflict with the bessel functions */
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_max_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_max_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double t1 = dat->x[i] - dat->x[j], t2 = dat->y[i] - dat->y[j];
+
+    if (t1 < 0)
+        t1 *= -1;
+    if (t2 < 0)
+        t2 *= -1;
+
+    return (int) (t1 < t2 ? t2 : t1);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_euclid_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_euclid_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double t1 = dat->x[i] - dat->x[j], t2 = dat->y[i] - dat->y[j];
+    int temp;
+
+    temp = (int) (sqrt (t1 * t1 + t2 * t2) + 0.5);
+    return temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_euclid3d_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_euclid3d_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double t1 = dat->x[i] - dat->x[j], t2 = dat->y[i] - dat->y[j];
+    double t3 = dat->z[i] - dat->z[j];
+    int temp;
+
+    temp = (int) (sqrt (t1 * t1 + t2 * t2 + t3 * t3) + 0.5);
+    return temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_ibm_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_ibm_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double dw = dat->x[i] - dat->x[j], dw1 = dat->y[i] - dat->y[j];
+    static double ibm_xmult[7] = {1062.5,
+        300.0,
+        300.0,
+        250.0,
+        300.0,
+        1000.0,
+        154.6};
+    static double ibm_xadd[7] = {155.0 - 0.01 * 1062.5,
+        197.5 - 0.05 * 300.0,
+        212.5 - 0.10 * 300.0,
+        227.5 - 0.15 * 250.0,
+        240.5 - 0.20 * 300.0,
+        255.0 - 0.25 * 1000.0,
+        305.0 - 0.30 * 154.6};
+    static double ibm_ymult[7] = {1062.5,
+        450.0,
+        350.0,
+        250.0,
+        300.0,
+        900.0,
+        157.7};
+    static double ibm_yadd[7] = {150.0 - 0.01 * 1062.5,
+        192.5 - 0.05 * 450.0,
+        215.0 - 0.10 * 350.0,
+        232.5 - 0.15 * 250.0,
+        245.5 - 0.20 * 300.0,
+        250.0 - 0.25 * 900.0,
+        295.0 - 0.30 * 157.7};
+
+    if (dw < 0.0)
+        dw = -dw;
+    dw /= 25400.0;
+    if (dw <= 0.01) {
+        dw *= 15500.0;
+    } else if (dw >= 0.30) {
+        dw = dw * 154.6 + (305.0 - 0.3 * 154.6);
+    } else {
+        dw = dw * ibm_xmult[(int) (dw / 0.05)] +
+            ibm_xadd[(int) (dw / 0.05)];
+    }
+    if (dw1 < 0.0)
+        dw1 = -dw1;
+    dw1 /= 25400.0;
+    if (dw1 <= 0.01) {
+        dw1 *= 15000.0;
+    } else if (dw1 >= 0.30) {
+        dw1 = dw1 * 157.7 + (295.0 - 0.3 * 157.7);
+    } else {
+        dw1 = dw1 * ibm_ymult[(int) (dw1 / 0.05)] +
+            ibm_yadd[(int) (dw1 / 0.05)];
+    }
+    if (dw < dw1)
+        dw = dw1;
+    return (int) dw;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_euclid_ceiling_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_euclid_ceiling_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double t1 = dat->x[i] - dat->x[j], t2 = dat->y[i] - dat->y[j];
+/*
+    int rd;
+    double max;
+
+    max = sqrt (t1 * t1 + t2 * t2);
+    rd = (int) max;
+    return (((max - rd) > .000000001) ? rd + 1 : rd);
+*/
+    return (int) (ceil (sqrt (t1 * t1 + t2 * t2)));
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_geographic_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_geographic_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double deg, min;
+    double lati, latj, longi, longj;
+    double q1, q2, q3;
+    int dd;
+    double x1 = dat->x[i], x2 = dat->x[j], yy1 = dat->y[i], yy2 = dat->y[j];
+
+    deg = dtrunc (x1);
+    min = x1 - deg;
+    lati = M_PI * (deg + 5.0 * min / 3.0) / 180.0;
+    deg = dtrunc (x2);
+    min = x2 - deg;
+    latj = M_PI * (deg + 5.0 * min / 3.0) / 180.0;
+
+    deg = dtrunc (yy1);
+    min = yy1 - deg;
+    longi = M_PI * (deg + 5.0 * min / 3.0) / 180.0;
+    deg = dtrunc (yy2);
+    min = yy2 - deg;
+    longj = M_PI * (deg + 5.0 * min / 3.0) / 180.0;
+
+    q1 = cos (longi - longj);
+    q2 = cos (lati - latj);
+    q3 = cos (lati + latj);
+    dd = (int) (6378.388 * acos (0.5 * ((1.0 + q1) * q2 - (1.0 - q1) * q3))
+                + 1.0);
+    return dd;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_att_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_att_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double xd = dat->x[i] - dat->x[j];
+    double yd = dat->y[i] - dat->y[j];
+    double rij = sqrt ((xd * xd + yd * yd) / 10.0);
+    double tij = dtrunc (rij);
+    int dij;
+
+    if (tij < rij)
+        dij = (int) tij + 1;
+    else
+        dij = (int) tij;
+    return dij;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double dtrunc (double x)
+#else
+static double dtrunc (x)
+double x;
+#endif
+{
+    int k;
+
+    k = (int) x;
+    x = (double) k;
+    return x;
+}
+
+static int dsjrand_param = 1;
+static double dsjrand_factor = 1.0;
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_dsjrand_init (int maxdist, int seed)
+#else
+void CCutil_dsjrand_init (maxdist, seed)
+int maxdist, seed;
+#endif
+{
+    dsjrand_factor = maxdist/2147483648.0;
+    dsjrand_param = 104*seed+1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_dsjrand_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_dsjrand_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    int di = (int) dat->x[i];
+    int dj = (int) dat->x[j];
+    int x, y, z;
+
+    x = di&dj;
+    y = di|dj;
+    z = dsjrand_param;
+
+    x *= z;
+    y *= x;
+    z *= y;
+
+    z ^= dsjrand_param;
+
+    x *= z;
+    y *= x;
+    z *= y;
+
+    x = ((di+dj)^z)&0x7fffffff;
+    return (int)(x*dsjrand_factor);
+}
+
+#define CRYSTAL_SCALE 10000
+
+#define CRYSTAL_FLIP_TOL ((180 * CRYSTAL_SCALE * 4) / 5)
+#define CRYSTAL_NEEDS_FLIP(x) ((x) > (CRYSTAL_FLIP_TOL))
+#define CRYSTAL_FLIP(x) ((2 * (CRYSTAL_FLIP_TOL)) - (x))
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_crystal_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_crystal_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    double w, w1;
+
+    w = dat->x[i] - dat->x[j];
+    if (w < 0)
+        w = -w;
+    w1 = dat->y[i] - dat->y[j];
+    if (w1 < 0)
+        w1 = -w1;
+    if (CRYSTAL_NEEDS_FLIP (w1))
+        w1 = CRYSTAL_FLIP (w1);
+    if (w < w1)
+        w = w1;
+    w1 = dat->z[i] - dat->z[j];
+    if (w1 < 0)
+        w1 = -w1;
+    if (w < w1)
+        w = w1;
+
+    return (int) w;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_matrix_edgelen (int i, int j, CCdatagroup *dat)
+#else
+int CCutil_matrix_edgelen (i, j, dat)
+int i, j;
+CCdatagroup *dat;
+#endif
+{
+    if (i > j)
+        return (dat->adj[i])[j];
+    else
+        return (dat->adj[j])[i];
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_freedatagroup (int ncount, CCdatagroup *dat)
+#else
+void CCutil_freedatagroup (ncount, dat)
+int ncount;
+CCdatagroup *dat;
+#endif
+{
+    int i;
+
+    CC_IFFREE (dat->x, double);
+    CC_IFFREE (dat->y, double);
+    CC_IFFREE (dat->z, double);
+    if (dat->adj) {
+        for (i = 0; i < ncount; i++) {
+            CC_IFFREE (dat->adj[i], int);
+        }
+        CC_FREE (dat->adj, int *);
+    }
+}
diff --git a/contrib/blossom/concorde97/UTIL/fastread.c b/contrib/blossom/concorde97/UTIL/fastread.c
new file mode 100644
index 0000000000000000000000000000000000000000..e3624b155489c6edc595ba51370aef13a7a1cee0
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/fastread.c
@@ -0,0 +1,49 @@
+/***************************************************************************/
+/*                                                                         */
+/*                   CODE TO READ ASCI INTS FAST                           */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Dave                                                      */
+/*  Date: Septmember 1994 (Bonn)  (cofeb16)                                */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCutil_readint (FILE *f)                                         */
+/*        - Returns the next int in the file f.                            */
+/*                                                                         */
+/*    NOTES:                                                               */
+/*       This is much faster that scanf. Its useful for big files and      */
+/*    and for profiling.                                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_readint (FILE *f)
+#else
+int CCutil_readint (f)
+FILE *f;
+#endif
+{
+    int v = 0;
+    int c;
+
+    while (( c = getc(f)) != EOF && !((c >= '0' && c <= '9') || c == '-'));
+    if (c == '-') {
+        v = 0;
+        while ((c = getc(f)) != EOF && c >= '0' && c <= '9') {
+            v = v * 10 + c - '0';
+        }
+        return -v;
+    } else {
+        v = c - '0';
+        while ((c = getc(f)) != EOF && c >= '0' && c <= '9') {
+            v = v * 10 + c - '0';
+        }
+        return v;
+    }
+}
diff --git a/contrib/blossom/concorde97/UTIL/genhash.c b/contrib/blossom/concorde97/UTIL/genhash.c
new file mode 100644
index 0000000000000000000000000000000000000000..bb0953c7b812f7a5ded1a79cf858b56570307187
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/genhash.c
@@ -0,0 +1,433 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  GENERIC HASH TABLE ROUTINES                            */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: November 12, 1996                                                */
+/*                                                                         */
+/*  These routines use a hash table to implement a generic associative     */
+/*  array.                                                                 */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCutil_genhash_init (CCgenhash *h, int size,                     */
+/*            int (*hcmp) (void *key1, void *key2, void *u_data),          */
+/*            unsigned int (*hfunc) (void *key, void *u_data),             */
+/*            void *u_data, double maxdensity, double lowdensity)          */
+/*      -CCgenhash *h (a pointer to a CCgenhash structure to be            */
+/*       initialized)                                                      */
+/*      -int size (the initial size of the hash table)                     */
+/*      -int (*hcmp) (void *key1, void *key2, void *u_data) (a pointer to  */
+/*       a function which returns 0 if key1 == key2, nonzero otherwise.    */
+/*       u_data will be the u_data passed to CCgenhash_init)               */
+/*      -unsigned int (*hfunc) (void *key, void *u_data) (a pointer to a   */
+/*       function which computes a hash function of key.                   */
+/*       u_data will be the u_data passed to CCgenhash_init)               */
+/*      -void *u_data (a pointer which will be passed into hcmp and hfunc) */
+/*      -double maxdensity (the maximum density (# elems / size) for the   */
+/*       hash table.  When this density is reached the hash table is       */
+/*       expanded.  0.0 means never expand the hash table)                 */
+/*      -double lowdensity (the density of a hash table immediately after  */
+/*       expansion)                                                        */
+/*     RETURNS 0 for success, -1 if out of memory.                         */
+/*                                                                         */
+/*    void CCutil_genhash_free (CCgenhash *h, void (*freefunc)(void *k,    */
+/*            void *d, void *u_data)                                       */
+/*      -CCgenhash *h (a pointer to the hash table)                        */
+/*      -void (*freefunc)(void *key, void *data, void *u_data) (a pointer  */
+/*       to a function to be called for each (key, data) pair in the       */
+/*       hashtable, or NULL)                                               */
+/*     ACTION: deletes all entries in h, and frees the space for h.        */
+/*                                                                         */
+/*    void CCutil_genhash_u_data (CCgenhash *h, void *u_data),             */
+/*      -CCgenhash *h (a pointer to the hash table)                        */
+/*      -void *u_data (a new value for u_data)                             */
+/*     ACTION: changes the u_data stored with the hash table, and          */
+/*      passed to hcomp and hfunc)                                         */
+/*                                                                         */
+/*    int CCutil_genhash_insert (CCgenhash *h, void *key, void *data)      */
+/*      -CCgenhash *h (a pointer to the hash table)                        */
+/*      -void *key (a pointer to the key data for this entry)              */
+/*      -void *data (the data to be stored)                                */
+/*     ACTION: h[key] = data                                               */
+/*     COMMENT: if h[key] already has a value, this acts like a stack      */
+/*      CCutil_genhash_delete (key) will reveal the old value.             */
+/*     RETURNS 0 for success, -1 if out of memory.                         */
+/*                                                                         */
+/*    int CCutil_genhash_replace (CCgenhash *h, void *key, void *data)     */
+/*      -CCgenhash *h (a pointer to the hash table)                        */
+/*      -void *key (a pointer to the key data for this entry)              */
+/*      -void *data (the data to be stored)                                */
+/*     ACTION: h[key] = data                                               */
+/*     COMMENT: if h[key] already has a value, this replaces that          */
+/*      value.                                                             */
+/*     RETURNS 0 for success, -1 if out of memory.                         */
+/*                                                                         */
+/*    int CCutil_genhash_delete (CCgenhash *h, void *key)                  */
+/*      -CCgenhash *h (a pointer to the hash table)                        */
+/*      -void *key (a pointer to the key data for this entry)              */
+/*     ACTION: h[key] = NULL                                               */
+/*     RETURNS 0 for success, -1 if h[key] was already NULL                */
+/*                                                                         */
+/*    void *CCutil_genhash_lookup (CCgenhash *h, void *key)                */
+/*      -CCgenhash *h (a pointer to the hash table)                        */
+/*      -void *key (a pointer to the key data for this entry)              */
+/*     RETURNS h[key], or NULL if h[key] not defined                       */
+/*                                                                         */
+/*    unsigned int CCutil_genhash_hash (CCgenhash *h, void *key)           */
+/*      -CCgenhash *h (a pointer to the hash table)                        */
+/*      -void *key (a pointer to key data)                                 */
+/*     RETURNS the hash function of key (ie, h->hfunc(key))                */
+/*                                                                         */
+/*    int CCutil_genhash_insert_h (CCgenhash *h, unsigned int hashval,     */
+/*            void *key, void *data)                                       */
+/*    int CCutil_genhash_replace_h (CCgenhash *h, unsigned int hashval,    */
+/*            void *key, void *data)                                       */
+/*    int CCutil_genhash_delete_h (CCgenhash *h, unsigned int hashval,     */
+/*            void *key)                                                   */
+/*    int CCutil_genhash_lookup_h (CCgenhash *h, unsigned int hashval,     */
+/*            void *key)                                                   */
+/*     NOTE: These are alternate versions of the same functions without    */
+/*      the _h suffix, and take an additional argument, hashval, which     */
+/*      should be equal to CCutil_genhash_hash (key).  They provide a      */
+/*      method to avoid recomputing CCgenhash_hash over multiple calls     */
+/*      with the same key.                                                 */
+/*                                                                         */
+/*    void CCutil_genhash_start (CCgenhash *h, CCgenhash_iter *iter)       */
+/*     -CCgenhash *h (a pointer to the hash table)                         */
+/*     -CCgenhash_iter *iter (a pointer to the iterator to be              */
+/*       initialized)                                                      */
+/*      ACTION: initializes iter for iterating over elements of h using    */
+/*       CCutil_genhash_next ().                                           */
+/*                                                                         */
+/*    void *CCutil_genhash_next (CCgenhash *h, CCgenhash_iter *iter,       */
+/*            void **key, int *keysize)                                    */
+/*     -CCgenhash *h (a pointer to the hash table)                         */
+/*     -CCgenhash_iter *iter (a pointer to an iterator)                    */
+/*     -void **key (a pointer to a location for the key value)             */
+/*     -int *keysize (a pointer to a location for the key size)            */
+/*     RETURNS: a next data value from the hash table (corresponding       */
+/*      to the returned key and keysize), or NULL if there                 */
+/*      are no more elements.                                              */
+/*     NOTE: CCgenhash_next can tolerate the deletion of the current       */
+/*      (last returned) element and arbitrary lookups and replaces         */
+/*      between calls to CCgenhash_next.  However, deletion of             */
+/*      elements other than the current one are not permitted, and         */
+/*      insertion a table which could be expanded can result in            */
+/*      elements being skipped.                                            */
+/*                                                                         */
+/*    NOTES:                                                               */
+/*       Functions prototyped in genhash.h.                                */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+typedef struct CCgenhash_elem {
+    void *key;
+    void *data;
+    struct CCgenhash_elem *next;
+} CCgenhash_elem;
+
+CC_PTR_ALLOC_ROUTINE (CCgenhash_elem, CCgenhash_elemalloc,
+                      CCgenhash_elemchunklist, CCgenhash_elemfreelist)
+CC_PTR_FREE_ROUTINE (CCgenhash_elem, CCgenhash_elemfree,
+                     CCgenhash_elemfreelist)
+CC_PTR_FREE_WORLD_ROUTINE (CCgenhash_elem, CCgenhash_elemfree_world,
+                           CCgenhash_elemchunklist, CCgenhash_elemfreelist)
+CC_PTR_LEAKS_ROUTINE (CCgenhash_elem, CCgenhash_elem_check_leaks,
+                      CCgenhash_elemchunklist, CCgenhash_elemfreelist,
+                      data, void *)
+CC_PTR_STATUS_ROUTINE (CCgenhash_elem, CCgenhash_elem_status,
+                       CCgenhash_elemchunklist, CCgenhash_elemfreelist)
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    genhash_resize (CCgenhash *h);
+
+#else
+
+static int
+    genhash_resize ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_genhash_init (CCgenhash *h, int size,
+                  int (*hcmp) (void *key1, void *key2, void *u_data),
+                  unsigned int (*hfunc) (void *key, void *u_data),
+                  void *u_data, double maxdensity, double lowdensity)
+#else
+int CCutil_genhash_init (h, size, hcmp, hfunc, u_data, maxdensity, lowdensity)
+CCgenhash *h;
+int size;
+int (*hcmp)();
+unsigned int (*hfunc)();
+void *u_data;
+double maxdensity;
+double lowdensity;
+#endif
+{
+    int i;
+
+    h->nelem = 0;
+    h->size = CCutil_nextprime ((unsigned int) size);
+    h->hcmp = hcmp;
+    h->hfunc = hfunc;
+    h->u_data = u_data;
+    h->maxdensity = maxdensity;
+    h->lowdensity = lowdensity;
+
+    if (maxdensity <= 0.0) {
+        h->maxelem = 0;
+    } else {
+        h->maxelem = (int) (h->maxdensity * h->size);
+    }
+
+    h->table = CC_SAFE_MALLOC (h->size, CCgenhash_elem *);
+    if (!h->table) {
+        return -1;
+    }
+    for (i=0; i<h->size; i++) {
+        h->table[i] = (CCgenhash_elem *) NULL;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_genhash_insert (CCgenhash *h, void *key, void *data)
+#else
+int CCutil_genhash_insert (h, key, data)
+CCgenhash *h;
+void *key;
+void *data;
+#endif
+{
+    return CCutil_genhash_insert_h (h, h->hfunc(key, h->u_data), key, data);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_genhash_u_data (CCgenhash *h, void *u_data)
+#else
+void CCutil_genhash_u_data (h, u_data)
+CCgenhash *h;
+void *u_data;
+#endif
+{
+    h->u_data = u_data;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_genhash_insert_h (CCgenhash *h, unsigned int hashval, void *key,
+            void *data)
+#else
+int CCutil_genhash_insert_h (h, hashval, key, data)
+CCgenhash *h;
+unsigned int hashval;
+void *key;
+void *data;
+#endif
+{
+    int loc;
+    CCgenhash_elem *e;
+
+    if (h->maxelem && h->nelem >= h->maxelem) {
+        if (genhash_resize (h)) {
+            return -1;
+        }
+    }
+
+    loc = hashval % h->size;
+    e = CCgenhash_elemalloc();
+    if (!e) return -1;
+
+    e->key = key;
+    e->data = data;
+    e->next = h->table[loc];
+    h->table[loc] = e;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_genhash_replace (CCgenhash *h, void *key, void *data)
+#else
+int CCutil_genhash_replace (h, key, data)
+CCgenhash *h;
+void *key;
+void *data;
+#endif
+{
+    return CCutil_genhash_replace_h (h, h->hfunc (key, h->u_data), key, data);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_genhash_replace_h (CCgenhash *h, unsigned int hashval, void *key,
+            void *data)
+#else
+int CCutil_genhash_replace_h (h, hashval, key, data)
+CCgenhash *h;
+unsigned int hashval;
+void *key;
+void *data;
+#endif
+{
+    CCgenhash_elem *e;
+
+    for (e = h->table[hashval % h->size]; e; e = e->next) {
+        if (h->hcmp(e->key, key, h->u_data) == 0) {
+            e->data = data;
+            return 0;
+        }
+    }
+    return CCutil_genhash_insert_h (h, hashval, key, data);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_genhash_delete (CCgenhash *h, void *key)
+#else
+int CCutil_genhash_delete (h, key)
+CCgenhash *h;
+void *key;
+#endif
+{
+    return CCutil_genhash_delete_h (h, h->hfunc(key, h->u_data), key);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_genhash_delete_h (CCgenhash *h, unsigned int hashval, void *key)
+#else
+int CCutil_genhash_delete_h (h, hashval, key)
+CCgenhash *h;
+unsigned int hashval;
+void *key;
+#endif
+{
+    int loc = hashval % h->size;
+    CCgenhash_elem *e, **eprev;
+
+    for (e = h->table[loc], eprev = &h->table[loc]; e;
+         eprev = &e->next, e = e->next) {
+        if (h->hcmp(e->key, key, h->u_data) == 0) {
+            *eprev = e->next;
+            CCgenhash_elemfree (e);
+            return 0;
+        }
+    }
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+unsigned int CCutil_genhash_hash (CCgenhash *h, void *key)
+#else
+unsigned int CCutil_genhash_hash (h, key)
+CCgenhash *h;
+void *key;
+#endif
+{
+    return h->hfunc (key, h->u_data);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void *CCutil_genhash_lookup (CCgenhash *h, void *key)
+#else
+void *CCutil_genhash_lookup (h, key)
+CCgenhash *h;
+void *key;
+#endif
+{
+    return CCutil_genhash_lookup_h (h, h->hfunc(key, h->u_data), key);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void *CCutil_genhash_lookup_h (CCgenhash *h, unsigned int hashval, void *key)
+#else
+void *CCutil_genhash_lookup_h (h, hashval, key)
+CCgenhash *h;
+unsigned int hashval;
+void *key;
+#endif
+{
+    CCgenhash_elem *e;
+
+    for (e = h->table[hashval % h->size]; e; e = e->next) {
+        if (h->hcmp(e->key, key, h->u_data) == 0) {
+            return e->data;
+        }
+    }
+    return (void *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_genhash_free (CCgenhash *h, void (*freefunc)(void *key, void *data,
+             void *u_data))
+#else
+void CCutil_genhash_free (h, freefunc)
+CCgenhash *h;
+void (*freefunc)();
+#endif
+{
+    int i;
+    CCgenhash_elem *e, *enext;
+    int total, onlist;
+
+    for (i=0; i<h->size; i++) {
+        for (e = h->table[i]; e; e = enext) {
+            enext = e->next;
+            if (freefunc) {
+                (*freefunc)(e->key, e->data, h->u_data);
+            }
+            CCgenhash_elemfree (e);
+        }
+    }
+    if (!CCgenhash_elem_status (&total, &onlist)) {
+        CCgenhash_elemfree_world();
+    }
+    CC_FREE (h->table, CCgenhash_elem *);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int genhash_resize (CCgenhash *h)
+#else
+static int genhash_resize (h)
+CCgenhash *h;
+#endif
+{
+    int newsize = CCutil_nextprime ((unsigned int) (h->nelem / h->lowdensity));
+    CCgenhash_elem **newtable;
+    CCgenhash_elem *e, *enext;
+    int loc;
+    int i;
+
+    if (newsize <= h->nelem)
+        newsize = CCutil_nextprime ((unsigned int) h->nelem + 1);
+
+    newtable = CC_SAFE_MALLOC (newsize, CCgenhash_elem *);
+    if (!newtable) {
+        return -1;
+    }
+
+    for (i=0; i<newsize; i++) {
+        newtable[i] = (CCgenhash_elem *) NULL;
+    }
+
+    for (i=0; i<h->size; i++) {
+        for (e = h->table[i]; e; e = enext) {
+            enext = e;
+            loc = h->hfunc(e->key, h->u_data) % newsize;
+            e->next = newtable[loc];
+            newtable[loc] = e;
+        }
+    }
+
+    CC_FREE (h->table, CCgenhash_elem *);
+
+    h->table = newtable;
+    h->size = newsize;
+    h->maxelem = (int) (h->maxdensity * h->size);
+
+    return 0;
+}
diff --git a/contrib/blossom/concorde97/UTIL/getdata.c b/contrib/blossom/concorde97/UTIL/getdata.c
new file mode 100644
index 0000000000000000000000000000000000000000..cb98d098d926c2b0e5e2ae04b17ae2a464d360be
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/getdata.c
@@ -0,0 +1,1983 @@
+/***************************************************************************/
+/*                                                                         */
+/*                   SOME DATA READING ROUTINES                            */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 2, 1995                                                    */
+/*  Changes: 17.7.96 (Bico)                                                */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*   int CCutil_getdata (char *datname, char *weightname, int binary_in,   */
+/*           int innorm, inusenodeweights, int *ncount, CCdatagroup *dat,  */
+/*           double **wcoord)                                              */
+/*    RETURNS the data to generate edge lengths in the dat structure.      */
+/*            The calling routine should be sure that dat points to        */
+/*            a structure. If datname is NULL then random entries will be  */
+/*            generated.                                                   */
+/*     -datname is the name of the datfile or the matrix file, if NULL     */
+/*      then random data will be generated, according to the norm type.    */
+/*      For D2 and D3 norms, the coordinates will be uniform between 0 and */
+/*      ncount -1 (GEOGRAPHIC norms have x between -90 and 90 and y        */
+/*      between -180 and 180). (For D2, the points will be distinct.)      */
+/*      For MATRIX norms, the entries will be                              */
+/*      uniform between 0 and MATRAND_SCALE * ncount - 1 (currently        */
+/*      10*ncount - 1. For CRYSTAL norms, a random matrix and bounds in    */
+/*      range of the TSPLIB problems is generated - the wavelength is      */
+/*      chosen to be 1.0, 1.35, or 1.70 depending on the ncount (but the   */
+/*      problem will not be very close to hitting ncount.).                */
+/*     -binary_in should be 1 if the datname file is in binary integers.   */
+/*     -innorm is the norm.                                                */
+/*     -ncount will return the number of nodes. If datname is NULL, then   */
+/*      ncount should be passed in with the number of nodes to be used in  */
+/*      the random problem generation.                                     */
+/*     -dat will contain the info to call the edgelen function.            */
+/*                                                                         */
+/*                                                                         */
+/*   int CCutil_writemaster (char *mastername, int ncount,                 */
+/*           CCdatagroup *dat, int *perm)                                  */
+/*    WRITES the dat information and the permutation into a binary file.   */
+/*           This is used in the TSP, where the dat file has usually       */
+/*           been permuted to but the nodes into tour order.               */
+/*     -mastername is the name of the file (cannot be NULL)                */
+/*     -ncount is the number of nodes                                      */
+/*     -dat contains the edgelen info (e.g. x,y coordinates), it can be    */
+/*      NULL                                                               */
+/*     -perm contains a permutation of 0 to ncount - 1 (so a tour in       */
+/*      node node node format)                                             */
+/*                                                                         */
+/*   int CCutil_getmaster (char *mastername, int *ncount, CCdatagroup *dat,*/
+/*           int *perm)                                                    */
+/*    RETURNS the dat information and the permutation from a binary file   */
+/*            (written by a call to writemaster). Used by the TSP code.    */
+/*     -mastername is the name of the file (cannot be NULL)                */
+/*     -ncount returns the number of nodes                                 */
+/*     -dat returns the edgelen info (e.g. x,y coordinates), or NULL       */
+/*     -perm returns a permutation of 0 to ncount - 1 (so a tour in        */
+/*      node node node format)                                             */
+/*                                                                         */
+/*   int CCutil_getnodeweights (char *weightname, int ncount,              */
+/*           int weight_limit, double **wcoord)                            */
+/*    RETURNS a list of nonnegative nodesweights (they will be translated  */
+/*            if the weightname file has negative entries). If weightname  */
+/*            is NULL then random entries (from 0 to ncount - 1 will be    */
+/*            generated.                                                   */
+/*     -weightname is the name of a file containing nodeweights. It will   */
+/*      only be read if inusenodeweights is 1. If NULL, random entries     */
+/*      will be generated (between 0 and weight_limit - 1)                 */
+/*     -wcoord will contain the nonnegative node weights (it will be       */
+/*      here in getnodeweights)                                            */
+/*                                                                         */
+/*   int CCutil_gettsplib (char *datname, int *ncount, CCdatagroup *dat)   */
+/*    READS an xxx.tsp TSPLIB file, and returns the dat structure to       */
+/*            generate edge lengths.                                       */
+/*     -datname should be the name of a TSPLIB xxx.tsp file.               */
+/*     -ncount returns the number of nodes.                                */
+/*     -dat returns the data.                                              */
+/*                                                                         */
+/*   int CCutil_getedgelist (int ncount, char *fname, int *ecount,         */
+/*           int **elist, int **elen)                                      */
+/*    READS an edgelist in end1 end2 length format.                        */
+/*     -fname name of the file                                             */
+/*     -ecount returns the number of edges                                 */
+/*     -elist returns the edges in end1 end2 format (it will be allocated  */
+/*      by getedgelist)                                                    */
+/*     -elen returns the length of the edges in len len len format         */
+/*                                                                         */
+/*   int CCutil_getedgelist_n (int *ncount, char *fname, int *ecount,      */
+/*           int **elist, int **elen)                                      */
+/*    READS an edgelist in end1 end2 length format.                        */
+/*    Like CCutil_getedgelist (), but it also returns ncount.              */
+/*                                                                         */
+/*   int CCutil_getcycle_edgelist (int ncount, char *cyclename,            */
+/*           int *outcycle)                                                */
+/*    READS a cycle in end1 end2 length format, and returns the cycle in   */
+/*            node node format in the array outcycle.                      */
+/*     -outcycle should be allocated by the calling routine (and should be */
+/*      be at least ncount long)                                           */
+/*                                                                         */
+/*   int CCutil_getcycle (int ncount, char *cyclename, int *outcycle)      */
+/*    READS a cycle in node node format, and returns the cycle in node     */
+/*            node format in the array outcycle.                           */
+/*     -outcycle should be allocated by the calling routine                */
+/*                                                                         */
+/*   int CCutil_getedges_double (int *ncount, char *fname, int *ecount,    */
+/*           int **elist, double **elen, int binary_in)                    */
+/*    READS the edgelist in end1 end2 length format, where the length      */
+/*            is a double (used for x-vectors)                             */
+/*     -returns the number of nodes                                        */
+/*     -fname is the name of the file to read.                             */
+/*     -ecount returns the number of edges.                                */
+/*     -elist returns the list of edges in end1 end2 format (it will be    */
+/*      allocated by getedges_double).                                     */
+/*     -elen returns the lengths of the edges.                             */
+/*     -binary_in indicates whether the file should be written in binary   */
+/*      or in ascii (1 is binary, 0 is ascii)                              */
+/*                                                                         */
+/*   int CCutil_writeedges (int ncount, char *outedgename, int ecount,     */
+/*           int *elist, CCdatagroup *dat)                                 */
+/*    WRITES the edgelist in end1 end2 length format.                      */
+/*     -ncount the number of nodes                                         */
+/*     -outedgename is the name of the file to write to.                   */
+/*     -ecount is the number of edges.                                     */
+/*     -elist is the list of edges in end1 end2 format.                    */
+/*     -dat contains the data to compute edgelengths.                      */
+/*                                                                         */
+/*   int CCutil_writecycle_edgelist (int ncount, char *outedgename,        */
+/*           int *cycle, CCdatagroup *dat)                                 */
+/*    WRITES the cycle int end1 end1 length format.                        */
+/*                                                                         */
+/*   int CCutil_writecycle (int ncount, char *outcyclename, int *cycle)    */
+/*    WRITES the cycle in node node node format.                           */
+/*                                                                         */
+/*   int CCutil_writeedges_double (int ncount, char *outedgename,          */
+/*           int ecount, int *elist, double *elen, int binary_out)         */
+/*    WRITES the edgelist in end1 end2 length format, where the length     */
+/*            is a double (used for x-vectors)                             */
+/*     -ncount the number of nodes                                         */
+/*     -outedgename is the name of the file to write to.                   */
+/*     -ecount is the number of edges.                                     */
+/*     -elist is the list of edges in end1 end2 format.                    */
+/*     -elen are the lengths of the edges.                                 */
+/*     -binary_out indicates whether the file should be written in binary  */
+/*        or in ascii (1 is binary, 0 is ascii)                            */
+/*                                                                         */
+/*   int CCutil_datagroup_perm (int ncount, CCdatagroup *dat, int *perm)   */
+/*    REORDERS the nodes to match the order given in perm.                 */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*     Functions prototyped in util.h. Functions return 0 when they        */
+/*    succeed and nonzero when they fail (usually do to bad filenames or   */
+/*    not enough memory).                                                  */
+/*     The TSPLIB reader works for all problems in TSPLIB_1.2, but does    */
+/*    not include all of the options listed in Reinelt's orginal TSPLIB    */
+/*    paper. It returns a failure on linhp318.tsp, since there is no       */
+/*    place for fixed edges in our edge length dat structure.              */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#define MATRAND_SCALE 10  /* Range of edge lengths: [0, MATRAND_SCALE * n) */
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    make_weights_nonnegative (int ncount, double *wcoord);
+static int
+    read_crystal (char *datname, int *ncount, CCdatagroup *dat);
+
+#else
+
+static void
+    make_weights_nonnegative ();
+static int
+    read_crystal ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getdata (char *datname, int binary_in, int innorm,
+             int *ncount, CCdatagroup *dat)
+#else
+int CCutil_getdata (datname, binary_in, innorm, ncount, dat)
+char *datname;
+int binary_in, innorm;
+int *ncount;
+CCdatagroup *dat;
+#endif
+{
+    int i, j;
+    int xi, yi, zi;
+
+    dat->x = (double *) NULL;
+    dat->y = (double *) NULL;
+    dat->z = (double *) NULL;
+    dat->adj = (int **) NULL;
+    dat->norm = innorm;
+
+    if (datname == (char *) NULL && *ncount == 0) {
+        fprintf (stderr, "getdata needs a datfile or a nodecount\n");
+        return 1;
+    }
+
+    if (innorm == CC_CRYSTAL) {
+        return read_crystal (datname, ncount, dat);
+    } else if ((innorm & CC_NORM_SIZE_BITS) == CC_D2_NORM_SIZE ||
+        (innorm & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+        if (datname != (char *) NULL) {
+            if (binary_in) {
+                CC_SFILE *f = CCutil_sopen (datname, "r");
+                if (f == (CC_SFILE *) NULL)
+                    return 1;
+                if (CCutil_sread_int (f, (unsigned int *) ncount)) {
+                    CCutil_sclose (f);
+                    return 1;
+                }
+                printf ("nnodes = %d\n", *ncount);
+                fflush (stdout);
+                dat->x = CC_SAFE_MALLOC (*ncount, double);
+                if (!dat->x) {
+                    if (CCutil_sclose (f))
+                        fprintf (stderr, "Could not close file\n");
+                    return 1;
+                }
+                dat->y = CC_SAFE_MALLOC (*ncount, double);
+                if (!dat->y) {
+                    if (CCutil_sclose (f))
+                        fprintf (stderr, "Could not close file\n");
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+                if ((innorm & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+                    dat->z = CC_SAFE_MALLOC (*ncount, double);
+                    if (!dat->z) {
+                        if (CCutil_sclose (f))
+                            fprintf (stderr, "Could not close file\n");
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                }
+                for (i = 0; i < *ncount; i++) {
+                    if (CCutil_sread_int (f, (unsigned int *) &xi)) {
+                        CCutil_sclose (f);
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    if (CCutil_sread_int (f, (unsigned int *) &yi)) {
+                        CCutil_sclose (f);
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    dat->x[i] = (double) xi;
+                    dat->y[i] = (double) yi;
+                    if ((innorm & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+                        if (CCutil_sread_int (f, (unsigned int *) &zi)) {
+                            CCutil_sclose (f);
+                            CCutil_freedatagroup (*ncount, dat);
+                            return 1;
+                        }
+                        dat->z[i] = (double) zi;
+                    }
+                }
+                if (CCutil_sclose (f)) {
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+            } else {
+                FILE *datin = fopen (datname, "r");
+                if (datin == (FILE *) NULL) {
+                    perror (datname);
+                    fprintf (stderr, "Unable to open %s for input\n", datname);
+                    return 1;
+                }
+                fscanf (datin, "%d", ncount);
+                printf ("nnodes = %d\n", *ncount);
+                dat->x = CC_SAFE_MALLOC (*ncount, double);
+                if (!dat->x) {
+                    fclose (datin);
+                    return 1;
+                }
+                dat->y = CC_SAFE_MALLOC (*ncount, double);
+                if (!dat->y) {
+                    fclose (datin);
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+                if ((innorm & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+                    dat->z = CC_SAFE_MALLOC (*ncount, double);
+                    if (!dat->z) {
+                        fclose (datin);
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    for (i = 0; i < *ncount; i++) {
+                        fscanf (datin, "%lf %lf %lf",
+                             &(dat->x[i]), &(dat->y[i]), &(dat->z[i]));
+                    }
+                } else {
+                    for (i = 0; i < *ncount; i++) {
+                        fscanf (datin, "%lf %lf", &(dat->x[i]), &(dat->y[i]));
+                    }
+                }
+                fclose (datin);
+            }
+        } else {
+            printf ("Random %d point set\n", *ncount);
+            fflush (stdout);
+            dat->x = CC_SAFE_MALLOC (*ncount, double);
+            if (!dat->x)
+                return 1;
+            dat->y = CC_SAFE_MALLOC (*ncount, double);
+            if (!dat->y) {
+                CCutil_freedatagroup (*ncount, dat);
+                return 1;
+            }
+            if ((innorm & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+                dat->z = CC_SAFE_MALLOC (*ncount, double);
+                if (!dat->z) {
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+                for (i = 0; i < *ncount; i++) {
+                    dat->x[i] = (double) (CCutil_lprand () % (*ncount));
+                    dat->y[i] = (double) (CCutil_lprand () % (*ncount));
+                    dat->z[i] = (double) (CCutil_lprand () % (*ncount));
+                }
+            } else if (innorm == CC_GEOGRAPHIC) {
+                for (i = 0; i < *ncount; i++) {
+                    dat->x[i] = (double) (CCutil_lprand () % 180) - 90.0;
+                    dat->y[i] = (double) (CCutil_lprand () % 360) - 180.0;
+                }
+            } else {
+                int **hit = (int **) NULL;
+                int *hitcount = (int *) NULL;
+                int winner, x, y;
+
+                hit      = CC_SAFE_MALLOC (*ncount, int *);
+                hitcount = CC_SAFE_MALLOC (*ncount, int);
+                if (!hit || !hitcount) {
+                    fprintf (stderr, "out of memory in getdata\n");
+                    CC_IFFREE (hit, int *);
+                    CC_IFFREE (hitcount, int);
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+
+                for (i = 0; i < *ncount; i++) {
+                    hit[i] = (int *) NULL;
+                    hitcount[i] = 0;
+                }
+
+                for (i = 0; i < *ncount; i++) {
+                    winner = 0;
+                    do {
+                        x = CCutil_lprand () % (*ncount);
+                        y = CCutil_lprand () % (*ncount);
+                        for (j = 0; j < hitcount[x]; j++) {
+                            if (hit[x][j] == y) break;
+                        }
+                        if (j == hitcount[x]) {
+                            if (CCutil_reallocrus_count ((void **) &(hit[x]),
+                                     hitcount[x] + 1, sizeof (int))) {
+                                fprintf (stderr, "reallocrus_count failed\n");
+                                for (i = 0; i < *ncount; i++) {
+                                    CC_IFFREE (hit[i], int);
+                                }
+                                CC_IFFREE (hit, int *);
+                                CC_IFFREE (hitcount, int);
+                                CCutil_freedatagroup (*ncount, dat);
+                                return 1;
+                            }
+                            hit[x][hitcount[x]] = y;
+                            hitcount[x]++;
+                            winner = 1;
+                        }
+                        if (!winner) {
+                            printf ("X"); fflush (stdout);
+                        }
+                    } while (!winner);
+                    dat->x[i] = (double) x;
+                    dat->y[i] = (double) y;
+                }
+                for (i = 0; i < *ncount; i++) {
+                    CC_IFFREE (hit[i], int);
+                }
+                CC_IFFREE (hit, int *);
+                CC_IFFREE (hitcount, int);
+            }
+        }
+    } else if ((innorm & CC_NORM_SIZE_BITS) == CC_MATRIX_NORM_SIZE){
+        if (datname != (char *) NULL) {
+            /* Matrix is the lower triangle plus the diagonal */
+            if (binary_in) {
+                CC_SFILE *f = CCutil_sopen (datname, "r");
+                if (f == (CC_SFILE *) NULL)
+                    return 1;
+                if (CCutil_sread_int (f, (unsigned int *) ncount)) {
+                    CCutil_sclose (f);
+                    return 1;
+                }
+                printf ("nnodes = %d\n", *ncount);
+                fflush (stdout);
+                dat->adj = CC_SAFE_MALLOC (*ncount, int *);
+                if (!dat->adj) {
+                    if (CCutil_sclose (f))
+                        fprintf (stderr, "Could not close file\n");
+                    return 1;
+                }
+                for (i = 0; i < *ncount; i++)
+                    dat->adj[i] = (int *) NULL;
+                for (i = 0; i < *ncount; i++) {
+                    dat->adj[i] = CC_SAFE_MALLOC (i + 1, int);
+                    if (!dat->adj[i]) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        if (CCutil_sclose (f))
+                            fprintf (stderr, "Could not close file\n");
+                        return 1;
+                    }
+                }
+                for (i = 0; i < *ncount; i++) {
+                    for (j = 0; j <= i; j++) {
+                        if (CCutil_sread_int (f,
+                            (unsigned int *) &(dat->adj[i][j]))) {
+                            CCutil_sclose (f);
+                            CCutil_freedatagroup (*ncount, dat);
+                            return 1;
+                        }
+                    }
+                }
+                if (CCutil_sclose (f)) {
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+            } else {
+                FILE *datin = fopen (datname, "r");
+                if (datin == (FILE *) NULL) {
+                    perror (datname);
+                    fprintf (stderr, "Unable to open %s for input\n", datname);
+                    return 1;
+                }
+                *ncount = CCutil_readint (datin);
+                printf ("nnodes = %d\n", *ncount);
+                dat->adj = CC_SAFE_MALLOC (*ncount, int *);
+                if (!dat->adj) {
+                    fclose (datin);
+                    return 1;
+                }
+                for (i = 0; i < *ncount; i++)
+                    dat->adj[i] = (int *) NULL;
+                for (i = 0; i < *ncount; i++) {
+                    dat->adj[i] = CC_SAFE_MALLOC (i + 1, int);
+                    if (!dat->adj[i]) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        fclose (datin);
+                        return 1;
+                    }
+                }
+                for (i = 0; i < *ncount; i++) {
+                    for (j = 0; j <= i; j++) {
+                        dat->adj[i][j] = CCutil_readint (datin);
+                    }
+                }
+
+                fclose (datin);
+            }
+        } else {
+            printf ("Complete graph with %d nodes and random edge lengths\n",
+                    *ncount);
+            fflush (stdout);
+            dat->adj = CC_SAFE_MALLOC (*ncount, int *);
+            if (!dat->adj)
+                return 1;
+            for (i = 0; i < *ncount; i++)
+                dat->adj[i] = (int *) NULL;
+            for (i = 0; i < *ncount; i++) {
+                dat->adj[i] = CC_SAFE_MALLOC (i + 1, int);
+                if (!dat->adj[i]) {
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+            }
+            for (i = 0; i < *ncount; i++) {
+                for (j = 0; j < i; j++)
+                    dat->adj[i][j] =
+                        CCutil_lprand () % (MATRAND_SCALE * (*ncount));
+                dat->adj[i][i] = 0;
+            }
+        }
+    } else if (innorm == CC_DSJRANDNORM) {
+        int maxdist, seed;
+        dat->x = CC_SAFE_MALLOC (*ncount, double);
+        if (!dat->x)
+            return 1;
+        for (i = 0; i < *ncount; i++)
+            dat->x[i] = 0x12345672*(i+1) + 1;
+        if (datname != (char *) NULL) {
+            FILE *datin = fopen (datname, "r");
+            if (datin == (FILE *) NULL) {
+                perror (datname);
+                fprintf (stderr, "Unable to open %s for input\n", datname);
+                return 1;
+            }
+            fscanf (datin, "%d", &seed);
+            fscanf (datin, "%d", &maxdist);
+            fclose (datin);
+        } else {
+            seed = 1;
+            maxdist = 1000000;
+        }
+        CCutil_dsjrand_init (maxdist, seed);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_writemaster (char *mastername, int ncount, CCdatagroup *dat,
+            int *perm)
+#else
+int CCutil_writemaster (mastername, ncount, dat, perm)
+char *mastername;
+int ncount;
+CCdatagroup *dat;
+int *perm;
+#endif
+{
+    CC_SFILE *out = (CC_SFILE *) NULL;
+    int i, j;
+
+    if (mastername == (char *) NULL) {
+        fprintf (stderr, "writemaster needs a filename\n");
+        return 1;
+    }
+
+    out = CCutil_sopen (mastername, "w");
+    if (out == (CC_SFILE *) NULL) {
+        fprintf (stderr, "Unable to open %s for output\n", mastername);
+        return 1;
+    }
+
+    if (CCutil_swrite_int (out, (unsigned int) ncount)) {
+        CCutil_sclose (out);
+        return 1;
+    }
+
+    if (dat) {
+        if (CCutil_swrite_int (out, (unsigned int) CC_MASTER_DAT)) {
+            CCutil_sclose (out);
+            return 1;
+        }
+        if (CCutil_swrite_int (out, (unsigned int) dat->norm)) {
+            CCutil_sclose (out);
+            return 1;
+        }
+
+        if (dat->norm == CC_CRYSTAL) {
+            for (i = 0; i < ncount; i++) {
+                if (CCutil_swrite_double (out, dat->x[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+                if (CCutil_swrite_double (out, dat->y[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+                if (CCutil_swrite_double (out, dat->z[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+            }
+        } else if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_D2_NORM_SIZE) {
+            for (i = 0; i < ncount; i++) {
+                if (CCutil_swrite_double (out, dat->x[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+                if (CCutil_swrite_double (out, dat->y[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+            }
+        } else if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+            for (i = 0; i < ncount; i++) {
+                if (CCutil_swrite_double (out, dat->x[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+                if (CCutil_swrite_double (out, dat->y[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+                if (CCutil_swrite_double (out, dat->z[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+            }
+        } else if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_MATRIX_NORM_SIZE){
+            /* Matrix is the lower triangle plus the diagonal */
+            for (i = 0; i < ncount; i++) {
+                for (j = 0; j <= i; j++) {
+                    if (CCutil_swrite_int (out,
+                                (unsigned int) dat->adj[i][j])) {
+                        CCutil_sclose (out);
+                        return 1;
+                    }
+                }
+            }
+        } else if (dat->norm == CC_DSJRANDNORM) {
+            for (i = 0; i < ncount; i++) {
+                if (CCutil_swrite_double (out, dat->x[i])) {
+                    CCutil_sclose (out);
+                    return 1;
+                }
+            }
+        } else {
+            fprintf (stderr, "unknown norm: %d\n", dat->norm);
+            return 1;
+        }
+    } else {
+        if (CCutil_swrite_int (out, (unsigned int) CC_MASTER_NO_DAT)) {
+            CCutil_sclose (out);
+            return 1;
+        }
+    }
+
+    for (i = 0; i < ncount; i++) {
+        if (perm[i] < 0 || perm[i] >= ncount) {
+            fprintf (stderr, "permutation in wrong format\n");
+            CCutil_sclose (out);
+            return 1;
+        }
+        if (CCutil_swrite_int (out, (unsigned int) perm[i])) {
+            CCutil_sclose (out);
+            return 1;
+        }
+    }
+
+    CCutil_sclose (out);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getmaster (char *mastername, int *ncount, CCdatagroup *dat,
+            int **perm)
+#else
+int CCutil_getmaster (mastername, ncount, dat, perm)
+char *mastername;
+int *ncount;
+CCdatagroup *dat;
+int **perm;
+#endif
+{
+    CC_SFILE *in = (CC_SFILE *) NULL;
+    int i, j;
+    int havedat = 0;
+
+    *ncount = 0;
+    dat->x = (double *) NULL;
+    dat->y = (double *) NULL;
+    dat->z = (double *) NULL;
+    dat->adj = (int **) NULL;
+    dat->norm = 0;
+    *perm = (int *) NULL;
+
+    if (mastername == (char *) NULL) {
+        fprintf (stderr, "getmaster needs a filename\n");
+        return 1;
+    }
+
+    in = CCutil_sopen (mastername, "r");
+    if (in == (CC_SFILE *) NULL) {
+        fprintf (stderr, "Unable to open %s for input\n", mastername);
+        return 1;
+    }
+
+    if (CCutil_sread_int (in, (unsigned int *) ncount)) {
+        CCutil_sclose (in);
+        return 1;
+    }
+
+    if (CCutil_sread_int (in, (unsigned int *) &havedat)) {
+        CCutil_sclose (in);
+        return 1;
+    }
+
+    if (havedat == CC_MASTER_DAT) {
+        if (CCutil_sread_int (in, (unsigned int *) &(dat->norm))) {
+            CCutil_sclose (in);
+            return 1;
+        }
+
+        if (dat->norm == CC_CRYSTAL) {
+            dat->x = CC_SAFE_MALLOC (*ncount, double);
+            dat->y = CC_SAFE_MALLOC (*ncount, double);
+            dat->z = CC_SAFE_MALLOC (*ncount, double);
+            if (!dat->x || !dat->y || !dat->z) {
+                fprintf (stderr, "out of memory in getmaster\n");
+                goto CLEANUP;
+            }
+            for (i = 0; i < *ncount; i++) {
+                if (CCutil_sread_double (in, &(dat->x[i]))) goto CLEANUP;
+                if (CCutil_sread_double (in, &(dat->y[i]))) goto CLEANUP;
+                if (CCutil_sread_double (in, &(dat->z[i]))) goto CLEANUP;
+            }
+        } else if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_D2_NORM_SIZE) {
+            dat->x = CC_SAFE_MALLOC (*ncount, double);
+            dat->y = CC_SAFE_MALLOC (*ncount, double);
+            if (!dat->x || !dat->y) {
+                fprintf (stderr, "out of memory in getmaster\n");
+                goto CLEANUP;
+            }
+            for (i = 0; i < *ncount; i++) {
+                if (CCutil_sread_double (in, &(dat->x[i]))) goto CLEANUP;
+                if (CCutil_sread_double (in, &(dat->y[i]))) goto CLEANUP;
+            }
+        } else if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_D3_NORM_SIZE) {
+            dat->x = CC_SAFE_MALLOC (*ncount, double);
+            dat->y = CC_SAFE_MALLOC (*ncount, double);
+            dat->z = CC_SAFE_MALLOC (*ncount, double);
+            if (!dat->x || !dat->y || !dat->z) {
+                fprintf (stderr, "out of memory in getmaster\n");
+                goto CLEANUP;
+            }
+            for (i = 0; i < *ncount; i++) {
+                if (CCutil_sread_double (in, &(dat->x[i]))) goto CLEANUP;
+                if (CCutil_sread_double (in, &(dat->y[i]))) goto CLEANUP;
+                if (CCutil_sread_double (in, &(dat->z[i]))) goto CLEANUP;
+            }
+        } else if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_MATRIX_NORM_SIZE){
+            /* Matrix is the lower triangle plus the diagonal */
+
+            dat->adj = CC_SAFE_MALLOC (*ncount, int *);
+            if (!dat->adj) goto CLEANUP;
+            for (i = 0; i < *ncount; i++)
+                dat->adj[i] = (int *) NULL;
+
+            for (i = 0; i < *ncount; i++) {
+                dat->adj[i] = CC_SAFE_MALLOC (i + 1, int);
+                if (!dat->adj[i]) goto CLEANUP;
+                for (j = 0; j <= i; j++) {
+                    if (CCutil_sread_int (in,
+                          (unsigned int *) &(dat->adj[i][j]))) {
+                        goto CLEANUP;
+                    }
+                }
+            }
+        } else if (dat->norm == CC_DSJRANDNORM) {
+            dat->x = CC_SAFE_MALLOC (*ncount, double);
+            if (!dat->x) {
+                fprintf (stderr, "out of memory in getmaster\n");
+                goto CLEANUP;
+            }
+            for (i = 0; i < *ncount; i++) {
+                if (CCutil_sread_double (in, &(dat->x[i]))) goto CLEANUP;
+            }
+        } else {
+            fprintf (stderr, "unknown norm: %d\n", dat->norm);
+            goto CLEANUP;
+        }
+    }
+
+    *perm = CC_SAFE_MALLOC (*ncount, int);
+    if (!(*perm))  {
+        fprintf (stderr, "out of memory in getmaster\n");
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < *ncount; i++) {
+        if (CCutil_sread_int (in, (unsigned int *) &((*perm)[i]))) goto CLEANUP;
+    }
+
+    CCutil_sclose (in);
+    return 0;
+
+CLEANUP:
+
+    CC_IFFREE (*perm, int);
+    CC_IFFREE (dat->x, double);
+    CC_IFFREE (dat->y, double);
+    CC_IFFREE (dat->z, double);
+    if (dat->adj) {
+        for (i = 0; i < *ncount; i++) {
+            CC_IFFREE (dat->adj[i], int);
+        }
+        CC_FREE (dat->adj, int *);
+    }
+
+    CCutil_sclose (in);
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getnodeweights (char *weightname, int ncount, int weight_limit,
+                    double **wcoord)
+#else
+int CCutil_getnodeweights (weightname, ncount, weight_limit, wcoord)
+char *weightname;
+int ncount, weight_limit;
+double **wcoord;
+#endif
+{
+    int i, k;
+
+    *wcoord = CC_SAFE_MALLOC (ncount, double);
+    if (!(*wcoord))
+        return 1;
+    if (weightname != (char *) NULL) {
+        FILE *weightin = fopen (weightname, "r");
+        if (weightin == (FILE *) NULL) {
+            perror (weightname);
+            fprintf (stderr, "Unable to open %s for input\n", weightname);
+            CC_FREE (*wcoord, double);
+            return 1;
+        }
+        fscanf (weightin, "%d", &k);
+        if (k != ncount) {
+            fprintf (stderr, "Weight file does not match node file\n");
+            fclose (weightin);
+            CC_FREE (*wcoord, double);
+            return 1;
+        }
+        for (i = 0; i < k; i++) {
+            fscanf (weightin, "%lf", &((*wcoord)[i]));
+        }
+        make_weights_nonnegative (ncount, *wcoord);
+        fclose (weightin);
+    } else {
+        for (i = 0; i < ncount; i++)
+            (*wcoord)[i] = (double) (CCutil_lprand () % (weight_limit));
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void make_weights_nonnegative (int ncount, double *wcoord)
+#else
+static void make_weights_nonnegative (ncount, wcoord)
+int ncount;
+double *wcoord;
+#endif
+{
+    int i;
+    double minx;
+
+    minx = wcoord[0];
+
+    for (i = 1; i < ncount; i++) {
+        if (wcoord[i] < minx)
+            minx = wcoord[i];
+    }
+    if (minx < 0.0) {
+        printf ("****WARNING**** Adjusting node weights by %f\n", minx);
+        for (i = 0; i < ncount; i++)
+            wcoord[i] -= minx;
+    }
+}
+
+#define MATRIX_LOWER_DIAG_ROW  0
+#define MATRIX_UPPER_ROW       1
+#define MATRIX_UPPER_DIAG_ROW  2
+#define MATRIX_FULL_MATRIX     3
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_gettsplib (char *datname, int *ncount, CCdatagroup *dat)
+#else
+int CCutil_gettsplib (datname, ncount, dat)
+char *datname;
+int *ncount;
+CCdatagroup *dat;
+#endif
+{
+    char buf[256], key[256], field[256];
+    char *p;
+    FILE *in;
+    int matrixform = MATRIX_LOWER_DIAG_ROW;
+
+    dat->x = (double *) NULL;
+    dat->y = (double *) NULL;
+    dat->z = (double *) NULL;
+    dat->adj = (int **) NULL;
+    dat->norm = -1;
+    *ncount = -1;
+
+    if ((in = fopen (datname, "r")) == (FILE *) NULL) {
+        perror (datname);
+        fprintf (stderr, "Unable to open %s for input\n", datname);
+        return 1;
+    }
+
+    while (fgets (buf, 254, in) != (char *) NULL) {
+        p = buf;
+        while (*p != '\0') {
+            if (*p == ':')
+                *p = ' ';
+            p++;
+        }
+        p = buf;
+        if (sscanf (p, "%s", key) != EOF) {
+            p += strlen (key);
+            while (*p == ' ')
+                p++;
+            if (!strcmp (key, "NAME")) {
+                printf ("Problem Name: %s", p);
+            } else if (!strcmp (key, "TYPE")) {
+                printf ("Problem Type: %s", p);
+                if (sscanf (p, "%s", field) == EOF || strcmp (field, "TSP")) {
+                    fprintf (stderr, "Not a TSP problem\n");
+                    return 1;
+                }
+            } else if (!strcmp (key, "COMMENT")) {
+                printf ("%s", p);
+            } else if (!strcmp (key, "DIMENSION")) {
+                if (sscanf (p, "%s", field) == EOF) {
+                    fprintf (stderr, "ERROR in DIMENSION line\n");
+                    return 1;
+                }
+                *ncount = atoi (field);
+                printf ("Number of Nodes: %d\n", *ncount);
+            } else if (!strcmp (key, "EDGE_WEIGHT_TYPE")) {
+                if (sscanf (p, "%s", field) == EOF) {
+                    fprintf (stderr, "ERROR in EDGE_WEIGHT_TYPE line\n");
+                    return 1;
+                }
+                if (!strcmp (field, "EXPLICIT")) {
+                    dat->norm = CC_MATRIXNORM;
+                    printf ("Explicit Lengths (CC_MATRIXNORM)\n");
+                } else if (!strcmp (field, "EUC_2D")) {
+                    dat->norm = CC_EUCLIDEAN;
+                    printf ("Rounded Euclidean Norm (CC_EUCLIDEAN)\n");
+                } else if (!strcmp (field, "EUC_3D")) {
+                    dat->norm = CC_EUCLIDEAN_3D;
+                    printf ("Rounded Euclidean 3D Norm (CC_EUCLIDEAN_3D)\n");
+                } else if (!strcmp (field, "MAX_2D")) {
+                    dat->norm = CC_MAXNORM;
+                    printf ("Max Norm (CC_MAXNORM)\n");
+                } else if (!strcmp (field, "GEO")) {
+                    dat->norm = CC_GEOGRAPHIC;
+                    printf ("Geographical Norm (CC_GEOGRAPHIC)\n");
+                } else if (!strcmp (field, "ATT")) {
+                    dat->norm = CC_ATT;
+                    printf ("ATT Norm (ATT)\n");
+                } else if (!strcmp (field, "CEIL_2D")) {
+                    dat->norm = CC_EUCLIDEAN_CEIL;
+                    printf ("Rounded Up Euclidean Norm (CC_EUCLIDEAN_CEIL)\n");
+                } else {
+                    fprintf (stderr, "ERROR: Not set up for norm %s\n", field);
+                    return 1;
+                }
+            } else if (!strcmp (key, "EDGE_WEIGHT_FORMAT")) {
+                if (sscanf (p, "%s", field) == EOF) {
+                    fprintf (stderr, "ERROR in EDGE_WEIGHT_FORMAT line\n");
+                    return 1;
+                }
+                if (!strcmp (field, "LOWER_DIAG_ROW")) {
+                    matrixform = MATRIX_LOWER_DIAG_ROW;
+                } else if (!strcmp (field, "UPPER_ROW")) {
+                    matrixform = MATRIX_UPPER_ROW;
+                } else if (!strcmp (field, "UPPER_DIAG_ROW")) {
+                    matrixform = MATRIX_UPPER_DIAG_ROW;
+                } else if (!strcmp (field, "FULL_MATRIX")) {
+                    matrixform = MATRIX_FULL_MATRIX;
+                } else if (strcmp (field, "FUNCTION")) {
+                    fprintf (stderr, "Cannot handle format: %s\n", field);
+                    return 1;
+                }
+            } else if (!strcmp (key, "NODE_COORD_SECTION")) {
+                int i;
+                if (*ncount <= 0) {
+                    fprintf (stderr, "ERROR: Dimension not specified\n");
+                    return 1;
+                }
+                if (dat->x != (double *) NULL) {
+                    fprintf (stderr, "ERROR: A second NODE_COORD_SECTION?\n");
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+                if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_D2_NORM_SIZE) {
+                    dat->x = CC_SAFE_MALLOC (*ncount, double);
+                    if (!dat->x) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    dat->y = CC_SAFE_MALLOC (*ncount, double);
+                    if (!dat->y) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    for (i = 0; i < *ncount; i++) {
+                        fscanf (in, "%*d %lf %lf", &(dat->x[i]), &(dat->y[i]));
+                    }
+                } else if (((dat->norm) & CC_NORM_SIZE_BITS) ==
+                                            CC_D3_NORM_SIZE) {
+                    dat->x = CC_SAFE_MALLOC (*ncount, double);
+                    if (!dat->x) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    dat->y = CC_SAFE_MALLOC (*ncount, double);
+                    if (!dat->y) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    dat->z = CC_SAFE_MALLOC (*ncount, double);
+                    if (!dat->z) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    for (i = 0; i < *ncount; i++) {
+                        fscanf (in, "%*d %lf %lf %lf",
+                               &(dat->x[i]), &(dat->y[i]), &(dat->z[i]));
+                    }
+                } else {
+                    fprintf (stderr, "ERROR: Node coordinates with norm %d?\n",
+                                 dat->norm);
+                    return 1;
+                }
+            } else if (!strcmp (key, "EDGE_WEIGHT_SECTION")) {
+                int i, j;
+                if (*ncount <= 0) {
+                    fprintf (stderr, "ERROR: Dimension not specified\n");
+                    return 1;
+                }
+                if (dat->adj != (int **) NULL) {
+                    fprintf (stderr, "ERROR: A second NODE_COORD_SECTION?\n");
+                    CCutil_freedatagroup (*ncount, dat);
+                    return 1;
+                }
+                if (((dat->norm) & CC_NORM_SIZE_BITS) == CC_MATRIX_NORM_SIZE) {
+                    dat->adj = CC_SAFE_MALLOC (*ncount, int *);
+                    if (!dat->adj) {
+                        CCutil_freedatagroup (*ncount, dat);
+                        return 1;
+                    }
+                    if (matrixform == MATRIX_LOWER_DIAG_ROW) {
+                        for (i = 0; i < *ncount; i++) {
+                            dat->adj[i] = CC_SAFE_MALLOC (i + 1, int);
+                            if (!dat->adj[i]) {
+                                CCutil_freedatagroup (*ncount, dat);
+                                return 1;
+                            }
+                            for (j = 0; j <= i; j++)
+                                fscanf (in, "%d", &(dat->adj[i][j]));
+                        }
+                    } else if (matrixform == MATRIX_UPPER_ROW ||
+                               matrixform == MATRIX_UPPER_DIAG_ROW ||
+                               matrixform == MATRIX_FULL_MATRIX) {
+                        int **tempadj;
+                        tempadj = CC_SAFE_MALLOC (*ncount, int *);
+                        if (!tempadj) {
+                            CCutil_freedatagroup (*ncount, dat);
+                            return 1;
+                        }
+                        for (i = 0; i < *ncount; i++) {
+                            tempadj[i] = CC_SAFE_MALLOC (*ncount, int);
+                            if (!tempadj[i]) {
+                                CCutil_freedatagroup (*ncount, dat);
+                                for (j = 0; j < i; j++)
+                                    CC_FREE (tempadj[j], int);
+                                CC_FREE (tempadj, int *);
+                                return 1;
+                            }
+                            if (matrixform == MATRIX_UPPER_ROW) {
+                                tempadj[i][i] = 0;
+                                for (j = i + 1; j < *ncount; j++)
+                                    fscanf (in, "%d", &(tempadj[i][j]));
+                            } else if (matrixform == MATRIX_UPPER_DIAG_ROW) {
+                                for (j = i; j < *ncount; j++)
+                                    fscanf (in, "%d", &(tempadj[i][j]));
+                            } else {
+                                for (j = 0; j < *ncount; j++)
+                                    fscanf (in, "%d", &(tempadj[i][j]));
+                            }
+                        }
+                        for (i = 0; i < *ncount; i++) {
+                            dat->adj[i] = CC_SAFE_MALLOC (i + 1, int);
+                            if (!dat->adj[i]) {
+                                CCutil_freedatagroup (*ncount, dat);
+                                for (j = 0; j < *ncount; j++)
+                                    CC_FREE (tempadj[j], int);
+                                CC_FREE (tempadj, int *);
+                                return 1;
+                            }
+                            for (j = 0; j <= i; j++)
+                                dat->adj[i][j] = tempadj[j][i];
+                        }
+                        for (i = 0; i < *ncount; i++)
+                            CC_FREE (tempadj[i], int);
+                        CC_FREE (tempadj, int *);
+                    }
+                } else {
+                    fprintf (stderr, "ERROR: Matrix with norm %d?\n",
+                             dat->norm);
+                    return 1;
+                }
+            } else if (!strcmp (key, "FIXED_EDGES_SECTION")) {
+                fprintf (stderr, "ERROR: Not set up for fixed edges\n");
+                return 1;
+            }
+        }
+    }
+    fclose (in);
+
+    if (dat->x == (double *) NULL && dat->adj == (int **) NULL) {
+        fprintf (stderr, "ERROR: Didn't find the data\n");
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_datagroup_perm (int ncount, CCdatagroup *dat, int *perm)
+#else
+int CCutil_datagroup_perm (ncount, dat, perm)
+int ncount;
+CCdatagroup *dat;
+int *perm;
+#endif
+{
+    int i, j;
+
+    if (dat->x != (double *) NULL) {
+        double *tempx;
+
+        tempx = CC_SAFE_MALLOC (ncount, double);
+        if (!tempx)
+            return 1;
+        for (i = 0; i < ncount; i++) {
+            tempx[i] = dat->x[perm[i]];
+        }
+        CC_FREE (dat->x, double);
+        dat->x = tempx;
+    }
+    if (dat->y != (double *) NULL) {
+        double *tempy;
+
+        tempy = CC_SAFE_MALLOC (ncount, double);
+        if (!tempy)
+            return 1;
+        for (i = 0; i < ncount; i++) {
+            tempy[i] = dat->y[perm[i]];
+        }
+        CC_FREE (dat->y, double);
+        dat->y = tempy;
+    }
+    if (dat->z != (double *) NULL) {
+        double *tempz;
+
+        tempz = CC_SAFE_MALLOC (ncount, double);
+        if (!tempz)
+            return 1;
+        for (i = 0; i < ncount; i++) {
+            tempz[i] = dat->z[perm[i]];
+        }
+        CC_FREE (dat->z, double);
+        dat->z = tempz;
+    }
+    if (dat->adj != (int **) NULL) {
+        int **tempadj;
+
+        tempadj = CC_SAFE_MALLOC (ncount, int *);
+        if (!tempadj)
+            return 1;
+
+        for (i = 0; i < ncount; i++) {
+            tempadj[i] = CC_SAFE_MALLOC (i + 1, int);
+            if (!tempadj[i]) {
+                for (j = 0; j < i; j++) {
+                    CC_FREE (tempadj[j], int);
+                }
+                CC_FREE (tempadj, int *);
+                return 1;
+            }
+            for (j = 0; j <= i; j++) {
+                if (perm[i] <  perm[j])
+                    tempadj[i][j] = dat->adj[perm[j]][perm[i]];
+                else
+                    tempadj[i][j] = dat->adj[perm[i]][perm[j]];
+            }
+        }
+        for (i = 0; i < ncount; i++)
+            CC_FREE (dat->adj[i], int);
+        CC_FREE (dat->adj, int *);
+        dat->adj = tempadj;
+    }
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getedgelist (int ncount, char *fname, int *ecount, int **elist,
+            int **elen)
+#else
+int CCutil_getedgelist (ncount, fname, ecount, elist, elen)
+int ncount;
+char *fname;
+int *ecount, **elist, **elen;
+#endif
+{
+    int k;
+
+    if (CCutil_getedgelist_n (&k, fname, ecount, elist, elen)) {
+        fprintf (stderr, "CCutil_getedgelist_n failed\n");
+        return 1;
+    }
+
+    if (k != ncount) {
+        fprintf (stderr, "Edge file does not match problem\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getedgelist_n (int *ncount, char *fname, int *ecount, int **elist,
+                   int **elen)
+#else
+int CCutil_getedgelist_n (ncount, fname, ecount, elist, elen)
+int *ncount;
+char *fname;
+int *ecount, **elist, **elen;
+#endif
+{
+    FILE *in;
+    int i, k;
+
+    *elist = (int *) NULL;
+    *elen = (int *) NULL;
+
+    if ((in = fopen (fname, "r")) == (FILE *) NULL) {
+        perror (fname);
+        fprintf (stderr, "Unable to open %s for input\n", fname);
+        return 1;
+    }
+
+    k = CCutil_readint (in);
+    *ncount = k;
+    *ecount = CCutil_readint (in);
+
+    *elist = CC_SAFE_MALLOC(2 * (*ecount), int);
+    if (!(*elist)) {
+        fprintf (stderr, "out of memory in getedgelist\n");
+        fclose (in);
+        return 1;
+    }
+    *elen = CC_SAFE_MALLOC(*ecount, int);
+    if (!(*elen)) {
+        fprintf (stderr, "out of memory in getedgelist\n");
+        CC_FREE (*elist, int);
+        fclose (in);
+        return 1;
+    }
+
+    for (i = 0, k = 0; i < *ecount; i++) {
+        (*elist)[k++] = CCutil_readint (in);
+        (*elist)[k++] = CCutil_readint (in);
+        (*elen)[i] = CCutil_readint (in);
+    }
+
+    fclose (in);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getcycle_edgelist (int ncount, char *cyclename, int *outcycle)
+#else
+int CCutil_getcycle_edgelist (ncount, cyclename, outcycle)
+int ncount;
+char *cyclename;
+int *outcycle;
+#endif
+{
+    FILE *cycin = fopen (cyclename, "r");
+    int *elist = (int *) NULL;
+    int i, k;
+
+    if (cycin == (FILE *) NULL) {
+        perror (cyclename);
+        fprintf (stderr, "Unable to open %s for input\n", cyclename);
+        return 1;
+    }
+    elist = CC_SAFE_MALLOC (2 * ncount, int);
+    if (!elist) {
+        fclose (cycin);
+        return 1;
+    }
+
+    fscanf (cycin, "%d %d", &i, &k);
+    if (i != ncount || k != ncount) {
+        fprintf (stderr, "file is not a cycle-edge file for this problem\n");
+        CC_FREE (elist, int);
+        fclose (cycin);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++)
+        fscanf (cycin, "%d %d %*d", &(elist[2 * i]), &(elist[(2 * i) + 1]));
+
+    if (CCutil_edge_to_cycle (ncount, elist, outcycle)) {
+        fprintf (stderr, "CCutil_edge_to_cycle failed\n");
+        CC_FREE (elist, int);
+        fclose (cycin);
+        return 1;
+    }
+
+    CC_FREE (elist, int);
+    fclose (cycin);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getcycle (int ncount, char *cyclename, int *outcycle)
+#else
+int CCutil_getcycle (ncount, cyclename, outcycle)
+int ncount;
+char *cyclename;
+int *outcycle;
+#endif
+{
+    FILE *cycin = fopen (cyclename, "r");
+    int i;
+
+    if (cycin == (FILE *) NULL) {
+        perror (cyclename);
+        fprintf (stderr, "Unable to open %s for input\n", cyclename);
+        return 1;
+    }
+
+    i = CCutil_readint (cycin);
+    if (i != ncount) {
+        fprintf (stderr, "Cycle files has wrong number of nodes\n");
+        return 1;
+    }
+    for (i = 0; i < ncount; i++)
+        outcycle[i] = CCutil_readint (cycin);
+
+    fclose (cycin);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_getedges_double (int *ncount, char *fname, int *ecount, int **elist,
+            double **elen, int binary_in)
+#else
+int CCutil_getedges_double (ncount, fname, ecount, elist, elen, binary_in)
+int *ncount;
+char *fname;
+int *ecount, **elist;
+double **elen;
+int binary_in;
+#endif
+{
+    int i, k;
+
+    if (binary_in) {
+        CC_SFILE *in;
+
+        *elist = (int *) NULL;
+        *elen = (double *) NULL;
+
+        if ((in = CCutil_sopen (fname, "r")) == (CC_SFILE *) NULL) {
+            fprintf (stderr, "Unable to open %s for input\n", fname);
+            return 1;
+        }
+
+        if (CCutil_sread_int (in, (unsigned int *) ncount)) {
+            CCutil_sclose (in);
+            return 1;
+        }
+
+        if (CCutil_sread_int (in, (unsigned int *) ecount)) {
+            CCutil_sclose (in);
+            return 1;
+        }
+
+        *elist = CC_SAFE_MALLOC(2 * (*ecount), int);
+        if (!(*elist)) {
+            CCutil_sclose (in);
+            return 1;
+        }
+        *elen = CC_SAFE_MALLOC(*ecount, double);
+        if (!(*elen)) {
+            CC_FREE (*elist, int);
+            CCutil_sclose (in);
+            return 1;
+        }
+
+        for (i = 0, k = 0; i < *ecount; i++) {
+            if (CCutil_sread_int (in, (unsigned int *) &((*elist)[k++]))) {
+                CCutil_sclose (in);
+                return 1;
+            }
+            if (CCutil_sread_int (in, (unsigned int *) &((*elist)[k++]))) {
+                CCutil_sclose (in);
+                return 1;
+            }
+            if (CCutil_sread_double (in, &((*elen)[i]))) {
+                CCutil_sclose (in);
+                return 1;
+            }
+        }
+
+        CCutil_sclose (in);
+    } else {
+        FILE *in;
+
+        *elist = (int *) NULL;
+        *elen = (double *) NULL;
+
+        if ((in = fopen (fname, "r")) == (FILE *) NULL) {
+            perror (fname);
+            fprintf (stderr, "Unable to open %s for input\n", fname);
+            return 1;
+        }
+
+        *ncount = CCutil_readint (in);
+        *ecount = CCutil_readint (in);
+
+        *elist = CC_SAFE_MALLOC(2 * (*ecount), int);
+        if (!(*elist)) {
+            fclose (in);
+            return 1;
+        }
+        *elen = CC_SAFE_MALLOC(*ecount, double);
+        if (!(*elen)) {
+            CC_FREE (*elist, int);
+            fclose (in);
+            return 1;
+        }
+
+        for (i = 0, k = 0; i < *ecount; i++) {
+            (*elist)[k++] = CCutil_readint (in);
+            (*elist)[k++] = CCutil_readint (in);
+            if (fscanf (in, "%lf", &((*elen)[i])) != 1) {
+                fprintf (stderr, "input file is in the wrong format\n");
+                fclose (in);
+                return 1;
+            }
+        }
+
+        fclose (in);
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_writeedges (int ncount, char *outedgename, int ecount, int *elist,
+            CCdatagroup *dat)
+#else
+int CCutil_writeedges (ncount, outedgename, ecount, elist, dat)
+int ncount;
+char *outedgename;
+int ecount, *elist;
+CCdatagroup *dat;
+#endif
+{
+    FILE *out = fopen (outedgename, "w");
+    int i;
+
+    if (out == (FILE *) NULL) {
+        perror (outedgename);
+        fprintf (stderr, "Unable to open %s for output\n", outedgename);
+        return 1;
+    }
+
+    fprintf (out, "%d %d\n", ncount, ecount);
+    for (i = 0; i < ecount; i++) {
+        fprintf (out, "%d %d %d\n", elist[2 * i], elist[(2 * i) + 1],
+                CCutil_dat_edgelen (elist[2 * i], elist[(2 * i) + 1], dat));
+    }
+    fclose (out);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_writecycle_edgelist (int ncount, char *outedgename, int *cycle,
+            CCdatagroup *dat)
+#else
+int CCutil_writecycle_edgelist (ncount, outedgename, cycle, dat)
+int ncount;
+char *outedgename;
+int *cycle;
+CCdatagroup *dat;
+#endif
+{
+    FILE *out = fopen (outedgename, "w");
+    int i;
+
+    if (out == (FILE *) NULL) {
+        perror (outedgename);
+        fprintf (stderr, "Unable to open %s for output\n", outedgename);
+        return 1;
+    }
+
+    fprintf (out, "%d %d\n", ncount, ncount);
+    for (i = 1; i < ncount; i++) {
+        fprintf (out, "%d %d %d\n", cycle[i - 1], cycle[i],
+                    CCutil_dat_edgelen (cycle[i - 1], cycle[i], dat));
+    }
+    fprintf (out, "%d %d %d\n", cycle[ncount - 1], cycle[0],
+                   CCutil_dat_edgelen (cycle[ncount - 1], cycle[0], dat));
+    fclose (out);
+
+    return 0;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_writecycle (int ncount, char *outcyclename, int *cycle)
+#else
+int CCutil_writecycle (ncount, outcyclename, cycle)
+int ncount;
+char *outcyclename;
+int *cycle;
+#endif
+{
+    FILE *cycout = fopen (outcyclename, "w");
+    int i;
+
+    if (cycout == (FILE *) NULL) {
+        perror (outcyclename);
+        fprintf (stderr, "Unable to open %s for output\n", outcyclename);
+        return 1;
+    }
+
+    fprintf (cycout, "%d\n", ncount);
+    for (i = 0; i < ncount; i++) {
+        fprintf (cycout, "%d ", cycle[i]);
+        if (i % 10 == 9)
+            fprintf (cycout, "\n");
+    }
+    if (i % 10)
+        fprintf (cycout, "\n");
+    fclose (cycout);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_writeedges_double (int ncount, char *outedgename, int ecount,
+                int *elist, double *elen, int binary_out)
+#else
+int CCutil_writeedges_double (ncount, outedgename, ecount, elist, elen, binary_out)
+int ncount;
+char *outedgename;
+int ecount, *elist;
+double *elen;
+int binary_out;
+#endif
+{
+    int i;
+
+    if (binary_out) {
+        CC_SFILE *out = CCutil_sopen (outedgename, "w");
+
+        if (out == (CC_SFILE *) NULL) {
+            fprintf (stderr, "Unable to open %s for output\n", outedgename);
+            return 1;
+        }
+
+        if (CCutil_swrite_int (out, (unsigned int) ncount)) {
+            CCutil_sclose (out);
+            return 1;
+        }
+        if (CCutil_swrite_int (out, (unsigned int) ecount)) {
+            CCutil_sclose (out);
+            return 1;
+        }
+
+        for (i = 0; i < ecount; i++) {
+            if (CCutil_swrite_int (out, (unsigned int) elist[2 * i])) {
+                CCutil_sclose (out);
+                return 1;
+            }
+            if (CCutil_swrite_int (out, (unsigned int) elist[(2 * i) + 1])) {
+                CCutil_sclose (out);
+                return 1;
+            }
+            if (CCutil_swrite_double (out, elen[i])) {
+                CCutil_sclose (out);
+                return 1;
+            }
+        }
+        CCutil_sclose (out);
+    } else {
+        FILE *out = fopen (outedgename, "w");
+
+        if (out == (FILE *) NULL) {
+            perror (outedgename);
+            fprintf (stderr, "Unable to open %s for output\n", outedgename);
+            return 1;
+        }
+
+        fprintf (out, "%d %d\n", ncount, ecount);
+        for (i = 0; i < ecount; i++) {
+            fprintf (out, "%d %d %f\n", elist[2 * i], elist[(2 * i) + 1],
+                                        elen[i]);
+        }
+        fclose (out);
+    }
+
+    return 0;
+}
+
+
+
+/* The crystal functions are based on David Shallcross's fortran code */
+
+#define CRYSTAL_SCALE 10000
+
+typedef struct three_d {
+    double phi;
+    double chi;
+    double twoth;
+} three_d;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    cry_quicksort (three_d *x, int l, int u),
+    cryswap (three_d *x, three_d *y);
+static int
+    point_compare (three_d *x, three_d *y),
+    crygenpts (double orient[3][3], double lambda, int bounds[3][2]),
+    cryangles (int h, int k, int l, double orient[3][3], double lambda,
+            double omega, double *phi, double *chi, double *twoth);
+static double
+    userint (double f);
+
+#else
+
+static void
+    cry_quicksort (),
+    cryswap ();
+static int
+    point_compare (),
+    crygenpts (),
+    cryangles ();
+static double
+    userint ();
+
+#endif
+
+
+static three_d *crypoints = (three_d *) NULL;
+static int ncrypoints = 0;
+
+#define CRY_MIN_ORIENT -0.2    /* For random problems */
+#define CRY_MAX_ORIENT  0.2
+
+#define CRY_MIN_BOUND  10
+#define CRY_MAX_BOUND  20
+
+#define CRY_1_00_CUTOFF 15000
+#define CRY_1_35_CUTOFF 10000
+
+#ifdef CC_PROTOTYPE_ANSI
+static int read_crystal (char *datname, int *ncount, CCdatagroup *dat)
+#else
+static int read_crystal (datname, ncount, dat)
+char *datname;
+int *ncount;
+CCdatagroup *dat;
+#endif
+{
+    FILE *datin;
+    double lambda;
+    double orient[3][3];
+    int bounds[3][2];
+    int i, j;
+
+    if (!datname) {
+        for (i = 0; i < 3; i++) {
+            for (j = 0; j < 3; j++) {
+                orient[i][j] = CRY_MIN_ORIENT +
+                   ((CRY_MAX_ORIENT - CRY_MIN_ORIENT) *
+                    ((double) (CCutil_lprand () % 1000) / 1000.0));
+            }
+        }
+        for (i = 0; i < 3; i++) {
+            bounds[i][1] = CRY_MIN_BOUND +
+                       (CCutil_lprand () % (CRY_MAX_BOUND - CRY_MIN_BOUND + 1));
+            bounds[i][0] = -bounds[i][1];
+        }
+
+        if (*ncount > CRY_1_00_CUTOFF)
+            lambda = 1.0;
+        else if (*ncount > CRY_1_35_CUTOFF)
+            lambda = 1.35;
+        else
+            lambda = 1.70;
+
+        printf ("Random crystal problem\n");
+        printf ("Note that the number of nodes will not match the request\n");
+        printf ("Orient:\n");
+        for (i = 0; i < 3; i++)
+            printf (" %.4f  %.4f  %.4f\n", orient[i][0], orient[i][1],
+                                                         orient[i][2]);
+        printf ("Bounds:\n");
+        for (i = 0; i < 3; i++)
+            printf (" %d %d ", bounds[i][0], bounds[i][1]);
+        printf ("\nWavelength:\n");
+            printf (" %.2f\n", lambda);
+        fflush (stdout);
+    } else {
+        datin = fopen (datname, "r");
+        if (datin == (FILE *) NULL) {
+            perror (datname);
+            fprintf (stderr, "Unable to open %s for input\n", datname);
+            return 1;
+        }
+
+        for (i = 0; i < 3; i++) {
+            for (j = 0; j < 3; j++) {
+                fscanf (datin, "%lf", &orient[i][j]);
+            }
+        }
+        fscanf (datin, "%lf", &lambda);
+        for (i = 0; i < 3; i++) {
+            for (j = 0; j < 2; j++) {
+                fscanf (datin, "%d", &(bounds[i][j]));
+            }
+        }
+        fclose (datin);
+    }
+
+    if (crygenpts (orient, lambda, bounds)) {
+        fprintf (stderr, "crygenpts failed\n");
+        if (crypoints)
+            CC_FREE (crypoints, three_d);
+        return 1;
+    }
+    cry_quicksort (crypoints, 0, ncrypoints -1);
+    printf ("Number of crystal points: %d\n", ncrypoints);
+
+    dat->x = CC_SAFE_MALLOC (ncrypoints, double);
+    if (!dat->x) {
+        CC_FREE (crypoints, three_d);
+        return 1;
+    }
+    dat->y = CC_SAFE_MALLOC (ncrypoints, double);
+    if (!dat->y) {
+        CC_FREE (crypoints, three_d);
+        CCutil_freedatagroup (ncrypoints, dat);
+        return 1;
+    }
+    dat->z = CC_SAFE_MALLOC (ncrypoints, double);
+    if (!dat->z) {
+        CC_FREE (crypoints, three_d);
+        CCutil_freedatagroup (ncrypoints, dat);
+        return 1;
+    }
+
+    for (i = 0; i < ncrypoints; i++) {
+        dat->x[i] = userint (crypoints[i].chi * CRYSTAL_SCALE),
+        dat->y[i] = userint (crypoints[i].phi * CRYSTAL_SCALE),
+        dat->z[i] = userint (crypoints[i].twoth * CRYSTAL_SCALE);
+    }
+    *ncount = ncrypoints;
+
+    if (crypoints)
+        CC_FREE (crypoints, three_d);
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int point_compare (three_d *x, three_d *y)
+#else
+static int point_compare (x, y)
+three_d *x;
+three_d *y;
+#endif
+{
+    int del;
+
+    del = (int) userint (x->chi * CRYSTAL_SCALE) -
+          (int) userint (y->chi * CRYSTAL_SCALE);
+    if (del)
+        return del;
+    del = (int) userint (x->phi * CRYSTAL_SCALE) -
+          (int) userint (y->phi * CRYSTAL_SCALE);
+    if (del)
+        return del;
+    del = (int) userint (x->twoth * CRYSTAL_SCALE) -
+          (int) userint (y->twoth * CRYSTAL_SCALE);
+    return del;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double userint (double f)
+#else
+static double userint (f)
+double f;
+#endif
+{
+    double t;
+    int u;
+
+    if (f > 0.0) {
+        u = (int) f;
+        t = (double) u;
+        return (f - t < 0.5 ? t : t + 1.0);
+    } else {
+        u = (int) f;
+        t = (double) u;
+        return (t - f < 0.5 ? t : t - 1.0);
+    }
+}
+
+
+/* genpts builds points, the array of accessible points of the lattice */
+
+#ifdef CC_PROTOTYPE_ANSI
+static int crygenpts (double orient[3][3], double lambda, int bounds[3][2])
+#else
+static int crygenpts (orient, lambda, bounds)
+double orient[3][3];
+double lambda;
+int bounds[3][2];
+#endif
+{
+    int h, k, l;
+    double p = 0.0, c = 0.0, t = 0.0;
+    double minp = 360.0, minc = 180.0, mint = 155.0;
+    double maxp = 0.0, maxc = -180.0, maxt = -55.0;
+
+    ncrypoints = 0;
+
+    crypoints = CC_SAFE_MALLOC (100000, three_d);
+    if (!crypoints)
+        return 1;
+
+    for (h = bounds[0][0]; h <= bounds[0][1]; h++) {
+        for (k = bounds[1][0]; k <= bounds[1][1]; k++) {
+            for (l = bounds[2][0]; l <= bounds[2][1]; l++) {
+                if (cryangles (h, k, l, orient, lambda, 0.0, &p, &c, &t)) {
+                    crypoints[ncrypoints].phi = p;
+                    crypoints[ncrypoints].chi = c;
+                    crypoints[ncrypoints].twoth = t;
+                    ncrypoints++;
+                    if (p < minp)
+                        minp = p;
+                    if (p > maxp)
+                        maxp = p;
+                    if (c < minc)
+                        minc = c;
+                    if (c > maxc)
+                        maxc = c;
+                    if (t < mint)
+                        mint = t;
+                    if (t > maxt)
+                        maxt = t;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+/*
+   angles computes positioning information for the detector given the
+   miller indices.  (From Matt Small, April 5, 1984)
+*/
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cryangles (int h, int k, int l, double orient[3][3], double lambda,
+                  double omega, double *phi, double *chi, double *twoth)
+#else
+static int cryangles (h, k, l, orient, lambda, omega, phi, chi, twoth)
+int h, k, l;
+double lambda, omega;
+double orient[3][3];
+double *phi, *chi, *twoth;
+#endif
+{
+    /* The original had pi = 3.14159265368979; */
+    static double pi = 3.14159265358979;
+    double x, y, z, d, dum, cosomg, sinchi, sinphi, cosphi, q, r;
+    double rh = h, rk = k, rl = l;
+    double t1, t2, t3;
+
+    omega = omega / 180.0 * pi;
+    cosomg = cos (omega);
+
+    x = orient[0][0] * rh + orient[0][1] * rk + orient[0][2] * rl;
+    y = orient[1][0] * rh + orient[1][1] * rk + orient[1][2] * rl;
+    z = orient[2][0] * rh + orient[2][1] * rk + orient[2][2] * rl;
+    d = sqrt (x * x + y * y + z * z);
+    dum = lambda * d / 2.0;
+    if (dum < .000001 || dum >= 1.0) {
+        return 0;
+    }
+    *twoth = asin (dum) * 2.0;
+    t1 = x / d;
+    t2 = y / d;
+    t3 = z / d;
+    if ((t3 < 0.0 ? -t3 : t3) >= (cosomg < 0.0 ? -cosomg : cosomg)) {
+        return 0;
+    }
+    sinchi = -t3 / cosomg;
+    *chi = asin (sinchi);
+    q = sin (omega);
+    r = cosomg * cos (*chi);
+    cosphi = (q * t1 + r * t2) / (t1 * t1 + t2 * t2);
+    sinphi = (r * t1 - q * t2) / (t1 * t1 + t2 * t2);
+    if (sinphi <= -.7)
+        *phi = -acos (cosphi);
+    else if (sinphi >= .7)
+        *phi = acos (cosphi);
+    else if (cosphi <= 0.0)
+        *phi = pi - asin (sinphi);
+    else
+        *phi = asin (sinphi);
+    *phi *= 180.0 / pi;
+    *chi *= 180.0 / pi;
+    *twoth *= 180.0 / pi;
+    *phi /= 1.25;   /* FOR VARYING MORTOR SPEEDS */
+    *chi /= 1.5;
+    *twoth /= 1.15;
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void cry_quicksort (three_d *x, int l, int u)
+#else
+static void cry_quicksort (x, l, u)
+three_d *x;
+int l, u;
+#endif
+{
+    int i, j;
+    three_d *t;
+
+    if (l >= u)
+        return;
+
+    cryswap (x + l, x + ((l+u)/2));
+
+    i = l;
+    j = u + 1;
+    t = x + l;
+
+    while (1) {
+        do i++; while (i <= u && (point_compare (x + i, t) < 0));
+        do j--; while (point_compare (x + j, t) > 0);
+        if (j < i) break;
+        cryswap (x + i, x + j);
+    }
+    cryswap (x + l, x + j);
+    cry_quicksort (x, l, j - 1);
+    cry_quicksort (x, i, u);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void cryswap (three_d *x, three_d *y)
+#else
+static void cryswap (x, y)
+three_d *x, *y;
+#endif
+{
+    three_d t;
+
+    t.phi = x->phi;
+    t.chi = x->chi;
+    t.twoth = x->twoth;
+
+    x->phi = y->phi;
+    x->chi = y->chi;
+    x->twoth = y->twoth;
+
+    y->phi = t.phi;
+    y->chi = t.chi;
+    y->twoth = t.twoth;
+}
diff --git a/contrib/blossom/concorde97/UTIL/priority.c b/contrib/blossom/concorde97/UTIL/priority.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c3e421a078a32d166933d78fb7a8798e06b16c7
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/priority.c
@@ -0,0 +1,189 @@
+/***************************************************************************/
+/*                                                                         */
+/*                      PRIORITY QUEUE ROUTINES                            */
+/*                                                                         */
+/*                                                                         */
+/*                              TSP CODE                                   */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: March 3, 1997                                                    */
+/*  Reference: R.E. Tarjan, Data Structures and Network Algorithms         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    int CCutil_priority_init (CCpriority *pri, int k)                    */
+/*      -h should point to a CCpriority struct.                            */
+/*      -k an initial allocation for the priority queue.                   */
+/*    void CCutil_priority_free (CCpriority *pri)                          */
+/*      -frees the spaces allocated for the priority queue.                */
+/*    void *CCutil_priority_findmin (CCpriority *pri, double *keyval)      */
+/*      -returns the entry with least key value.                           */
+/*      -returns NULL if no entries in heap.                               */
+/*      -if (keyval != NULL), *keyval will be the minimum key value.       */
+/*    int CCutil_priority_insert (CCpriority *pri, void *data,             */
+/*            double keyval)                                               */
+/*      -adds (data, keyval) to h.                                         */
+/*      -returns a handle (>= 0) to use when deleting or changing the entry*/
+/*      -returns -1 if out of memory.                                      */
+/*    void CCutil_priority_delete (CCpriority *pri, int handle)            */
+/*      -deletes an entry from the queue.  handle is the value returned by */
+/*       CCpriority_insert.                                                */
+/*    void *CCutil_priority_deletemin (CCpriority *pri, double *keyval)    */
+/*      -like CCpriority_findmin, but also deletes the entry.              */
+/*    void CCutil_priority_changekey (CCpriority *pri, int handle,         */
+/*            double newkey)                                               */
+/*      -changes the key of an entry in the queue.  handle is the value    */
+/*       returned by CCpriority_insert.                                    */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*      These priority queue routines use the dheap routines to maintain   */
+/*  the priority queue.                                                    */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_priority_init (CCpriority *pri, int k)
+#else
+int CCutil_priority_init (pri, k)
+CCpriority *pri;
+int k;
+#endif
+{
+    int i;
+    int list;
+
+    pri->space = k;
+    pri->pri_info = CC_SAFE_MALLOC (k, union pri_data);
+    if (!pri->pri_info) {
+        return -1;
+    }
+    if (CCutil_dheap_init (&pri->heap, k)) {
+        CC_FREE (pri->pri_info, union pri_data);
+        return -1;
+    }
+
+    list = -1;
+    for (i=k-1; i>=0; i--) {
+        pri->pri_info[i].next = list;
+        list = i;
+    }
+    pri->freelist = list;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_priority_free (CCpriority *pri)
+#else
+void CCutil_priority_free (pri)
+CCpriority *pri;
+#endif
+{
+    CCutil_dheap_free (&pri->heap);
+    CC_FREE (pri->pri_info, union pri_data);
+    pri->space = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void *CCutil_priority_findmin (CCpriority *pri, double *keyval)
+#else
+void *CCutil_priority_findmin (pri, keyval)
+CCpriority *pri;
+double *keyval;
+#endif
+{
+    int handle = CCutil_dheap_findmin (&pri->heap);
+
+    if (handle < 0) {
+        return (void *) NULL;
+    } else {
+        if (keyval) *keyval = pri->heap.key[handle];
+        return pri->pri_info[handle].data;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_priority_insert (CCpriority *pri, void *data, double keyval)
+#else
+int CCutil_priority_insert (pri, data, keyval)
+CCpriority *pri;
+void *data;
+double keyval;
+#endif
+{
+    int newsize;
+    int i;
+    int list;
+
+    if (pri->freelist == -1) {
+        newsize = (int) (1.3 * pri->space);
+        if (newsize < pri->space + 1000) newsize = pri->space + 1000;
+        if (CCutil_dheap_resize (&pri->heap, newsize)) {
+            return -1;
+        }
+        if (CCutil_reallocrus_count ((void **) &pri->pri_info, newsize,
+                              sizeof (union pri_data))) {
+            return -1;
+        }
+        list = -1;
+        for (i=newsize-1; i>=pri->space; i--) {
+            pri->pri_info[i].next = list;
+            list = i;
+        }
+        pri->freelist = list;
+    }
+
+    i = pri->freelist;
+    pri->freelist = pri->pri_info[i].next;
+    pri->pri_info[i].data = data;
+    pri->heap.key[i] = keyval;
+    CCutil_dheap_insert (&pri->heap, i);
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_priority_delete (CCpriority *pri, int handle)
+#else
+void CCutil_priority_delete (pri, handle)
+CCpriority *pri;
+int handle;
+#endif
+{
+    CCutil_dheap_delete (&pri->heap, handle);
+    pri->pri_info[handle].next = pri->freelist;
+    pri->freelist = handle;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void *CCutil_priority_deletemin (CCpriority *pri, double *keyval)
+#else
+void *CCutil_priority_deletemin (pri, keyval)
+CCpriority *pri;
+double *keyval;
+#endif
+{
+    int handle = CCutil_dheap_deletemin (&pri->heap);
+    void *data;
+
+    if (handle < 0) {
+        return (void *) NULL;
+    } else {
+        if (keyval) *keyval = pri->heap.key[handle];
+        data = pri->pri_info[handle].data;
+        pri->pri_info[handle].next = pri->freelist;
+        pri->freelist = handle;
+        return data;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_priority_changekey (CCpriority *pri, int handle, double newkey)
+#else
+void CCutil_priority_changekey (pri, handle, newkey)
+CCpriority *pri;
+int handle;
+double newkey;
+#endif
+{
+    CCutil_dheap_changekey (&pri->heap, handle, newkey);
+}
diff --git a/contrib/blossom/concorde97/UTIL/safe_io.c b/contrib/blossom/concorde97/UTIL/safe_io.c
new file mode 100644
index 0000000000000000000000000000000000000000..45608ed0ef9d9dc6eff8b0f19b00c359405406c3
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/safe_io.c
@@ -0,0 +1,1086 @@
+/***************************************************************************/
+/*                                                                         */
+/*                    INPUT/OUTPUT ROUTINES                                */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/* Written by:  Applegate, Bixby, Chvatal, and Cook                        */
+/* Date: February 13, 1995                                                 */
+/*                                                                         */
+/* EXPORTED FUNCTIONS:                                                     */
+/*                                                                         */
+/* CC_SFILE                                                                */
+/*     *CCutil_sopen (char *f, char *s),                                   */
+/*     *CCutil_sdopen (int d, char *s);                                    */
+/* int                                                                     */
+/*    CCutil_swrite (CC_SFILE *f, unsigned char *buf, int size),           */
+/*    CCutil_swrite_bits (CC_SFILE *f, unsigned int x, int xbits),         */
+/*    CCutil_swrite_char (CC_SFILE *f, unsigned char x),                   */
+/*    CCutil_swrite_string (CC_SFILE *f, unsigned char *s)                 */
+/*    CCutil_swrite_short (CC_SFILE *f, unsigned short x),                 */
+/*    CCutil_swrite_int (CC_SFILE *f, unsigned int x),                     */
+/*    CCutil_swrite_double (CC_SFILE *f, double x),                        */
+/*    CCutil_sread (CC_SFILE *f, unsigned char *buf, int size),            */
+/*    CCutil_sread_bits (CC_SFILE *f, unsigned int x, int xbits),          */
+/*    CCutil_sread_char (CC_SFILE *f, unsigned char *x),                   */
+/*    CCutil_sread_string (CC_SFILE *f, unsigned char *x, int maxlen)      */
+/*    CCutil_sread_short (CC_SFILE *f, unsigned short *x),                 */
+/*    CCutil_sread_short_r (CC_SFILE *f, unsigned short *x),               */
+/*    CCutil_sread_int (CC_SFILE *f, unsigned int *x),                     */
+/*    CCutil_sread_int_r (CC_SFILE *f, unsigned int *x),                   */
+/*    CCutil_sread_double (CC_SFILE *f, double *x),                        */
+/*    CCutil_sread_double_r (CC_SFILE *f, double *x),                      */
+/*    CCutil_sflush (CC_SFILE *f),                                         */
+/*    CCutil_stell (CC_SFILE *f),                                          */
+/*    CCutil_sseek (CC_SFILE *f, int offset),                              */
+/*    CCutil_srewind (CC_SFILE *f),                                        */
+/*    CCutil_sclose (CC_SFILE *f),                                         */
+/*    CCutil_sbits (unsigned int x),                                       */
+/*    CCutil_sdelete_file (char *f),                                       */
+/*    CCutil_sdelete_file_backup (char *f)                                 */
+/*                                                                         */
+/*  This routines provide buffered binary I/O.  The routines sopen,        */
+/*  sdopen, swrite, sread, sflush, stell, sseek, srewind, and sclose       */
+/*  resemble the stdio routines fopen, fdopen, fwrite, fread, fflush,      */
+/*  ftell, fseek, rewind, and fclose.  swrite_{char,short,int,double}      */
+/*  and sread_{char,short,int,double} provide a somewhat machine           */
+/*  independent binary I/O mechanism.  sread_{short,int,double}_r read     */
+/*  the values in reverse order, and are provided for compatibility        */
+/*  reasons.  sread_bits and swrite_bits write variable-length bit         */
+/*  strings.  sbits can be used to compute the number of bits necessary    */
+/*  to represent a number.  The variable-length bit strings are padded     */
+/*  to a byte boundary when one of the other read/write routines, flush,   */
+/*  tell, seek, rewind, or close are called.                               */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#ifndef SEEK_SET
+#ifdef L_SET
+#define SEEK_SET L_SET
+#else
+#define SEEK_SET 0
+#endif
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static CC_SFILE
+    *sopen_write (char *f),
+    *sdopen_write (int t),
+    *sopen_read (char *f),
+    *sdopen_read (int t);
+
+static int
+    swrite_buffer (CC_SFILE *f),
+    sread_buffer (CC_SFILE *f);
+
+static void
+    sinit (CC_SFILE *s);
+
+#else
+
+static CC_SFILE
+    *sopen_write (),
+    *sdopen_write (),
+    *sopen_read (),
+    *sdopen_read ();
+
+static int
+    swrite_buffer (),
+    sread_buffer ();
+
+static void
+    sinit ();
+
+#endif
+
+
+/* VERSION A3 */
+
+/* sopen interprets filenames "stdin" as descriptor 0, "stdout" as
+ * descriptor 1, and "stderr" as descriptor 2.  "-" is interpreted as
+ * 0 or 1, depending on whether the file is opened for reading or writing.
+ *
+ * sclose doesn't close descriptors 0, 1, and 2.
+ */
+
+/* When writing, written data extends from buffer[0] bit 7 through
+ * buffer[chars_in_buffer-1] bit bits_in_last_char.  Empty space extends
+ * from buffer[chars_in_buffer-1] bit bits_in_last_char-1 through
+ * buffer[CC_SBUFFER_SIZE-1] bit 0.
+ *
+ * When reading, read data extends from buffer[0] bit 7 through
+ * buffer[current_buffer_char] bit bits_in_last_char.  unread data
+ * extends from buffer[current_buffer_char] bit bits_in_last_char-1
+ * through buffer[chars_in_buffer-1] bit 0.  Empty space extends from
+ * buffer[chars_in_buffer] bit 7 through buffer[CC_SBUFFER_SIZE-1] bit 0.
+ */
+
+/* If the routines detect an error, they return -1.
+ */
+
+#define SREAD 1
+#define SWRITE 2
+
+#define NBITMASK(n) ((1<<(n))-1)
+#define BITRANGE(x,start,length) (((x) >> (start)) & NBITMASK(length))
+#define BITS_PER_CHAR (8)
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifndef O_EXCL
+#define O_EXCL 0
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+CC_SFILE *CCutil_sopen (char *f, char *s)
+#else
+CC_SFILE *CCutil_sopen (f, s)
+char *f;
+char *s;
+#endif
+{
+    if (s[0] == 'r' || s[0] == 'R') {
+        return sopen_read (f);
+    } else if (s[0] == 'w' || s[0] == 'W') {
+        return sopen_write (f);
+    } else {
+        fprintf (stderr, "Need to specify read/write in sopen\n");
+        return (CC_SFILE *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+CC_SFILE *CCutil_sdopen (int d, char *s)
+#else
+CC_SFILE *CCutil_sdopen (d, s)
+int d;
+char *s;
+#endif
+{
+    if (s[0] == 'r' || s[0] == 'R') {
+        return sdopen_read (d);
+    } else if (s[0] == 'w' || s[0] == 'W') {
+        return sdopen_write (d);
+    } else {
+        fprintf (stderr, "Need to specify read/write in sopen\n");
+        return (CC_SFILE *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static CC_SFILE *sopen_write (char *f)
+#else
+static CC_SFILE *sopen_write (f)
+char *f;
+#endif
+{
+    CC_SFILE *s = (CC_SFILE *) NULL;
+    int t;
+    char fbuf[CC_SFNAME_SIZE];
+    char fbuf_N[CC_SFNAME_SIZE + 32];
+    char fbuf_Nx[CC_SFNAME_SIZE + 64];
+
+    strncpy (fbuf, f, sizeof (fbuf) - 12);
+    fbuf[sizeof (fbuf) - 12] = '\0';
+    sprintf (fbuf_N, "N%s", fbuf);
+    sprintf (fbuf_Nx, "N%s~", fbuf);
+
+
+    if (!strcmp (f, "stdout") || !strcmp (f, "-")) {
+        s = sdopen_write (1);
+    } else if (!strcmp (f, "stderr")) {
+        s = sdopen_write (2);
+    } else {
+        t = open (fbuf_N, O_WRONLY | O_CREAT | O_BINARY | O_EXCL, 0644);
+        if (t == -1 && errno == EEXIST) {
+            fprintf (stderr, "%s already exists, renaming to %s\n",
+                          fbuf_N, fbuf_Nx);
+            if (rename (fbuf_N, fbuf_Nx)) {
+                perror (fbuf_Nx);
+                fprintf (stderr, "Couldn't rename %s to %s\n", fbuf_N,
+                         fbuf_Nx);
+                return (CC_SFILE *) NULL;
+            }
+            t = open (fbuf_N, O_WRONLY | O_CREAT | O_BINARY | O_EXCL, 0644);
+        }
+        if (t == -1) {
+            perror (fbuf_N);
+            fprintf (stderr, "Couldn't open %s for output\n", fbuf_N);
+            return (CC_SFILE *) NULL;
+        }
+        s = sdopen_write (t);
+        if (!s) {
+            close (t);
+        }
+    }
+    if (s) {
+        strncpy (s->fname, fbuf, sizeof (s->fname));
+        s->fname[sizeof (s->fname)-1] = '\0';
+    }
+    return s;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static CC_SFILE *sdopen_write (int t)
+#else
+static CC_SFILE *sdopen_write (t)
+int t;
+#endif
+{
+    CC_SFILE *s = (CC_SFILE *) NULL;
+
+    if (t < 0) {
+        fprintf (stderr, "Invalid descriptor %d\n", t);
+        return (CC_SFILE *) NULL;
+    }
+
+    s = CC_SAFE_MALLOC (1, CC_SFILE);
+    if (s == (CC_SFILE *) NULL) {
+        return s;
+    }
+    sinit (s);
+
+    s->status = SWRITE;
+    s->desc = t;
+    sprintf (s->fname, "descriptor %d", t);
+    return s;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static CC_SFILE *sopen_read (char *f)
+#else
+static CC_SFILE *sopen_read (f)
+char *f;
+#endif
+{
+    CC_SFILE *s = (CC_SFILE *) NULL;
+    int t;
+
+    if (!strcmp (f, "stdin") || !strcmp (f, "-")) {
+        s = sdopen_read (0);
+    } else {
+        t = open (f, O_RDONLY | O_BINARY, 0644);
+        if (t == -1) {
+            perror (f);
+            fprintf (stderr, "Couldn't open for input\n");
+            s = (CC_SFILE *) NULL;
+        }
+        s = sdopen_read (t);
+        if (!s) {
+            close (t);
+        }
+    }
+    if (s) {
+        strncpy (s->fname, f, sizeof (s->fname));
+        s->fname[sizeof (s->fname)-1] = '\0';
+    }
+    return s;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static CC_SFILE *sdopen_read (int t)
+#else
+static CC_SFILE *sdopen_read (t)
+int t;
+#endif
+{
+    CC_SFILE *s = (CC_SFILE *) NULL;
+
+    if (t < 0) {
+        fprintf (stderr, "Invalid descriptor %d\n", t);
+        return (CC_SFILE *) NULL;
+    }
+
+    s = CC_SAFE_MALLOC (1, CC_SFILE);
+    if (s == (CC_SFILE *) NULL) {
+        return s;
+    }
+    sinit (s);
+
+    s->status = SREAD;
+    s->desc = t;
+    sprintf (s->fname, "descriptor %d", t);
+    return s;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_swrite (CC_SFILE *f, unsigned char *buf, int size)
+#else
+int CCutil_swrite (f, buf, size)
+CC_SFILE *f;
+unsigned char *buf;
+int size;
+#endif
+{
+    int i;
+
+    for (i=0; i<size; i++) {
+        if (CCutil_swrite_char (f, buf[i])) return -1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_swrite_bits (CC_SFILE *f, unsigned int x, int xbits)
+#else
+int CCutil_swrite_bits (f, x, xbits)
+CC_SFILE *f;
+unsigned int x;
+int xbits;
+#endif
+{
+    int getbits;
+    unsigned int v;
+
+    if (!f) return -1;
+    if (f->status != SWRITE) {
+        fprintf (stderr, "%s not open for output\n", f->fname);
+        return -1;
+    }
+    while (xbits) {
+        if (f->bits_in_last_char == 0) {
+            if (f->chars_in_buffer == CC_SBUFFER_SIZE) {
+                if (swrite_buffer (f)) return -1;
+            }
+            f->buffer[f->chars_in_buffer++] = 0;
+            f->bits_in_last_char = BITS_PER_CHAR;
+        }
+        getbits = f->bits_in_last_char;
+        if (getbits > xbits)
+            getbits = xbits;
+        xbits -= getbits;
+        f->bits_in_last_char -= getbits;
+        v = BITRANGE (x, xbits, getbits);
+        f->buffer[f->chars_in_buffer - 1] |=
+            v << f->bits_in_last_char;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_swrite_char (CC_SFILE *f, unsigned char x)
+#else
+int CCutil_swrite_char (f, x)
+CC_SFILE *f;
+unsigned char x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SWRITE) {
+        fprintf (stderr, "%s not open for output\n", f->fname);
+        return -1;
+    }
+
+    f->bits_in_last_char = 0;
+    if (f->chars_in_buffer + 1 > CC_SBUFFER_SIZE) {
+        if (swrite_buffer (f)) return -1;
+    }
+    f->buffer[f->chars_in_buffer++] = ((unsigned int) x) & 0xff;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_swrite_string (CC_SFILE *f, unsigned char *s)
+#else
+int CCutil_swrite_string (f, s)
+CC_SFILE *f;
+unsigned char *s;
+#endif
+{
+    int rval;
+
+    while (*s) {
+        rval = CCutil_swrite_char (f, *s);
+        if (rval)
+            return rval;
+        s++;
+    }
+    CCutil_swrite_char (f, (unsigned char) 0);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_swrite_short (CC_SFILE *f, unsigned short x)
+#else
+int CCutil_swrite_short (f, x)
+CC_SFILE *f;
+unsigned short x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SWRITE) {
+        fprintf (stderr, "%s not open for output\n", f->fname);
+        return -1;
+    }
+
+    f->bits_in_last_char = 0;
+    if (f->chars_in_buffer + 2 > CC_SBUFFER_SIZE) {
+        if (swrite_buffer (f)) return -1;
+    }
+
+    f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 8) & 0xff;
+    f->buffer[f->chars_in_buffer++] = ((unsigned int) x) & 0xff;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_swrite_int (CC_SFILE *f, unsigned int x)
+#else
+int CCutil_swrite_int (f, x)
+CC_SFILE *f;
+unsigned int x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SWRITE) {
+        fprintf (stderr, "%s not open for output\n", f->fname);
+        return -1;
+    }
+
+    f->bits_in_last_char = 0;
+    if (f->chars_in_buffer + 4 > CC_SBUFFER_SIZE) {
+        if (swrite_buffer (f)) return -1;
+    }
+
+    f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 24) & 0xff;
+    f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 16) & 0xff;
+    f->buffer[f->chars_in_buffer++] = (((unsigned int) x) >> 8) & 0xff;
+    f->buffer[f->chars_in_buffer++] = ((unsigned int) x) & 0xff;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_swrite_double (CC_SFILE *f, double x)
+#else
+int CCutil_swrite_double (f, x)
+CC_SFILE *f;
+double x;
+#endif
+{
+    unsigned short e;
+    unsigned int m1;
+    unsigned int m2;
+
+    e = 128;
+
+    if (x < 0) {
+        e += 256;
+        x = -x;
+    }
+
+    if (x >= 1.0) {
+#define MUNCH_HI_EXP(x,e,v,lv) if (x >= v) {e += lv; x *= 1/v;}
+        MUNCH_HI_EXP(x,e,18446744073709551616.0,64);
+        MUNCH_HI_EXP(x,e,4294967296.0,32);
+        MUNCH_HI_EXP(x,e,65536.0, 16);
+        MUNCH_HI_EXP(x,e,256.0, 8);
+        MUNCH_HI_EXP(x,e,16.0, 4);
+        MUNCH_HI_EXP(x,e,4.0, 2);
+        MUNCH_HI_EXP(x,e,2.0, 1);
+        x /= 2; e++;
+    } else if (x < 0.5) {
+#define MUNCH_LO_EXP(x,e,v,lv) if (x < 1/v) {e -= lv; x *= v;}
+        MUNCH_LO_EXP(x,e,18446744073709551616.0,64);
+        MUNCH_LO_EXP(x,e,4294967296.0,32);
+        MUNCH_LO_EXP(x,e,65536.0, 16);
+        MUNCH_LO_EXP(x,e,256.0, 8);
+        MUNCH_LO_EXP(x,e,16.0, 4);
+        MUNCH_LO_EXP(x,e,4.0, 2);
+        MUNCH_LO_EXP(x,e,2.0, 1);
+    }
+    x *= 4294967296.0;
+    m1 = (unsigned int) x;
+    m2 = (unsigned int) ((x - m1) * 4294967296.0);
+    if (CCutil_swrite_short (f, e)) return -1;
+    if (CCutil_swrite_int (f, m1)) return -1;
+    if (CCutil_swrite_int (f, m2)) return -1;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread (CC_SFILE *f, unsigned char *buf, int size)
+#else
+int CCutil_sread (f, buf, size)
+CC_SFILE *f;
+unsigned char *buf;
+int size;
+#endif
+{
+    int i;
+
+    for (i=0; i<size; i++) {
+        if (CCutil_sread_char (f, &buf[i])) return -1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_bits (CC_SFILE *f, unsigned int *x, int xbits)
+#else
+int CCutil_sread_bits (f, x, xbits)
+CC_SFILE *f;
+unsigned int *x;
+int xbits;
+#endif
+{
+    int getbits;
+    unsigned int v;
+
+    if (!f) return -1;
+    if (f->status != SREAD) {
+        fprintf (stderr, "%s not open for input\n", f->fname);
+        return -1;
+    }
+    *x = 0;
+    while (xbits) {
+        if (f->bits_in_last_char == 0) {
+            if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+                if (sread_buffer (f)) return -1;
+            }
+            f->current_buffer_char++;
+            f->bits_in_last_char = BITS_PER_CHAR;
+        }
+        getbits = f->bits_in_last_char;
+        if (getbits > xbits)
+            getbits = xbits;
+        f->bits_in_last_char -= getbits;
+        xbits -= getbits;
+        v = BITRANGE ((unsigned int) f->buffer[f->current_buffer_char],
+                      f->bits_in_last_char, getbits);
+        *x |= v << xbits;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_char (CC_SFILE *f, unsigned char *x)
+#else
+int CCutil_sread_char (f, x)
+CC_SFILE *f;
+unsigned char *x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SREAD) {
+        fprintf (stderr, "%s not open for input\n", f->fname);
+        return -1;
+    }
+    f->bits_in_last_char = 0;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x = ((unsigned char) f->buffer[++f->current_buffer_char]);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_string (CC_SFILE *f, unsigned char *x, int maxlen)
+#else
+int CCutil_sread_string (f, x, maxlen)
+CC_SFILE *f;
+unsigned char *x;
+int maxlen;
+#endif
+{
+    int i, rval;
+
+    maxlen--;
+    for (i = 0; i < maxlen;  i++, x++) {
+        rval = CCutil_sread_char (f, x);
+        if (rval)
+            return rval;
+        if (*x == 0)
+            return 0;
+    }
+    *x = 0;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_short (CC_SFILE *f, unsigned short *x)
+#else
+int CCutil_sread_short (f, x)
+CC_SFILE *f;
+unsigned short *x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SREAD) {
+        fprintf (stderr, "%s not open for input\n", f->fname);
+        return -1;
+    }
+    f->bits_in_last_char = 0;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x = ((unsigned short) f->buffer[++f->current_buffer_char]) << 8;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_short_r (CC_SFILE *f, unsigned short *x)
+#else
+int CCutil_sread_short_r (f, x)
+CC_SFILE *f;
+unsigned short *x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SREAD) {
+        fprintf (stderr, "%s not open for input\n", f->fname);
+        return -1;
+    }
+    f->bits_in_last_char = 0;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x = ((unsigned short) f->buffer[++f->current_buffer_char]);
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]) << 8;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_int (CC_SFILE *f, unsigned int *x)
+#else
+int CCutil_sread_int (f, x)
+CC_SFILE *f;
+unsigned int *x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SREAD) {
+        fprintf (stderr, "%s not open for input\n", f->fname);
+        return -1;
+    }
+    f->bits_in_last_char = 0;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x = ((unsigned short) f->buffer[++f->current_buffer_char]) << 24;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]) << 16;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]) << 8;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_int_r (CC_SFILE *f, unsigned int *x)
+#else
+int CCutil_sread_int_r (f, x)
+CC_SFILE *f;
+unsigned int *x;
+#endif
+{
+    if (!f) return -1;
+    if (f->status != SREAD) {
+        fprintf (stderr, "%s not open for input\n", f->fname);
+        return -1;
+    }
+    f->bits_in_last_char = 0;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x = ((unsigned short) f->buffer[++f->current_buffer_char]);
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]) << 8;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]) << 16;
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        if (sread_buffer (f)) return -1;
+    }
+    *x |= ((unsigned short) f->buffer[++f->current_buffer_char]) << 24;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_double (CC_SFILE *f, double *x)
+#else
+int CCutil_sread_double (f, x)
+CC_SFILE *f;
+double *x;
+#endif
+{
+    unsigned short e;
+    unsigned int m1;
+    unsigned int m2;
+
+    if (CCutil_sread_short (f, &e)) return -1;
+    if (CCutil_sread_int (f, &m1)) return -1;
+    if (CCutil_sread_int (f, &m2)) return -1;
+
+    *x = ((m2 / 4294967296.0) + m1) / 4294967296.0;
+
+    if (e >= 256) {
+        *x = -*x;
+        e -= 256;
+    }
+
+    if (e > 128) {
+#define UNMUNCH_HI_EXP(x,e,v,lv) if (e >= (unsigned short) (128 + lv)) \
+                                      {e -= lv; x *= v;}
+        UNMUNCH_HI_EXP(*x,e,18446744073709551616.0,64);
+        UNMUNCH_HI_EXP(*x,e,4294967296.0,32);
+        UNMUNCH_HI_EXP(*x,e,65536.0, 16);
+        UNMUNCH_HI_EXP(*x,e,256.0, 8);
+        UNMUNCH_HI_EXP(*x,e,16.0, 4);
+        UNMUNCH_HI_EXP(*x,e,4.0, 2);
+        UNMUNCH_HI_EXP(*x,e,2.0, 1);
+    } else if (e < 128) {
+#define UNMUNCH_LO_EXP(x,e,v,lv) if (e <= (unsigned short) (128 - lv)) \
+                                     {e += lv; x *= 1/v;}
+        UNMUNCH_LO_EXP(*x,e,18446744073709551616.0,64);
+        UNMUNCH_LO_EXP(*x,e,4294967296.0,32);
+        UNMUNCH_LO_EXP(*x,e,65536.0, 16);
+        UNMUNCH_LO_EXP(*x,e,256.0, 8);
+        UNMUNCH_LO_EXP(*x,e,16.0, 4);
+        UNMUNCH_LO_EXP(*x,e,4.0, 2);
+        UNMUNCH_LO_EXP(*x,e,2.0, 1);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sread_double_r (CC_SFILE *f, double *x)
+#else
+int CCutil_sread_double_r (f, x)
+CC_SFILE *f;
+double *x;
+#endif
+{
+    unsigned short e;
+    unsigned int m1;
+    unsigned int m2;
+
+    if (CCutil_sread_short_r (f, &e)) return -1;
+    if (CCutil_sread_int_r (f, &m1)) return -1;
+    if (CCutil_sread_int_r (f, &m2)) return -1;
+
+    *x = ((m2 / 4294967296.0) + m1) / 4294967296.0;
+
+    if (e >= 256) {
+        *x = -*x;
+        e -= 256;
+    }
+
+    if (e > 128) {
+#define UNMUNCH_HI_EXP(x,e,v,lv) if (e >= (unsigned short) (128 + lv)) \
+                                     {e -= lv; x *= v;}
+        UNMUNCH_HI_EXP(*x,e,18446744073709551616.0,64);
+        UNMUNCH_HI_EXP(*x,e,4294967296.0,32);
+        UNMUNCH_HI_EXP(*x,e,65536.0, 16);
+        UNMUNCH_HI_EXP(*x,e,256.0, 8);
+        UNMUNCH_HI_EXP(*x,e,16.0, 4);
+        UNMUNCH_HI_EXP(*x,e,4.0, 2);
+        UNMUNCH_HI_EXP(*x,e,2.0, 1);
+    } else if (e < 128) {
+#define UNMUNCH_LO_EXP(x,e,v,lv) if (e <= (unsigned short) (128 - lv)) \
+                                      {e += lv; x *= 1/v;}
+        UNMUNCH_LO_EXP(*x,e,18446744073709551616.0,64);
+        UNMUNCH_LO_EXP(*x,e,4294967296.0,32);
+        UNMUNCH_LO_EXP(*x,e,65536.0, 16);
+        UNMUNCH_LO_EXP(*x,e,256.0, 8);
+        UNMUNCH_LO_EXP(*x,e,16.0, 4);
+        UNMUNCH_LO_EXP(*x,e,4.0, 2);
+        UNMUNCH_LO_EXP(*x,e,2.0, 1);
+    }
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sflush (CC_SFILE *f)
+#else
+int CCutil_sflush (f)
+CC_SFILE *f;
+#endif
+{
+    if (!f) return -1;
+    if (f->status == SREAD) {
+        f->bits_in_last_char = 0;
+        return 0;
+    } else if (f->status == SWRITE) {
+        return swrite_buffer (f);
+    } else {
+        fprintf (stderr, "Buffer %s has invalid status %d\n", f->fname,
+                 f->status);
+        return -1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_stell (CC_SFILE *f)
+#else
+int CCutil_stell (f)
+CC_SFILE *f;
+#endif
+{
+    if (!f) return -1;
+    f->bits_in_last_char = 0;
+    if (f->status == SREAD) {
+        return f->pos - f->chars_in_buffer + f->current_buffer_char + 1;
+    } else if (f->status == SWRITE) {
+        return f->pos + f->chars_in_buffer;
+    } else {
+        fprintf (stderr, "Buffer %s has invalid status %d\n", f->fname,
+                 f->status);
+        return -1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sseek (CC_SFILE *f, int offset)
+#else
+int CCutil_sseek (f, offset)
+CC_SFILE *f;
+int offset;
+#endif
+{
+    int curloc;
+
+    if (!f) return -1;
+    if (CCutil_sflush (f)) return -1;
+    curloc = CCutil_stell (f);
+    if (curloc < 0) return curloc;
+    if (curloc == offset) return 0;
+    if (lseek (f->desc, offset, SEEK_SET) < 0) {
+        perror (f->fname);
+        fprintf (stderr, "Unable to lseek on %s\n", f->fname);
+        return -1;
+    }
+    f->chars_in_buffer = 0;
+    f->current_buffer_char = -1;
+    f->pos = offset;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_srewind (CC_SFILE *f)
+#else
+int CCutil_srewind (f)
+CC_SFILE *f;
+#endif
+{
+    return CCutil_sseek (f, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sclose (CC_SFILE *f)
+#else
+int CCutil_sclose (f)
+CC_SFILE *f;
+#endif
+{
+    int retval = 0;
+    char fbuf_O[CC_SFNAME_SIZE + 32];
+    char fbuf_N[CC_SFNAME_SIZE + 32];
+
+    if (!f) return -1;
+
+    if (f->status == SWRITE && f->chars_in_buffer) {
+        if (swrite_buffer (f)) retval = -1;
+    }
+
+    if (f->desc >= 3) {
+        if (close (f->desc)) {
+            perror ("close");
+            fprintf (stderr, "Unable to close swrite file %s\n", f->fname);
+            retval = -1;
+        }
+        if (f->status == SWRITE) {
+            sprintf (fbuf_N, "N%s", f->fname);
+            sprintf (fbuf_O, "O%s", f->fname);
+            rename (f->fname, fbuf_O);
+            if (rename (fbuf_N, f->fname)) {
+                perror (f->fname);
+                fprintf (stderr, "Couldn't rename %s to %s\n",
+                                               fbuf_N, f->fname);
+                retval = -1;
+            }
+        }
+    }
+
+    CC_FREE (f, CC_SFILE);
+
+    return retval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int swrite_buffer (CC_SFILE *f)
+#else
+static int swrite_buffer (f)
+CC_SFILE *f;
+#endif
+{
+    char *p;
+    int nleft;
+    int n;
+
+    if (!f) return -1;
+    if (f->status != SWRITE) {
+        fprintf (stderr, "%s not open for output\n", f->fname);
+        return -1;
+    }
+    p = (char *) f->buffer;
+    nleft = f->chars_in_buffer;
+    while (nleft) {
+        n = write (f->desc, p, nleft);
+        if (n == -1) {
+            if (errno == EINTR) {
+                fprintf (stderr, "swrite interrupted, retrying\n");
+                continue;
+            }
+            perror ("write");
+            fprintf (stderr, "swrite of %d chars to %s failed\n", nleft,
+                     f->fname);
+            return -1;
+        }
+        nleft -= n;
+        p += n;
+        f->pos += n;
+    }
+    f->bits_in_last_char = 0;
+    f->chars_in_buffer = 0;
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int sread_buffer (CC_SFILE *f)
+#else
+static int sread_buffer (f)
+CC_SFILE *f;
+#endif
+{
+    int n;
+
+    if (!f) return -1;
+    if (f->status != SREAD) {
+        fprintf (stderr, "%s not open for input\n", f->fname);
+        return -1;
+    }
+    if (f->current_buffer_char + 1 == f->chars_in_buffer) {
+        f->chars_in_buffer = 0;
+        f->current_buffer_char = -1;
+    }
+    if (f->chars_in_buffer == CC_SBUFFER_SIZE) {
+        fprintf (stderr, "sread_buffer for %s when buffer full\n", f->fname);
+        return 0;
+    }
+
+retry:
+    n = read (f->desc, (char *) f->buffer + f->chars_in_buffer,
+              CC_SBUFFER_SIZE - f->chars_in_buffer);
+
+    if (n == -1) {
+        if (errno == EINTR) {
+            fprintf (stderr, "sread interrupted, retrying\n");
+            goto retry;
+        }
+        perror ("read");
+        fprintf (stderr, "sread failed\n");
+        return -1;
+    }
+    if (n == 0) {
+        fprintf (stderr, "sread encountered EOF\n");
+        return -1;
+    }
+    f->pos += n;
+    f->chars_in_buffer += n;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void sinit (CC_SFILE *s)
+#else
+static void sinit (s)
+CC_SFILE *s;
+#endif
+{
+    s->status = 0;
+    s->desc = -1;
+    s->chars_in_buffer = 0;
+    s->current_buffer_char = -1;
+    s->bits_in_last_char = 0;
+    s->pos = 0;
+    s->fname[0] = '\0';
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sbits (unsigned int x)
+#else
+int CCutil_sbits (x)
+unsigned int x;
+#endif
+{
+    int i;
+    int ux = x;
+    unsigned int b;
+
+    i = 32;
+    b = ((unsigned int) 1) << 31;
+    while ((ux & b) == 0 && i > 1) {
+        b >>= 1;
+        i--;
+    }
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sdelete_file (char *fname)
+#else
+int CCutil_sdelete_file (fname)
+char *fname;
+#endif
+{
+    int rval;
+
+    rval = unlink (fname);
+    if (rval) {
+        perror (fname);
+        fprintf (stderr, "unlink: could not delete %s\n", fname);
+    }
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_sdelete_file_backup (char *fname)
+#else
+int CCutil_sdelete_file_backup (fname)
+char *fname;
+#endif
+{
+    int rval;
+    char fbuf_O[CC_SFNAME_SIZE + 32];
+
+    sprintf (fbuf_O, "O%s", fname);
+    rval = unlink (fbuf_O);
+
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/UTIL/sortrus.c b/contrib/blossom/concorde97/UTIL/sortrus.c
new file mode 100644
index 0000000000000000000000000000000000000000..a5fb7b3e01f6bc11729cf5a616ef218b6449359d
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/sortrus.c
@@ -0,0 +1,331 @@
+/****************************************************************************/
+/*                                                                          */
+/*                         SORTING ROUTINES                                 */
+/*                                                                          */
+/*                             TSP CODE                                     */
+/*                                                                          */
+/*   Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*   DATE:  February 24, 1994                                               */
+/*                                                                          */
+/*   EXPORTED FUNCTIONS:                                                    */
+/*     char *CCutil_linked_radixsort (char *data, char *datanext,           */
+/*                                    char *dataval, int valsize)           */
+/*       USAGE:                                                             */
+/*         head = (bar *) CCutil_linked_radixsort ((char *) head,           */
+/*             (char *) &(head->next), (char *) &(head->val), sizeof (int));*/
+/*       Then head is the start of the linked list in increasing order of   */
+/*       val, with next as the field that links the bars.                   */
+/*       WARNING: DOES NOT HANDLE NEGATIVE NUMBERS PROPERLY.                */
+/*                                                                          */
+/*     void CCutil_int_array_quicksort (int *len, int n)                    */
+/*       len - the array to be sorted                                       */
+/*       n - the number of elements in len                                  */
+/*       Uses quicksort to put len in increasing order.                     */
+/*                                                                          */
+/*     void CCutil_int_perm_quicksort (int *perm, int *len, int n)          */
+/*     void CCutil_double_perm_quicksort (int *perm, double *len, int n)    */
+/*       perm - must be allocated and initialized by the calling routine,   */
+/*              it will be arranged in increasing order of len.             */
+/*       n - the number of elements in perm and len.                        */
+/*                                                                          */
+/*     void CCutil_rselect (int *arr, int l, int r, int m, double *coord)   */
+/*       arr - permutation that will be rearranged                          */
+/*       l,r - specify the range of arr that we are interested in           */
+/*       m - is the index into l,r that is the break point for the perm     */
+/*       coord - gives the keys that determine the ordering                 */
+/*                                                                          */
+/****************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+#define BITS_PER_PASS (8)
+
+#define NBINS (1<<BITS_PER_PASS)
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    select_split (int *arr, int n, double v, int *start, int *end,
+           double *coord),
+    select_sort (int *arr, int n, double *coord),
+    select_sort_dsample (double *samp, int n);
+
+#else
+
+static void
+    select_split (),
+    select_sort (),
+    select_sort_dsample ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+char *CCutil_linked_radixsort (char *data, char *datanext, char *dataval,
+                               int valsize)
+#else
+char *CCutil_linked_radixsort (data, datanext, dataval, valsize)
+char *data;
+char *datanext;
+char *dataval;
+int valsize;
+#endif
+{
+    int nextoff = datanext - data;
+    int valoff = dataval - data;
+    int i;
+    char *head[NBINS];
+    char **tail[NBINS];
+    char *p;
+    char **last;
+    int j;
+    int v;
+
+    for (j = valsize - 1; j >= 0; j--) {
+        for (i = 0; i < NBINS; i++) {
+            head[i] = (char *) NULL;
+            tail[i] = &head[i];
+        }
+        for (p = data; p; p = *(char **) (p + nextoff)) {
+            v = (unsigned char) p[valoff + j];
+            *tail[v] = p;
+            tail[v] = (char **) (p + nextoff);
+        }
+        last = &data;
+        for (i = 0; i < NBINS; i++) {
+            if (head[i]) {
+                *last = head[i];
+                last = tail[i];
+            }
+        }
+        *last = (char *) NULL;
+    }
+    return data;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_int_array_quicksort (int *len, int n)
+#else
+void CCutil_int_array_quicksort (len, n)
+int *len;
+int n;
+#endif
+{
+    int i, j, temp, t;
+
+    if (n <= 1)
+        return;
+
+    SWAP (len[0], len[(n - 1)/2], temp);
+
+    i = 0;
+    j = n;
+    t = len[0];
+
+    while (1) {
+        do i++; while (i < n && len[i] < t);
+        do j--; while (len[j] > t);
+        if (j < i) break;
+        SWAP (len[i], len[j], temp);
+    }
+    SWAP (len[0], len[j], temp);
+
+    CCutil_int_array_quicksort (len, j);
+    CCutil_int_array_quicksort (len + i, n - i);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_int_perm_quicksort (int *perm, int *len, int n)
+#else
+void CCutil_int_perm_quicksort (perm, len,  n)
+int *perm;
+int *len;
+int n;
+#endif
+{
+    int i, j, temp, t;
+
+    if (n <= 1)
+        return;
+
+    SWAP (perm[0], perm[(n - 1)/2], temp);
+
+    i = 0;
+    j = n;
+    t = len[perm[0]];
+
+    while (1) {
+        do i++; while (i < n && len[perm[i]] < t);
+        do j--; while (len[perm[j]] > t);
+        if (j < i) break;
+        SWAP (perm[i], perm[j], temp);
+    }
+    SWAP (perm[0], perm[j], temp);
+
+    CCutil_int_perm_quicksort (perm, len, j);
+    CCutil_int_perm_quicksort (perm + i, len, n - i);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_double_perm_quicksort (int *perm, double *len, int n)
+#else
+void CCutil_double_perm_quicksort (perm, len,  n)
+int *perm;
+double *len;
+int n;
+#endif
+{
+    int i, j, temp;
+    double t;
+
+    if (n <= 1)
+        return;
+
+    SWAP (perm[0], perm[(n - 1)/2], temp);
+
+    i = 0;
+    j = n;
+    t = len[perm[0]];
+
+    while (1) {
+        do i++; while (i < n && len[perm[i]] < t);
+        do j--; while (len[perm[j]] > t);
+        if (j < i) break;
+        SWAP (perm[i], perm[j], temp);
+    }
+    SWAP (perm[0], perm[j], temp);
+
+    CCutil_double_perm_quicksort (perm, len, j);
+    CCutil_double_perm_quicksort (perm + i, len, n - i);
+}
+
+
+/**********  Median - Select Routines **********/
+
+/* NSAMPLES should be odd */
+#define NSAMPLES 3
+#define SORTSIZE 20
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_rselect (int *arr, int l, int r, int m, double *coord)
+#else
+void CCutil_rselect (arr, l, r, m, coord)
+int *arr;
+int l;
+int r;
+int m;
+double *coord;
+#endif
+{
+    double samplevals[NSAMPLES];
+    int i;
+    int st, en;
+    int n;
+
+    arr += l;
+    n = r - l + 1;
+    m -= l;
+
+    while (n > SORTSIZE) {
+        for (i = 0; i < NSAMPLES; i++) {
+            samplevals[i] = coord[arr[CCutil_lprand () % n]];
+        }
+        select_sort_dsample (samplevals, NSAMPLES);
+        select_split (arr, n, samplevals[(NSAMPLES - 1) / 2], &st, &en, coord);
+        if (st > m) {
+            n = st;
+        } else if (en <= m) {
+            arr += en;
+            n -= en;
+            m -= en;
+        } else {
+            return;
+        }
+    }
+
+    select_sort (arr, n, coord);
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void select_split (int *arr, int n, double v, int *start, int *end,
+                          double *coord)
+#else
+static void select_split (arr, n, v, start, end, coord)
+int *arr;
+int n;
+double v;
+int *start, *end;
+double *coord;
+#endif
+{
+    int i, j, k;
+    int t;
+
+    i = 0;
+    j = k = n;
+
+    while (i < j) {
+        if (coord[arr[i]] < v) {
+            i++;
+        } else if (coord[arr[i]] == v) {
+            j--;
+            SWAP (arr[i], arr[j], t);
+        } else {
+            j--;
+            k--;
+            t = arr[i];
+            arr[i] = arr[j];
+            arr[j] = arr[k];
+            arr[k] = t;
+        }
+    }
+    *start = j;
+    *end = k;
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void select_sort (int *arr, int n, double *coord)
+#else
+static void select_sort (arr, n, coord)
+int *arr;
+int n;
+double *coord;
+#endif
+{
+    int i, j;
+    int t;
+
+    for (i = 1; i < n; i++) {
+        t = arr[i];
+        for (j = i; j > 0 && coord[arr[j - 1]] > coord[t]; j--) {
+            arr[j] = arr[j - 1];
+        }
+        arr[j] = t;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void select_sort_dsample (double *samp, int n)
+#else
+static void select_sort_dsample (samp, n)
+double *samp;
+int n;
+#endif
+{
+    int i, j;
+    double t;
+
+    for (i = 1; i < n; i++) {
+        t = samp[i];
+        for (j = i; j > 0 && samp[j - 1] > t; j--) {
+            samp[j] = samp[j - 1];
+        }
+        samp[j] = t;
+    }
+}
diff --git a/contrib/blossom/concorde97/UTIL/urandom.c b/contrib/blossom/concorde97/UTIL/urandom.c
new file mode 100644
index 0000000000000000000000000000000000000000..2b6b09049651b4ad2c87f4af0d1a7eb5ac12210d
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/urandom.c
@@ -0,0 +1,140 @@
+/***************************************************************************/
+/*                                                                         */
+/*              MACHINE INDEPENDENT RANDOM NUMBER GENERATOR                */
+/*                                                                         */
+/*                             TSP CODE                                    */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  DIMACS  (modified for TSP)                                */
+/*  Date: February 7, 1995  (cofeb16)                                      */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    void CCutil_sprand (int seed)                                        */
+/*      - Call once to initialize the generator.                           */
+/*    int CCutil_lprand (void)                                             */
+/*      - Returns an integer in the range 0 to PRANDMAX - 1.               */
+/*                                                                         */
+/*    NOTES (from DIMACS):                                                 */
+/*        This file contains a set of c-language functions for generating  */
+/*    uniform integers.   This is a COMPLETELY PORTABLE generator. It will */
+/*    give IDENTICAL sequences of random numbers for any architecture with */
+/*    at least 30-bit integers, regardless of the integer representation,  */
+/*    MAXINT value, or roundoff/truncation method, etc.                    */
+/*        This Truly Remarkable RNG is described more fully in             */
+/*    J. Bentley's column, ``The Software Exploratorium ''. It is based on */
+/*    one in Knuth, Vol 2, Section 3.2.2 (Algorithm A).                    */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "machdefs.h"
+#include "util.h"
+
+#define PRANDMAX 1000000000
+static int a;
+static int b;
+static int arr[55];
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void CCutil_sprand (int seed)
+#else
+void CCutil_sprand (seed)
+int seed;
+#endif
+{
+    int i, ii;
+    int last, next;
+
+    seed %= PRANDMAX;
+    if (seed < 0) seed += PRANDMAX;
+
+    arr[0] = last = seed;
+    next = 1;
+    for (i = 1; i < 55; i++) {
+        ii = (21 * i) % 55;
+        arr[ii] = next;
+        next = last - next;
+        if (next < 0)
+            next += PRANDMAX;
+        last = arr[ii];
+    }
+    a = 0;
+    b = 24;
+    for (i = 0; i < 165; i++)
+        last = CCutil_lprand ();
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_lprand (void)
+#else
+int CCutil_lprand ()
+#endif
+{
+    int t;
+
+    if (a-- == 0)
+        a = 54;
+    if (b-- == 0)
+        b = 54;
+
+    t = arr[a] - arr[b];
+
+    if (t < 0)
+        t += PRANDMAX;
+
+    arr[a] = t;
+
+    return t;
+}
+
+
+#ifdef      TRY_CODE
+
+/*-----------------------------------------------*/
+/* This is a little driver program so you can    */
+/* test the code.                                */
+/* Typing: a.out 0 3 1                           */
+/* should produce                                */
+/*     921674862                                 */
+/*     250065336                                 */
+/*     377506581                                 */
+/*  Typing: a.out 1000000 1 2                    */
+/*  should produce                               */
+/*     57265995                                  */
+/*-----------------------------------------------*/
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int i;
+    int j;
+    int n;
+    int m;
+    int seed;
+
+    if (ac < 4) {
+        fprintf (stderr, "Usage: #discard #print #seed\n");
+        return 0;
+    }
+    m = atoi (av[1]);           /* Number to discard initially */
+    n = atoi (av[2]);           /* Number to print */
+    seed = atoi (av[3]);        /* Seed */
+
+    CCutil_sprand (seed);
+
+    for (i = 0; i < m; i++)
+        j = CCutil_lprand ();
+    for (i = 0; i < n; i++)
+        printf ("%ld\n", CCutil_lprand ());
+    return 0;
+}
+
+#endif  /* TRY_CODE */
diff --git a/contrib/blossom/concorde97/UTIL/util.c b/contrib/blossom/concorde97/UTIL/util.c
new file mode 100644
index 0000000000000000000000000000000000000000..50e6fa6fbea792e075bea31b822020cc4586a4e8
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/util.c
@@ -0,0 +1,96 @@
+/***************************************************************************/
+/*                                                                         */
+/*               MISCELLANEOUS UTILITY ROUTINES                            */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: October 12, 1995                                                 */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "macrorus.h"
+#include "util.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    isprime (unsigned int x);
+
+#else
+
+static int
+    isprime ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+unsigned int CCutil_nextprime (unsigned int x)
+#else
+unsigned int CCutil_nextprime (x)
+unsigned int x;
+#endif
+{
+    if (x < 3) return 3;
+    x |= 1;
+    while (!isprime (x)) x += 2;
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int isprime (unsigned int p)
+#else
+static int isprime (p)
+unsigned int p;
+#endif
+{
+    unsigned int i;
+
+    if ((p&1) == 0) return 0;
+    for (i=3; i*i<=p; i+=2) {
+        if (p%i == 0) return 0;
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int CCutil_our_gcd (int a, int b)
+#else
+int CCutil_our_gcd (a, b)
+int a;
+int b;
+#endif
+{
+    int c;
+
+    if (a < 0) a = -a;
+    if (b < 0) b = -b;
+    if (a > b) CC_SWAP (a, b, c);
+
+    while (a) {
+        c = b % a;
+        b = a;
+        a = c;
+    }
+    return b;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+char *CCutil_strrchr (char *s, int c)
+#else
+char *CCutil_strrchr (s, c)
+char *s;
+int c;
+#endif
+{
+    char *l = (char *) NULL;
+
+    while (*s) {
+        if (*s == c) l = s;
+        s++;
+    }
+    return l;
+}
+
diff --git a/contrib/blossom/concorde97/UTIL/zeit.c b/contrib/blossom/concorde97/UTIL/zeit.c
new file mode 100644
index 0000000000000000000000000000000000000000..3b9a677c1a3cb411028d2118441dfc239e7a186f
--- /dev/null
+++ b/contrib/blossom/concorde97/UTIL/zeit.c
@@ -0,0 +1,92 @@
+/***************************************************************************/
+/*                                                                         */
+/*                        TIMING FUNCTIONS                                 */
+/*                                                                         */
+/*                            TSP CODE                                     */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: Summer 1994  (cofeb16)                                           */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED FUNCTIONS:                                                    */
+/*    double CCutil_zeit (void)                                            */
+/*        - To measure cpu time.                                           */
+/*                                                                         */
+/*    double CCutil_real_zeit (void)                                       */
+/*        - To measure wall clock time.                                    */
+/*                                                                         */
+/*    NOTES:                                                               */
+/*       To use these, set double t = CCutil_zeit (), run the function you */
+/*    want to time, then commpute CCutil_zeit () - t.                      */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "machdefs.h"
+#include "util.h"
+
+#ifdef CC_ZEIT_RUSAGE
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#ifdef CC_PROTOTYPE_ANSI
+double CCutil_zeit (void)
+#else
+double CCutil_zeit ()
+#endif
+{
+    struct rusage ru;
+
+    getrusage (RUSAGE_SELF, &ru);
+
+    return ((double) ru.ru_utime.tv_sec) +
+            ((double) ru.ru_utime.tv_usec) / 1000000.0;
+}
+#endif /* CC_ZEIT_RUSAGE */
+
+#ifdef CC_ZEIT_TIMES
+
+#include <sys/param.h>
+#include <sys/times.h>
+
+#ifdef CLK_TCK
+#define MACHINE_FREQ CLK_TCK
+#else
+#define MACHINE_FREQ HZ
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+double CCutil_zeit (void)
+#else
+double CCutil_zeit ()
+#endif
+{
+    struct tms now;
+
+    times (&now);
+    return ((double) now.tms_utime) / ((double) MACHINE_FREQ);
+}
+#endif /* CC_ZEIT_TIMES */
+
+#ifdef CC_ZEIT_DUMMY
+
+#ifdef CC_PROTOTYPE_ANSI
+double CCutil_zeit (void)
+#else
+double CCutil_zeit ()
+#endif
+{
+    return 0.0;
+}
+#endif /* CC_ZEIT_DUMMY */
+
+#ifdef CC_PROTOTYPE_ANSI
+double CCutil_real_zeit (void)
+#else
+double CCutil_real_zeit ()
+#endif
+{
+    return (double) time (0);
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Makefile b/contrib/blossom/concorde97/XSTUFF/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..25383be61bb23849300913ea99374e747aac80ac
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Makefile
@@ -0,0 +1,73 @@
+SHELL=/bin/sh
+ROOT=..
+INCLUDE=$(ROOT)/INCLUDE
+
+include $(ROOT)/Makefile.conf
+
+# place overrides for COMFLAGS, OPTFLAGS, and LOADFLAGS here
+#OPTFLAGS=-g
+
+LIB=Xstuff.a
+LIBSRCS=Xourallo.c Xgraph.c   Xshrink.c Xflow.c   Xcututil.c Xcuthash.c \
+        Xcclean.c  Xcutload.c Xblock.c  Xclique.c Xgomhu.c   Xblossom.c \
+        Xcuts.c    Xblobs.c   Xstuff.c  Xpqnew.c  Xnewkids.c Xallcuts.c \
+        Xnecklac.c
+ALLSRCS=Xtest.c    $(LIBSRCS)
+
+LIBS=$(ROOT)/TSP/tsp.a       $(ROOT)/BIGGUY/bigguy.a   \
+     $(ROOT)/LP/lp.a         $(ROOT)/CUT/cut.a         \
+     $(ROOT)/FMATCH/fmatch.a $(ROOT)/EDGEGEN/edgegen.a \
+     $(ROOT)/KDTREE/kdtree.a $(ROOT)/LINKERN/linkern.a \
+     $(ROOT)/UTIL/util.a
+
+all: Xtest $(LIB)
+
+Xtest: Xtest.$o $(LIB) $(LIBS)
+	$(CC) $(LDFLAGS) -o $@ $+ $(CPLEX_LIB) -lm
+
+clean:
+	-rm -f *.$o $(LIB) Xtest
+
+include $(INCLUDE)/Makefile.common
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+I=$(INCLUDE)
+
+Xallcuts.$o: Xallcuts.c $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xblobs.$o:   Xblobs.c   $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xblock.$o:   Xblock.c   $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xblossom.$o: Xblossom.c $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xcclean.$o:  Xcclean.c  $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xclique.$o:  Xclique.c  $(I)/machdefs.h      Xsubtour.h      Xcutpool.h 
+Xcuthash.$o: Xcuthash.c $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xcutload.$o: Xcutload.c $(I)/machdefs.h      Xsubtour.h      Xcutpool.h 
+Xcuts.$o:    Xcuts.c    $(I)/machdefs.h      Xsubtour.h      Xcutpool.h 
+Xcututil.$o: Xcututil.c $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xflow.$o:    Xflow.c    $(I)/machdefs.h      Xsubtour.h      Xcutpool.h 
+Xgomhu.$o:   Xgomhu.c   $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xgraph.$o:   Xgraph.c   $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h 
+Xnecklac.$o: Xnecklac.c $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h      Xpq.h           Xpqsets.h       Xnecklac.h 
+Xnewkids.$o: Xnewkids.c $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h      Xpq.h           Xpqsets.h  
+Xourallo.$o: Xourallo.c $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h      Xnecklac.h 
+Xpqnew.$o:   Xpqnew.c   $(I)/machdefs.h $(I)/util.h          Xsubtour.h \
+             Xcutpool.h      Xpq.h           Xpqsets.h  
+Xshrink.$o:  Xshrink.c  $(I)/machdefs.h      Xsubtour.h      Xcutpool.h 
+Xstuff.$o:   Xstuff.c   $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h        Xsubtour.h      Xcutpool.h $(I)/Xstuff.h   
+Xtest.$o:    Xtest.c    $(I)/machdefs.h $(I)/util.h     $(I)/tsp.h      \
+        $(I)/edgegen.h  $(I)/bigguy.h   $(I)/lp.h       $(I)/cut.h      \
+        $(I)/kdtree.h   $(I)/Xstuff.h   
diff --git a/contrib/blossom/concorde97/XSTUFF/Xallcuts.c b/contrib/blossom/concorde97/XSTUFF/Xallcuts.c
new file mode 100644
index 0000000000000000000000000000000000000000..7c72b46992d38efd107cd8fc585afebbc29b6540
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xallcuts.c
@@ -0,0 +1,489 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTION:                                                     */
+/*        void  all_tightcuts ()                                          */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    magiclabel_nodes (Xnodeptr *S, int v),
+    test_cut (Xnode *, Xedge *),
+    found_tight_cut (Xnodeptr *),
+    unbump_S (Xnodeptr *, Xedge *),
+    buildpseudonodelist_pathshrink (int),
+    collect_nodes (Xnode *);
+
+static int
+    next_min_cut (Xnodeptr *, Xnode *, Xnode *, Xedge *, Xnodeptr **);
+
+static double
+    cut_value (Xnodeptr *S);
+
+static Xnode
+    *next_node (Xnode *, Xnode *);
+
+#else
+
+static void
+    magiclabel_nodes (),
+    test_cut (),
+    found_tight_cut (),
+    unbump_S (),
+    buildpseudonodelist_pathshrink (),
+    collect_nodes ();
+
+static int
+    next_min_cut ();
+
+static double
+    cut_value ();
+
+static Xnode
+    *next_node ();
+
+#endif
+
+
+#define EPSILON (0.0005)
+
+#define TWO      2.0
+#define TWOPLUS  (2.0 + EPSILON)
+#define TWOMINUS (2.0 - EPSILON)
+#define ONEMINUS (1.0 - EPSILON/2)
+
+static Xclique **cliquelist;
+static int *ncliques;
+static int quiet = 0;
+static Xgraph *G;
+
+#ifdef CC_PROTOTYPE_ANSI
+void  Xall_tightcuts (Xgraph *Gin, Xclique **cliquelistin, int *ncliquesin)
+#else
+void  Xall_tightcuts (Gin, cliquelistin, ncliquesin)
+Xgraph *Gin;
+Xclique **cliquelistin;
+int *ncliquesin;
+#endif
+{
+    Xnode *s;
+    Xedgeptr *ep;
+    Xedge *e;
+    int i;
+    Xclique *c;
+    Xintptr *p;
+
+    G = Gin;
+    cliquelist = cliquelistin;
+    ncliques = ncliquesin;
+
+    buildpseudonodelist_pathshrink (1);
+
+    for (i = 0; i < G->nedges; i++) {
+        if (G->edgelist[i].x > ONEMINUS) {
+            c = Xcliquealloc ();
+            p = Xintptralloc ();
+            p->this = G->edgelist[i].ends[0] - G->nodelist;
+            p->next = (Xintptr *) NULL;
+            c->nodes = p;
+            p = Xintptralloc ();
+            p->this = G->edgelist[i].ends[1] - G->nodelist;
+            p->next = c->nodes;
+            c->nodes = p;
+            c->slack = 1.0 - G->edgelist[i].x;
+            c->next = *cliquelist;
+            *cliquelist = c;
+            (*ncliques)++;
+        }
+    }
+
+    for (s = G->pseudonodelist->next; s; s = s->next) {
+        for (ep = s->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (s == e->cends[0]) {
+                test_cut (s, e);
+                e->x += 2.5;    /* So we won't hit these again */
+            }
+        }
+    }
+
+    for (s = G->pseudonodelist->next; s; s = s->next) {
+        Xedgeptr_list_free (s->cadj.head);
+        s->cadj.head = (Xedgeptr *) NULL;
+        s->cadj.tail = (Xedgeptr *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void  test_cut (Xnode *s, Xedge *st)
+#else
+static void  test_cut (s, st)
+Xnode *s;
+Xedge *st;
+#endif
+{
+    Xnodeptr *S, *smallest;
+    Xnode *t;
+
+    /* Find all cuts containing edge st (and chose the side missing s) */
+
+    t = OTHERCURRENTEND (st, s);
+    smallest = (Xnodeptr *) NULL;
+    Xadd_nodeptr (&smallest, t);
+
+    /* printf ("Cuts containing (%d, %d)\n", s - G->nodelist, t - G->nodelist); */
+    do {
+        S = smallest;
+        if (next_min_cut (S, s, t, st, &smallest)) {
+            found_tight_cut (smallest);
+            if (!quiet && (cut_value (smallest) < TWOMINUS ||
+                           cut_value (smallest) > TWOPLUS)) {
+                fprintf (stderr, "PROBLEM WITH CUT VALUE %f\n",
+                         cut_value (smallest));
+                fflush (stderr);
+            }
+        }
+        Xnodeptr_list_free (S);
+    } while (smallest);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void  found_tight_cut (Xnodeptr *smallest)
+#else
+static void  found_tight_cut (smallest)
+Xnodeptr *smallest;
+#endif
+{
+    int count;
+    Xnodeptr *np, *np2;
+    int match;
+    int i;
+    Xclique *c;
+    Xintptr *p;
+
+    for (i = 0; i < G->nnodes; i++) {
+        G->nodelist[i].mark = 0;
+    }
+
+    for (count = 0, np = smallest; np; np = np->next) {
+        for (np2 = np->this->base.head; np2; np2 = np2->next) {
+            count++;
+            np2->this->mark = 1;
+        }
+    }
+
+    if (count != (G->nnodes - 1) && count != 1) {
+        if (count > G->nnodes / 2)
+            match = 0;
+        else
+            match = 1;
+        c = Xcliquealloc ();
+        c->nodes = (Xintptr *) NULL;
+        for (i = 0; i < G->nnodes; i++) {
+            if (G->nodelist[i].mark == match) {
+                p = Xintptralloc ();
+                p->this = i;
+                p->next = c->nodes;
+                c->nodes = p;
+            }
+        }
+        c->slack = 0.0;
+        c->next = *cliquelist;
+        *cliquelist = c;
+        (*ncliques)++;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int  next_min_cut (Xnodeptr *S, Xnode *s, Xnode *t, Xedge *st, Xnodeptr **smallest)
+#else
+static int next_min_cut (S, s, t, st, smallest)
+Xnodeptr *S;
+Xnode *s, *t;
+Xedge *st;
+Xnodeptr **smallest;
+#endif
+{
+    Xnodeptr *np, *nlist;
+    Xnode *n;
+    Xedgeptr *ep, *delta;
+    Xedge *e;
+    int least_count, count, label;
+    double val;
+
+    *smallest = (Xnodeptr *) NULL;
+
+    G->magicnum++;
+    for (np = S; np; np = np->next) {
+        if (np->this == s) {
+            printf ("%d in S\n", (int) (s - G->nodelist));
+            return 0;
+        }
+        np->this->magiclabel = G->magicnum;
+    }
+    delta = (Xedgeptr *) NULL;
+    for (np = S; np; np = np->next) {
+        n = np->this;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            if ((e = ep->this) == st)
+                continue;
+            if ((OTHERCURRENTEND (e, n))->magiclabel == G->magicnum) {
+                if (e->x < 4.0)
+                    e->x += 4.0;
+            } else
+                Xadd_edgeptr (&delta, e);
+        }
+    }
+
+    if (Xflow (G, s, t, TWOPLUS) >= TWOPLUS) {
+        unbump_S (S, st);
+        Xedgeptr_list_free (delta);
+        return 0;
+    }
+    least_count = G->nnodes + 1;
+    for (ep = delta; ep; ep = ep->next) {
+        e = ep->this;
+        e->x += 4.0;
+        if (Xmincut (G, s, t, TWOPLUS, &val, &label)) {
+            count = 0;
+            nlist = (Xnodeptr *) NULL;
+            for (n = G->pseudonodelist->next; n; n = n->next)
+                if (n->magiclabel == label) {
+                    count++;
+                    Xadd_nodeptr (&nlist, n);
+                }
+            if (count < least_count) {
+                least_count = count;
+                if (*smallest)
+                    Xnodeptr_list_free (*smallest);
+                *smallest = nlist;
+            } else
+                Xnodeptr_list_free (nlist);
+        }
+        e->x -= 4.0;
+    }
+
+    unbump_S (S, st);
+    Xedgeptr_list_free (delta);
+
+    return (*smallest != (Xnodeptr *) NULL);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void  unbump_S (Xnodeptr *S, Xedge *st)
+#else
+static void  unbump_S (S, st)
+Xnodeptr *S;
+Xedge *st;
+#endif
+{
+    Xnodeptr *np;
+    Xnode *n;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    magiclabel_nodes (S, ++G->magicnum);
+    for (np = S; np; np = np->next) {
+        n = np->this;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            if ((e = ep->this) == st)
+                continue;
+            if ((OTHERCURRENTEND (e, n))->magiclabel == G->magicnum) {
+                if (e->x >= 4.0)
+                    e->x -= 4.0;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void  buildpseudonodelist_pathshrink (int all)
+#else
+static void  buildpseudonodelist_pathshrink (all)
+int all;
+#endif
+{
+    /* modified 2/10 to compress paths of ones */
+    int i;
+    Xnode *n;
+    Xedge *e;
+    Xedgeptr *e1;
+    static Xnode pseudodummy;
+    Xnode *nprev;
+    Xnode *n2;
+
+    for (i = 0; i < G->nnodes; i++) {
+        G->nodelist[i].Tmark = 0;
+        G->nodelist[i].tnext = (Xnode *) NULL;
+    }
+
+    for (i = 0; i < G->nedges; i++) {
+        if (G->edgelist[i].x > ONEMINUS) {
+            G->edgelist[i].ends[0]->Tmark++;
+            G->edgelist[i].ends[1]->Tmark++;
+        }
+    }
+
+    G->pseudonodelist = &pseudodummy;
+    pseudodummy.prev = (Xnode *) NULL;
+    pseudodummy.next = (Xnode *) NULL;
+    nprev = G->pseudonodelist;
+    for (i = 0, n = G->nodelist; i < G->nnodes; i++, n++) {
+        n->base.head = Xnodeptralloc ();
+        n->base.tail = n->base.head;
+        n->base.head->next = (Xnodeptr *) NULL;
+        n->base.head->this = n;
+        if (n->Tmark == 1) {
+            collect_nodes (n);
+        }
+        n->cadj.head = n->cadj.tail = (Xedgeptr *) NULL;
+        if (n->Tmark != 2) {
+            n->prev = nprev;
+            nprev->next = n;
+            nprev = n;
+            n->tnext = n;
+        }
+    }
+    for (i=0; i<G->nnodes; i++) {
+        if (G->nodelist[i].tnext == (Xnode *) NULL) {
+            printf ("ALLCUTS GRAPH CONTAINS CYCLE\n");
+            n = next_node (&G->nodelist[i], (Xnode *) NULL);
+            n2 = next_node (&G->nodelist[i], n); /* this trusts that next_node is consistent between calls */
+            G->nodelist[i].Tmark = 1;
+            n2->Tmark = 1;
+            collect_nodes (&G->nodelist[i]);
+            G->nodelist[i].prev = nprev;
+            nprev->next = &G->nodelist[i];
+            nprev = &G->nodelist[i];
+            G->nodelist[i].tnext = &G->nodelist[i];
+        }
+    }
+    nprev->next = (Xnode *) NULL;
+
+    for (i = G->nedges, e = G->edgelist; i; i--, e++) {
+        if ((all || e->x > 0.0) && e->ends[0]->tnext != e->ends[1]->tnext) {
+            e->stay = 1;
+            e->cends[0] = e->ends[0]->tnext;
+            e->cends[1] = e->ends[1]->tnext;
+            e1 = Xedgeptralloc ();
+            e1->next = (e->cends[0])->cadj.head;
+            e1->this = e;
+            (e->cends[0])->cadj.head = e1;
+            if ((e->cends[0])->cadj.tail == (Xedgeptr *) NULL) {
+                (e->cends[0])->cadj.tail = e1;
+            }
+            e1 = Xedgeptralloc ();
+            e1->next = (e->cends[1])->cadj.head;
+            e1->this = e;
+            (e->cends[1])->cadj.head = e1;
+            if ((e->cends[1])->cadj.tail == (Xedgeptr *) NULL) {
+                (e->cends[1])->cadj.tail = e1;
+            }
+        } else {
+            e->stay = 0;
+        }
+    }
+    G->npseudonodes = G->nnodes;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xnode  *next_node (Xnode *n, Xnode *nold)
+#else
+static Xnode  *next_node (n, nold)
+Xnode *n;
+Xnode *nold;
+#endif
+{
+    Xedgeptr *ep;
+
+    for (ep = n->adj.head; ep; ep = ep->next) {
+        if (ep->this->x > ONEMINUS) {
+            if (ep->this->ends[0] != n && ep->this->ends[0] != nold) {
+                return ep->this->ends[0];
+            } else if (ep->this->ends[1] != n && ep->this->ends[1] != nold) {
+                return ep->this->ends[1];
+            }
+        }
+    }
+    return (Xnode *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void  collect_nodes (Xnode *n)
+#else
+static void  collect_nodes (n)
+Xnode *n;
+#endif
+{
+    Xnode *nold;
+    Xnode *nnew;
+    Xnode *ncur;
+    Xnodeptr *np;
+
+    ncur = n;
+    nold = (Xnode *) NULL;
+
+    while ((nnew = next_node (ncur, nold)) && nnew->Tmark == 2) {
+        nold = ncur;
+        ncur = nnew;
+        ncur->tnext = n;
+        np = Xnodeptralloc ();
+        np->this = ncur;
+        np->next = (Xnodeptr *) NULL;
+        if (!n->base.tail) {
+            n->base.tail = n->base.head = np;
+        } else {
+            n->base.tail->next = np;
+            n->base.tail = np;
+        }
+    }
+    if (!nnew) {
+        fprintf (stderr, "Path vanished\n");
+        exit (1);
+    }
+    nnew->Tmark = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double cut_value (Xnodeptr *S)
+#else
+static double cut_value (S)
+Xnodeptr *S;
+#endif
+{
+    double val = 0.0;
+    Xnodeptr *np;
+    Xnode *n;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    magiclabel_nodes (S, ++(G->magicnum));
+    for (np = S; np; np = np->next) {
+        n = np->this;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (OTHERCURRENTEND (e, n)->magiclabel != G->magicnum)
+                val += e->x;
+        }
+    }
+    return val;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void magiclabel_nodes (Xnodeptr *S, int v)
+#else
+static void magiclabel_nodes (S, v)
+Xnodeptr *S;
+int v;
+#endif
+{
+    Xnodeptr *np;
+
+    for (np = S; np; np = np->next)
+        np->this->magiclabel = v;
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xblobs.c b/contrib/blossom/concorde97/XSTUFF/Xblobs.c
new file mode 100644
index 0000000000000000000000000000000000000000..a13429a7dfb7bb55a00f29e5fe91e7b66e5abb1e
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xblobs.c
@@ -0,0 +1,1293 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    void                                                                */
+/*        Xpancakex (Xgraph *G, double *x),                               */
+/*        Xfreepancake (void),                                            */
+/*        Xshrinksmallblobs (Xgraph *G, int rnum, int biggest),           */
+/*        Xtightblobs (Xgraph *G);                                        */
+/*                                                                        */
+/*    int                                                                 */
+/*        Xblobsviolated (Xgraph *G, Xcplane **list );                    */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+typedef struct pannode {
+    struct panedge **edgelist;
+    struct panedge **goodedge;
+    int degree;
+    struct vaseknode *vptr;
+} pannode;
+
+typedef struct panedge {
+    double panweight;
+    pannode *ends[2];
+    int elim;
+    int tag;
+    struct vaseknode *a[2];
+    struct vaseknode *roof;
+    struct vaseknode *top;
+    struct panedge *next;
+    double rc;
+    double realrc;
+} panedge;
+
+typedef struct vaseknode {
+    struct vaseknode *parent;
+    struct vaseknode *child;
+    struct vaseknode *sibling;
+    struct vaseknode *anc;
+    struct vaseknode *ptr;
+    struct vaseknode *qtr;
+    struct vaseknode *listpointer;
+    int b;
+    int d;
+    int n;
+    int tag;
+    int fringe;
+    double y;
+    double w;
+    double mult;
+    struct panedge *tree;
+    struct panedge *junk;
+    struct triomino *adj;
+    struct triomino *scan;
+} vaseknode;
+
+typedef struct triomino {
+    panedge *edge;
+    vaseknode *end;
+    struct triomino *next;
+} triomino;
+
+
+static panedge **panedgespace, *panedgelist;
+static pannode *pannodelist;
+
+
+#define XPOSITIVE 1
+
+#define VNODEALLOC(vrequest) {                                          \
+        if (vnodestack == (vaseknode *) NULL) {                         \
+                printf ("Ran out of vnode supply\n");                   \
+                exit (1);                                               \
+        }                                                               \
+        vrequest = vnodestack;                                          \
+        vnodestack = vnodestack->ptr;                                   \
+    }
+
+#define VNODEFREE(vreturn) {                                            \
+        vreturn->ptr = vnodestack;                                      \
+        vnodestack = vreturn;                                           \
+    }
+
+#define TRIALLOC(trequest) {                                            \
+        trequest = tristack;                                            \
+        tristack = tristack->next;                                      \
+    }
+
+#define TRIFREE(treturn) {                                              \
+        treturn->next = tristack;                                       \
+        tristack = treturn;                                             \
+    }
+
+#define XSHORT 1000
+#define XFEW 1
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    panalloc (Xgraph *G),
+    buildpanadjlist (Xgraph *G),
+    pancakemain (Xgraph *G),
+    initpancake (Xgraph *G),
+    buildfirsttree (Xgraph *G),
+    decompositiontree (Xgraph *G),
+    initdecompositiontree (Xgraph *G),
+    drop (panedge *e, vaseknode *x),
+    throw (vaseknode *x, vaseknode *y, panedge *e),
+    trickledown (int i),
+    hookup (vaseknode *parent, vaseknode *child),
+    distribute (void),
+    initdistribute (void),
+    split (vaseknode *a),
+    bruteforce (panedge *e),
+    update (panedge *e),
+    dealwith (panedge *e, vaseknode **pa),
+    attach (panedge *e),
+    magicrc (void),
+    labeler (Xgraph *G, vaseknode *p),
+    shrinkblob (Xgraph *G, vaseknode *v);
+
+static int
+    ssblob (Xgraph *G, vaseknode *v, int rnum, int biggest, int *shrunk);
+
+static double
+    min2 (panedge **elist),
+    findbound (void),
+    blnode (Xgraph *G, Xcplane **list, vaseknode *v, int *hit),
+    tblob (Xgraph *G, vaseknode *v, int *count);
+
+static vaseknode
+    *anc (vaseknode *v),
+    *vsmall (Xgraph *G, vaseknode *p),
+    *newcomp (vaseknode *v, double w);
+
+#else
+
+static void
+    panalloc (),
+    buildpanadjlist (),
+    pancakemain (),
+    initpancake (),
+    buildfirsttree (),
+    decompositiontree (),
+    initdecompositiontree (),
+    drop (),
+    throw (),
+    trickledown (),
+    hookup (),
+    distribute (),
+    initdistribute (),
+    split (),
+    bruteforce (),
+    update (),
+    dealwith (),
+    attach (),
+    magicrc (),
+    labeler (),
+    shrinkblob ();
+
+static int
+    ssblob ();
+
+static double
+    min2 (),
+    findbound (),
+    blnode (),
+    tblob ();
+
+static vaseknode
+    *anc (),
+    *vsmall (),
+    *newcomp ();
+
+#endif
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    dumpwork (void),
+    dumpdecompositiontree (Xgraph *G),
+    dumpvaseknodes (Xgraph *G, vaseknode *pv),
+    printvaseknode (vaseknode *v);
+#else
+static void
+    dumpdecompositiontree (),
+    dumpwork (),
+    dumpvaseknodes (),
+    printvaseknode ();
+#endif
+#endif /* DEBUG */
+
+#define XMAGICNODE 0
+
+static int step = 0;
+static vaseknode *root;
+static vaseknode *vpannodes = (vaseknode *) NULL, *vnodehit;
+static vaseknode *head, *tail;
+static vaseknode *vnodestack = (vaseknode *) NULL;
+static triomino *trisupply, *tristack;
+static panedge *work;
+static panedge **vheap;
+static int vheapend = 0;
+static int componentcount = 0;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xpancakex (Xgraph *G, double *x)
+#else
+void Xpancakex (G, x)
+Xgraph *G;
+double *x;
+#endif
+{
+    double *dp;
+    int i;
+    panedge *pm;
+
+    panalloc (G);
+    Xloadx (G, x);
+
+    for (i = G->nedges, pm = panedgelist, dp = x; i; i--, pm++)
+        pm->panweight = -(*dp++);
+
+    pancakemain (G);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void panalloc (Xgraph *G)
+#else
+static void panalloc (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    Xedge *pe;
+    panedge *pa;
+
+    pannodelist = CC_SAFE_MALLOC (G->nnodes + 1000, pannode);
+    panedgelist = CC_SAFE_MALLOC (G->nedges + 1000, panedge);
+    if (!pannodelist || !panedgelist) {
+        fprintf (stderr, "out of memory in panalloc\n");
+        exit (1);
+    }
+
+    for (i = G->nedges, pa = panedgelist, pe = G->edgelist; i;
+                                                       i--, pa++, pe++) {
+        pa->ends[0] = pannodelist + (pe->ends[0] - G->nodelist);
+        pa->ends[1] = pannodelist + (pe->ends[1] - G->nodelist);
+    }
+
+    buildpanadjlist (G);
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildpanadjlist (Xgraph *G)
+#else
+static void buildpanadjlist (G)
+Xgraph *G;
+#endif
+{
+    int i, *degrees, *pint;
+    pannode *pv;
+    panedge *pa, **edgespace;
+    Xedge *pe;
+
+    edgespace = CC_SAFE_MALLOC (G->nnodes + (G->nedges * 2) + 1000, panedge *);
+    degrees = CC_SAFE_MALLOC (G->nnodes + 1000, int);
+    if (!edgespace || !degrees) {
+        fprintf (stderr, "out of memory in buildpadadjlist\n");
+        exit (1);
+    }
+    panedgespace = edgespace;
+
+    for (i = 0, pint = degrees; i < G->nnodes; i++)
+        *pint++ = 0;
+
+    for (i = 0, pe = G->edgelist; i < G->nedges; i++, pe++) {
+        degrees[pe->ends[0] - G->nodelist]++;
+        degrees[pe->ends[1] - G->nodelist]++;
+    }
+
+    for (i = 0, pint = degrees, pv = pannodelist; i < G->nnodes;
+         i++, pint++, pv++) {
+        if (*pint) {
+            pv->edgelist = pv->goodedge = edgespace;
+            edgespace += *pint + 1;
+        } else
+            pv->edgelist = pv->goodedge = (panedge **) NULL;
+    }
+
+    for (i = 0, pa = panedgelist; i < G->nedges; i++, pa++) {
+        *(pa->ends[0]->goodedge++) = pa;
+        *(pa->ends[1]->goodedge++) = pa;
+    }
+
+    for (i = 0, pv = pannodelist; i < G->nnodes; i++, pv++)
+        *(pv->goodedge) = (panedge *) NULL;
+
+    CC_FREE (degrees, int);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void pancakemain (Xgraph *G)
+#else
+static void pancakemain (G)
+Xgraph *G;
+#endif
+{
+    initpancake (G);
+    buildfirsttree (G);
+    findbound ();
+    /* printf ("decompositiontree: %lf\n", findbound ()); */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void initpancake (Xgraph *G)
+#else
+static void initpancake (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    pannode *pn;
+    vaseknode *pv;
+    triomino *pt;
+
+    vpannodes = CC_SAFE_MALLOC ((2 * G->nnodes) - 1 + 1000, vaseknode);
+    if (!vpannodes) {
+        fprintf (stderr, "out of memory in initpancake\n");
+        exit (1);
+    }
+
+    for (i = G->nnodes, pn = pannodelist, pv = vpannodes; i; i--, pn++, pv++) {
+        pv->parent = (vaseknode *) NULL;
+        pv->child = (vaseknode *) NULL;
+        pv->sibling = (vaseknode *) NULL;
+        pv->adj = (triomino *) NULL;
+        pv->n = 0;
+        pv->b = 1;
+        pv->anc = pv;
+        pv->junk = (panedge *) NULL;
+        pv->w = XBIGNEG;
+        pv->y = 0.0;
+        pn->vptr = pv;
+    }
+
+    vnodestack = vpannodes + G->nnodes;
+    for (i = G->nnodes - 2, pv = vnodestack; i; i--, pv++)
+        pv->ptr = pv + 1;
+    pv->ptr = (vaseknode *) NULL;
+
+    trisupply = CC_SAFE_MALLOC (2 * G->nedges + 1000, triomino);
+    if (!trisupply) {
+        fprintf (stderr, "out of memory in initpancake\n");
+        exit (1);
+    }
+
+    tristack = trisupply;
+    for (i = 2 * G->nedges - 1, pt = tristack; i; i--, pt++)
+        pt->next = pt + 1;
+
+    VNODEALLOC (head);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xfreepancake (void)
+#else
+void Xfreepancake ()
+#endif
+{
+    CC_FREE (vpannodes, vaseknode);
+    CC_FREE (trisupply, triomino);
+    CC_FREE (vheap, panedge *);
+    CC_FREE (pannodelist, pannode);
+    CC_FREE (panedgelist, panedge);
+    CC_FREE (panedgespace, panedge *);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildfirsttree (Xgraph *G)
+#else
+static void buildfirsttree (G)
+Xgraph *G;
+#endif
+{
+    vaseknode *p;
+    double parw;
+    vaseknode *q;
+
+    decompositiontree (G);
+    distribute ();
+
+
+    head->ptr = tail = root;
+    p = head;
+    do {
+        p = p->ptr;
+        parw = p->w;
+        for (q = p->child; q != (vaseknode *) NULL; q = q->sibling) {
+            q->mult = parw - q->w;
+            if (q->child != (vaseknode *) NULL) {
+                tail->ptr = q;
+                tail = q;
+            }
+        }
+    } while (p != tail);
+    root->mult = -root->w;
+
+    magicrc ();
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void decompositiontree (Xgraph *G)
+#else
+static void decompositiontree (G)
+Xgraph *G;
+#endif
+{
+    panedge *e;
+    int i;
+    double w, ub;
+    vaseknode *x, *y;
+
+    initdecompositiontree (G);
+
+    for (componentcount = G->nnodes - 2; componentcount;) {
+        for (;;) {
+            e = *vheap;
+            *vheap = vheap[vheapend--];
+            trickledown (0);
+            x = anc (e->ends[0]->vptr);
+            y = anc (e->ends[1]->vptr);
+            if (x != y)
+                break;
+            drop (e, x);
+        }
+
+        w = e->panweight;
+        throw (x, y, e);
+
+        ub = w + 0.01;
+
+        while (vheapend >= 0 && (e = *vheap)->panweight < ub) {
+            *vheap = vheap[vheapend--];
+            trickledown (0);
+            x = anc (e->ends[0]->vptr);
+            y = anc (e->ends[1]->vptr);
+            if (x != y)
+                throw (x, y, e);
+            else
+                drop (e, x);
+        }
+
+        for (; vnodehit != (vaseknode *) NULL; vnodehit = vnodehit->ptr)
+            if (vnodehit->n)
+                root = newcomp (vnodehit, w);
+    }
+    i = vheapend + 1;
+    while (i)
+        drop (vheap[--i], root);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void initdecompositiontree (Xgraph *G)
+#else
+static void initdecompositiontree (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    panedge *pe, **ph;
+    pannode *pm;
+
+    vnodehit = (vaseknode *) NULL;
+    work = (panedge *) NULL;
+
+    for (i = G->nedges, pe = panedgelist; i; i--, pe++)
+        pe->tag = XFALSE;
+
+    vheap = CC_SAFE_MALLOC (G->nedges + 1000, panedge *);
+    if (!vheap) {
+        fprintf (stderr, "out of memory in initdecompositiontree\n");
+        exit (1);
+    }
+
+    pm = pannodelist + XMAGICNODE;
+    for (i = G->nedges, pe = panedgelist, ph = vheap; i; i--, pe++)
+        if (pe->ends[0] != pm && pe->ends[1] != pm)
+            *(ph++) = pe;
+        else
+            pe->rc = pe->panweight;
+
+    vheapend = (ph - vheap) - 1;
+    for (i = vheapend / 2; i >= 0; i--)
+        trickledown (i);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void drop (panedge *e, vaseknode *x)
+#else
+static void drop (e, x)
+panedge *e;
+vaseknode *x;
+#endif
+{
+    e->a[0] = e->ends[0]->vptr;
+    e->a[1] = e->ends[1]->vptr;
+    e->roof = x;
+    e->rc = XPOSITIVE;
+    e->next = work;
+    work = e;
+}
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void dumpwork (void)
+#else
+static void dumpwork ()
+#endif
+{
+    panedge *pe;
+
+    printf ("WORK: ");
+    for (pe = work; pe != (panedge *) NULL; pe = pe->next)
+        printf ("(%d, %d) -> ", pe->ends[0] - pannodelist,
+                pe->ends[1] - pannodelist);
+    printf ("NULL\n");
+    fflush (stdout);
+}
+#endif /* DEBUG */
+
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void dumpdecompositiontree (Xgraph *G)
+#else
+static void dumpdecompositiontree (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    pannode *pn;
+
+    printf ("Nodes of the decomposition tree:\n");
+    for (i = 0, pn = pannodelist; i < G->nnodes; i++, pn++)
+        if (pn != pannodelist + XMAGICNODE)
+            dumpvaseknodes (G, pn->vptr);
+    printf ("\n");
+    fflush (stdout);
+}
+#endif /* DEBUG */
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void dumpvaseknodes (Xgraph *G, vaseknode *pv)
+#else
+static void dumpvaseknodes (G, pv)
+Xgraph *G;
+vaseknode *pv;
+#endif
+{
+    /* dump vaseknodes whose smallest real pannode is v */
+
+    vaseknode *p;
+
+    for (p = pv->parent; p != (vaseknode *) NULL && vsmall (G, p) == pv;
+                                                       p = p->parent) {
+        printf ("Node %d: ", p - vpannodes);
+        printvaseknode (p);
+        printf ("\n");
+    }
+    fflush (stdout);
+}
+#endif /* DEBUG */
+
+#ifdef CC_PROTOTYPE_ANSI
+static vaseknode *vsmall (Xgraph *G, vaseknode *p)
+#else
+static vaseknode *vsmall (G, p)
+Xgraph *G;
+vaseknode *p;
+#endif
+{
+    vaseknode *p1, *p2, *psmall = vpannodes + G->nnodes;
+
+    if (p->child == (vaseknode *) NULL)
+        return p;
+    for (p1 = p->child; p1 != (vaseknode *) NULL; p1 = p1->sibling)
+        if ((p2 = vsmall (G, p1)) < psmall)
+            psmall = p2;
+    return psmall;
+}
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void printvaseknode (vaseknode *p)
+#else
+static void printvaseknode (p)
+vaseknode *p;
+#endif
+{
+    vaseknode *p1;
+    panedge *pe;
+
+    if (p->child != (vaseknode *) NULL) {
+        for (p1 = p->child; p1 != (vaseknode *) NULL; p1 = p1->sibling)
+            printf ("%d ", p1 - vpannodes);
+    } else
+        printf ("%d ", p - vpannodes);
+    printf ("mult: %f ", p->mult);
+    printf ("parent: %d ", p->parent - vpannodes);
+    printf ("depth: %d ", p->d);
+    printf ("b: %d ", p->b);
+    printf ("junk: ");
+    for (pe = p->junk; pe != (panedge *) NULL; pe = pe->next)
+        printf ("(%d, %d) ", pe->ends[0] - pannodelist,
+                pe->ends[1] - pannodelist);
+    fflush (stdout);
+}
+#endif /* DEBUG */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void throw (vaseknode *x, vaseknode *y, panedge *e)
+#else
+static void throw (x, y, e)
+vaseknode *x, *y;
+panedge *e;
+#endif
+{
+    e->a[0] = x;
+    e->a[1] = y;
+
+    e->rc = 0.0;
+    attach (e);
+
+    if (!(x->n)) {
+        x->n = 1;
+        x->ptr = vnodehit;
+        vnodehit = x;
+    }
+    if (!(y->n)) {
+        y->n = 1;
+        y->ptr = vnodehit;
+        vnodehit = y;
+    }
+    e->next = work;
+    work = e;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static vaseknode *anc (vaseknode *v)
+#else
+static vaseknode *anc (v)
+vaseknode *v;
+#endif
+{
+    vaseknode *hand, *va;
+
+    hand = v;
+    while (hand != hand->anc)
+        hand = hand->anc;
+
+    va = hand;
+    for (hand = v; hand != va; hand = hand->anc)
+        hand->anc = va;
+
+    return va;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void trickledown (int i)
+#else
+static void trickledown (i)
+int i;
+#endif
+{
+    panedge *memo;
+    int k, minchild;
+
+    memo = vheap[i];
+
+    while ((k = (2 * i) + 2) <= vheapend) {
+        minchild = (vheap[k - 1]->panweight <= vheap[k]->panweight ? k - 1 : k);
+
+        if (memo->panweight > vheap[minchild]->panweight) {
+            vheap[i] = vheap[minchild];
+            i = minchild;
+        } else {
+            vheap[i] = memo;
+            return;
+        }
+    }
+    if (k - 1 == vheapend && memo->panweight > vheap[vheapend]->panweight) {
+        vheap[i] = vheap[vheapend];
+        i = vheapend;
+    }
+    vheap[i] = memo;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static vaseknode *newcomp (vaseknode *v, double w)
+#else
+static vaseknode *newcomp (v, w)
+vaseknode *v;
+double w;
+#endif
+{
+    vaseknode *new, *stack;
+    triomino *t;
+
+    VNODEALLOC (new);
+    new->parent = (vaseknode *) NULL;
+    new->child = (vaseknode *) NULL;
+    new->sibling = (vaseknode *) NULL;
+    new->anc = new;
+    new->n = 0;
+    new->b = 0;
+    new->w = w;
+    new->adj = (triomino *) NULL;
+    new->junk = (panedge *) NULL;
+    new->tag = XFALSE;
+
+    hookup (new, v);
+    v->qtr = (vaseknode *) NULL;
+
+    do {
+        stack = v->qtr;
+        for (t = v->adj; t != (triomino *) NULL; t = t->next) {
+            t->edge->roof = new;
+            v = t->end;
+            if (v->n) {
+                v->qtr = stack;
+                stack = v;
+                hookup (new, v);
+                componentcount--;
+            }
+        }
+    } while ((v = stack) != (vaseknode *) NULL);
+
+    return new;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void hookup (vaseknode *parent, vaseknode *child)
+#else
+static void hookup (parent, child)
+vaseknode *parent, *child;
+#endif
+{
+    child->n = 0;
+    child->parent = parent;
+    child->anc = parent;
+    child->sibling = parent->child;
+    parent->child = child;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void distribute (void)
+#else
+static void distribute ()
+#endif
+{
+    vaseknode *active;
+    panedge *e, *f;
+
+    initdistribute ();
+    active = (vaseknode *) NULL;
+    root->n = 0;
+
+    for (e = work, work = (panedge *) NULL; e != (panedge *) NULL; e = f) {
+        f = e->next;
+        e->top = root;
+        dealwith (e, &active);
+    }
+
+    while (work) {
+        for (; active != (vaseknode *) NULL; active = active->ptr)
+            if (active->n < XFEW)
+                active->n = -1;
+            else {
+                active->n = 0;
+                split (active);
+            }
+        for (e = work, work = (panedge *) NULL; e != (panedge *) NULL;
+                                                                    e = f) {
+            f = e->next;
+            if (e->top->n >= 0) {
+                update (e);
+                dealwith (e, &active);
+            } else
+                bruteforce (e);
+        }
+        step = step / 2;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void initdistribute (void)
+#else
+static void initdistribute ()
+#endif
+{
+    vaseknode *stack, *finger, *x;
+    int maxd, twice, d;
+
+    maxd = 0;
+
+    root->d = 0;
+    root->ptr = (vaseknode *) NULL;
+
+    for (finger = root; finger != (vaseknode *) NULL; finger = stack) {
+        stack = finger->ptr;
+        finger->anc = root;
+        if ((x = finger->child) != (vaseknode *) NULL) {
+            d = finger->d + 1;
+            do {
+                x->d = d;
+                x->ptr = stack;
+                stack = x;
+                x = x->sibling;
+            } while (x != (vaseknode *) NULL);
+            if (d > maxd)
+                maxd = d;
+        }
+    }
+    step = 1;
+    twice = 2;
+    while (twice < maxd) {
+        step = twice;
+        twice = step + step;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void split (vaseknode *a)
+#else
+static void split (a)
+vaseknode *a;
+#endif
+{
+    int mid, bot;
+    vaseknode *stack, *hand, *foot, *memo, *x;
+
+    mid = step + a->d;
+    bot = step + mid;
+
+    a->qtr = (vaseknode *) NULL;
+    for (hand = a; hand != (vaseknode *) NULL; hand = stack) {
+        stack = hand->qtr;
+        if (hand->d == mid) {
+            memo = hand->qtr;
+            hand->qtr = (vaseknode *) NULL;
+            for (foot = hand; foot != (vaseknode *) NULL; foot = stack) {
+                stack = foot->qtr;
+                foot->anc = hand;
+                if (foot->d != bot) {
+                    for (x = foot->child; x != (vaseknode *) NULL;
+                         x = x->sibling) {
+                        x->qtr = stack;
+                        stack = x;
+                    }
+                }
+            }
+            hand->qtr = memo;
+        } else
+            for (x = hand->child; x != (vaseknode *) NULL; x = x->sibling) {
+                x->qtr = stack;
+                stack = x;
+            }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void bruteforce (panedge *e)
+#else
+static void bruteforce (e)
+panedge *e;
+#endif
+{
+    vaseknode *x, *y, *nx, *ny;
+    int dx, dy;
+
+    x = e->a[0];
+    y = e->a[1];
+
+    if (x == y) {
+        printf ("Tough luck Pal 1.\n");
+        exit (1);
+    }
+    dx = x->d;
+    dy = y->d;
+
+    while (dx > dy) {
+        x = x->parent;
+        dx--;
+    }
+    if (x == y) {
+        printf ("Tough luck Pal 2.\n");
+        exit (1);
+    }
+    while (dy > dx) {
+        y = y->parent;
+        dy--;
+    }
+    if (x == y) {
+        printf ("Tough luck Pal 3.\n");
+        exit (1);
+    }
+    nx = x->parent;
+    ny = y->parent;
+    while (nx != ny) {
+        x = nx;
+        y = ny;
+        nx = x->parent;
+        ny = y->parent;
+    }
+
+    e->a[0] = x;
+    e->a[1] = y;
+
+    e->roof = nx;
+    /* if (e->rc > 0.0) { e->next = nx->junk; nx->junk = e; } else { e->tag =
+     * XFALSE; attach (e); } */
+    e->next = nx->junk;
+    nx->junk = e;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void update (panedge *e)
+#else
+static void update (e)
+panedge *e;
+#endif
+{
+    vaseknode *x, *y, *v;
+
+    x = e->a[0]->anc;
+    y = e->a[1]->anc;
+    v = e->top;
+
+    if (x == v) {
+        if (y != v)
+            e->a[1] = y;
+    } else if (y == v)
+        e->a[0] = x;
+    else if (x != y) {
+        e->a[0] = x;
+        e->a[1] = y;
+    } else {
+        e->top = x;
+        if (x->d > e->roof->d)
+            e->roof = x;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dealwith (panedge *e, vaseknode **pa)
+#else
+static void dealwith (e, pa)
+panedge *e;
+vaseknode **pa;
+#endif
+{
+    if ((e->roof->d) - (e->a[0]->d) < XSHORT &&
+        (e->roof->d) - (e->a[1]->d) < XSHORT)
+        bruteforce (e);
+    else {
+        e->next = work;
+        work = e;
+        if (!e->top->n) {
+            e->top->ptr = *pa;
+            *pa = e->top;
+        }
+        (e->top->n)++;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void attach (panedge *e)
+#else
+static void attach (e)
+panedge *e;
+#endif
+{
+    triomino *cell;
+
+    TRIALLOC (cell);
+    cell->edge = e;
+    cell->end = e->a[1];
+    cell->next = e->a[0]->adj;
+    e->a[0]->adj = cell;
+
+    TRIALLOC (cell);
+    cell->edge = e;
+    cell->end = e->a[0];
+    cell->next = e->a[1]->adj;
+    e->a[1]->adj = cell;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void magicrc (void)
+#else
+static void magicrc ()
+#endif
+{
+    double a;
+    panedge **pee, *pe;
+
+    a = min2 ((pannodelist + XMAGICNODE)->edgelist);
+
+    for (pee = (pannodelist + XMAGICNODE)->edgelist;
+                (pe = *pee) != (panedge *) NULL; pee++)
+        pe->rc -= a;
+
+    (pannodelist + XMAGICNODE)->vptr->y += a;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double min2 (panedge **elist)
+#else
+static double min2 (elist)
+panedge **elist;
+#endif
+{
+    double minweight, minweight2, td;
+    panedge *e;
+
+    if (elist == (panedge **) NULL || elist[0] == (panedge *) NULL ||
+                                      elist[1] == (panedge *) NULL) {
+        fprintf (stderr, "Vertex has degree < two\n");
+        exit (1);
+    }
+    minweight = elist[0]->rc;
+    minweight2 = elist[1]->rc;
+    if (minweight > minweight2) {
+        SWAP (minweight, minweight2, td);
+    }
+    for (elist += 2; (e = *elist) != (panedge *) NULL; elist++) {
+        if (e->rc < minweight2) {
+            minweight2 = e->rc;
+            if (minweight > minweight2) {
+                SWAP (minweight, minweight2, td);
+            }
+        }
+    }
+    return minweight2;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double findbound (void)
+#else
+static double findbound ()
+#endif
+{
+    vaseknode *p, *q, *stack;
+    triomino *tri;
+    panedge **pee, *pe;
+    double tree_bound = 0.0;
+    double star_bound = 0.0;
+    double edge_bound = 0.0;
+
+    root->ptr = (vaseknode *) NULL;
+    root->n = 1;
+    root->b = 0;
+
+
+    for (p = stack = root; p; p = stack) {
+        if (p->n) {
+            p->n = 0;
+            q = p->child;
+            if (q)
+                for (; q; q = q->sibling) {
+                    q->ptr = stack;
+                    stack = q;
+                    q->n = 1;
+                    q->b = 0;
+                }
+            else {
+                stack = p->ptr;
+                (p->parent->b)++;
+                star_bound += p->y;
+            }
+            for (tri = p->adj; tri; tri = tri->next)
+                edge_bound += tri->edge->rc;
+        } else {
+            stack = p->ptr;
+            if (stack)
+                (p->parent->b) += p->b;
+            tree_bound -= (p->mult) * ((p->b) - 1);
+        }
+    }
+    star_bound *= 2.0;
+    edge_bound /= 2.0;
+
+    for (pee = ((pannodelist + XMAGICNODE)->edgelist);
+                 (pe = *pee) != (panedge *) NULL; pee++)
+        if (pe->rc < 0.0)
+            edge_bound += pe->rc;
+    star_bound += (pannodelist + XMAGICNODE)->vptr->y * 2;
+
+    return tree_bound + star_bound + edge_bound;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xblobsviolated (Xgraph *G, Xcplane **list)
+#else
+int Xblobsviolated (G, list)
+Xgraph *G;
+Xcplane **list;
+#endif
+{
+    int hit = 0;
+
+    blnode (G, list, root, &hit);
+    return hit;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double blnode (Xgraph *G, Xcplane **list, vaseknode *v, int *hit)
+#else
+static double blnode (G, list, v, hit)
+Xgraph *G;
+Xcplane **list;
+vaseknode *v;
+int *hit;
+#endif
+{
+    double w = 0.0;
+    double t;
+    panedge *e;
+    vaseknode *c;
+
+    if (!v->child)
+        return 0.0;
+    else {
+        for (e = v->junk; e; e = e->next)
+            w += (G->edgelist + (e - panedgelist))->x;
+        for (c = v->child; c; c = c->sibling)
+            w += blnode (G, list, c, hit);
+        t = v->b;
+        if (w > t - 1.0 + XCUTTOLERANCE) {
+            G->magicnum++;
+            labeler (G, v);
+            if (Xcutchecksout (G, G->magicnum)) {
+                Xloadcplane_cut (G, list, G->magicnum);
+                (*hit)++;
+            } else {
+                printf ("BAD BLOB");
+                fflush (stdout);
+            }
+        }
+        return w;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void labeler (Xgraph *G, vaseknode *p)
+#else
+static void labeler (G, p)
+Xgraph *G;
+vaseknode *p;
+#endif
+{
+    vaseknode *c;
+
+    if (!p->child)
+        (G->nodelist + (p - vpannodes))->magiclabel = G->magicnum;
+    else
+        for (c = p->child; c; c = c->sibling)
+            labeler (G, c);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xshrinksmallblobs (Xgraph *G, int rnum, int biggest)
+#else
+void Xshrinksmallblobs (G, rnum, biggest)
+Xgraph *G;
+int rnum;
+int biggest;
+#endif
+{
+    int shrunk = 0;
+
+    ssblob (G, root, rnum, biggest, &shrunk);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int ssblob (Xgraph *G, vaseknode *v, int rnum, int biggest, int *shrunk)
+#else
+static int ssblob (G, v, rnum, biggest, shrunk)
+Xgraph *G;
+vaseknode *v;
+int rnum;
+int biggest;
+int *shrunk;
+#endif
+{
+    int count = 0;
+    vaseknode *c;
+    static int s = 0;
+
+    if (v->b < 3)
+        return 0;
+    else {
+        for (c = v->child; c; c = c->sibling)
+            count += ssblob (G, c, rnum, biggest, shrunk);
+        if (count)
+            return count;
+        else {
+            if (v->tag) {
+                if (v->b <= biggest &&
+                    (!rnum || (++s) % 2)) {
+                    shrinkblob (G, v);
+                    (*shrunk)++;
+                }
+                return 1;
+            } else
+                return 0;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void shrinkblob (Xgraph *G, vaseknode *v)
+#else
+static void shrinkblob (G, v)
+Xgraph *G;
+vaseknode *v;
+#endif
+{
+    Xnode *first, *pn;
+
+    G->magicnum++;
+    labeler (G, v);
+    first = G->pseudonodelist->next;
+    while (first->magiclabel != G->magicnum)
+        first = first->next;
+    for (pn = first->next; pn; pn = pn->next)
+        if (pn->magiclabel == G->magicnum)
+            Xsimpleshrink (G, first, pn);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xtightblobs (Xgraph *G)
+#else
+void Xtightblobs (G)
+Xgraph *G;
+#endif
+{
+    int count = 0;
+
+    tblob (G, root, &count);
+    printf ("Number tight blobs: %d\n", count);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double tblob (Xgraph *G, vaseknode *v, int *count)
+#else
+static double tblob (G, v, count)
+Xgraph *G;
+vaseknode *v;
+int *count;
+#endif
+{
+    double w = 0.0;
+    double t;
+    panedge *e;
+    vaseknode *c;
+
+    if (v->b < 3)
+        return 0.0;
+    else {
+        for (e = v->junk; e; e = e->next)
+            w += (G->edgelist + (e - panedgelist))->x;
+        for (c = v->child; c; c = c->sibling)
+            w += tblob (G, c, count);
+        t = v->b;
+        if (w > t - 1.0 - XEPSILON) {
+            v->tag = 1;
+            (*count)++;
+        } else
+            v->tag = 0;
+        return w;
+    }
+}
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xblock.c b/contrib/blossom/concorde97/XSTUFF/Xblock.c
new file mode 100644
index 0000000000000000000000000000000000000000..690d51ce8bdcfcbae44421ee4dd0e1f589a40551
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xblock.c
@@ -0,0 +1,1825 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    void                                                                */
+/*        Xlocalshrink_a (),                                              */
+/*        Xlocalshrink_b (),                                              */
+/*        Xlocalshrink_c (),                                              */
+/*        Xadd_tooth ();                                                  */
+/*        Xmarktooth ();                                                  */
+/*        Xmarktoothend ();                                               */
+/*                                                                        */
+/*    int                                                                 */
+/*        Xlocalcombs (),                                                 */
+/*        Xglobalcombs (),                                                */
+/*        Xblockcombs (),                                                 */
+/*        XTmark_components (),                                           */
+/*        Xrepeat_1_shrink (),                                            */
+/*        Xbasiccliques (),                                               */
+/*        Xsearchbasiccliques (),                                         */
+/*        Xbasicclique ();                                                */
+/*                                                                        */
+/*    Xedge                                                               */
+/*        *Xcurrentedge (Xnode *n1, Xnode *n2);                           */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+#define BLOTOLERANCE .01
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    block_biconnect (Xgraph *G, Xnode *v, Xnode *u, int *lastnumber,
+          Xnode ***top_pointer, Xblock **tblock, Xcutnode **tcut,
+          int count_cut),
+    dfs_Tmark (Xnode *start, int t),
+    blockweight (Xgraph *G, Xblock *b),
+    blockone (Xgraph *G, Xblock *b),
+    buildcutnodes (Xgraph *G),
+    buildallneighbors (void),
+    buildneighbors (Xblock *b),
+    freeblocklist (void),
+    freecutnodelist (void),
+    handlesearch (Xgraph *G, Xcplane **cplanelist, double *x,
+          int *combcount, int *searchcount);
+
+static int
+    blockcombs_work (Xgraph *G, Xcplane **cplanelist, int pseudo,
+          double *x),
+    localcombs_work (Xgraph *G, Xcplane **cplanelist,
+          Xnode *startnode, double *x, int pseudo),
+    analyze_component (Xgraph *G, Xcplane **cplanelist, Xnode *n,
+          int first, Xnode **nodestack, double *x),
+    connectedhandles (Xgraph *G, Xcplane **cplanelist, double *x),
+    processhandle (Xgraph *G, Xcplane **cplanelist, double *x),
+    markblock (Xblock *b, Xcutnode *c, Xnodeptr **list),
+    component_basicclique (Xgraph *G, Xcplane **list, Xnode *n, int first,
+          Xnode **nodestack, double *x),
+    combslack (Xgraph *G, Xblock *handle, Xblock *fixtooth, double *slack,
+          Xnodeptrptr **teeth);
+
+static double
+    hoodweight (Xgraph *G, Xblock *b, Xnode *n);
+
+static Xnode
+    *globalshrink (Xgraph *G);
+
+#else
+
+static void
+    block_biconnect (),
+    dfs_Tmark (),
+    blockweight (),
+    blockone (),
+    buildcutnodes (),
+    buildallneighbors (),
+    buildneighbors (),
+    freeblocklist (),
+    freecutnodelist (),
+    handlesearch ();
+
+static int
+    blockcombs_work (),
+    localcombs_work (),
+    analyze_component (),
+    connectedhandles (),
+    processhandle (),
+    markblock (),
+    component_basicclique (),
+    combslack ();
+
+static double
+    hoodweight ();
+
+static Xnode
+    *globalshrink ();
+
+#endif
+
+#define FMPMAX 25
+#define SEARCHMAX 500           /* Was 5000 */
+static int nblocks, ncutnodes;
+static Xblock *blocklist;
+static Xcutnode *cutnodelist;
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xblockcombs (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xblockcombs (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    return blockcombs_work (G, list, 0, x);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xlocalcombs (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xlocalcombs (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    return localcombs_work (G, list, (Xnode *) NULL, x, 0);
+
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int localcombs_work (Xgraph *G, Xcplane **cplanelist,
+            Xnode *startnode, double *x, int pseudo)
+#else
+static int localcombs_work (G, cplanelist, startnode, x, pseudo)
+Xgraph *G;
+Xcplane **cplanelist;
+Xnode *startnode;
+double *x;
+int pseudo;
+#endif
+{
+    int hit, component;
+    Xnode *n;
+
+    /* printf ("localcombs...\n"); fflush (stdout); */
+
+    if (startnode)
+        component = startnode->Tmark;
+    else
+        component = 0;
+    if (x == (double *) NULL) {
+        printf ("need x vector for Xlocalcombs\n");
+        return 0;
+    }
+    if (!pseudo) {
+        Xloadx (G, x);
+        Xbuildpseudonodelist (G, 0);
+    }
+    Xlocalshrink_a (G, component);
+    Xlocalshrink_b (G, component);
+    Xlocalshrink_c (G, component);
+    if (startnode == (Xnode *) NULL)
+        hit = blockcombs_work (G, cplanelist, 1, x);
+    else {
+        n = G->pseudonodelist->next;
+        while (n && n->Tmark != component)
+            n = n->next;
+        if (!n) {
+            hit = 0;
+            printf ("WHOOOPS, did not find the component\n");
+        } else
+            hit = analyze_component (G, cplanelist, n, 0, (Xnode **) NULL, x);
+    }
+    if (!pseudo)
+        Xdestroypseudonodelist (G);
+
+    return hit;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xglobalcombs (Xgraph *G, Xcplane **cplanelist, double *x)
+#else
+int Xglobalcombs (G, cplanelist, x)
+Xgraph *G;
+Xcplane **cplanelist;
+double *x;
+#endif
+{
+    int count = 0;
+    Xnode *n, **nodestack;
+
+    Xloadx (G, x);
+    Xbuildpseudonodelist (G, 0);
+    nodestack = CC_SAFE_MALLOC (G->npseudonodes, Xnode *);
+    if (!nodestack) {
+        fprintf (stderr, "out of memory on globalcombs\n");
+        exit (1);
+    }
+
+    while ((n = globalshrink (G)) != (Xnode *) NULL) {
+        /* printf ("N: %d ", n - G->nodelist); fflush (stdout); */
+        XTmark_components (G);
+        count += analyze_component (G, cplanelist, n, 0, nodestack, x);
+        count += localcombs_work (G, cplanelist, n, x, 1);
+        /* printf ("\n"); fflush (stdout); */
+    }
+
+/*
+    printf ("%d globalcombs\n", count);
+*/
+
+    CC_FREE (nodestack, Xnode *);
+    Xdestroypseudonodelist (G);
+
+    return count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xlocalshrink_a (Xgraph *G, int component)
+#else
+void Xlocalshrink_a (G, component)
+Xgraph *G;
+int component;
+#endif
+{
+    int i;
+    Xedge *e;
+    Xnode *u, *v;
+
+    /* printf ("localshrink_a (%d)...\n", component); */
+    if (!component) {
+        for (e = G->edgelist, i = G->nedges; i; e++, i--)
+            if (e->stay && e->x == 1.0) {
+                u = e->cends[0];
+                v = e->cends[1];
+                Xrepeat_1_shrink (G, u, e);
+                Xrepeat_1_shrink (G, v, e);
+            }
+    } else {
+        for (e = G->edgelist, i = G->nedges; i; e++, i--)
+            if (e->stay && e->x == 1.0 &&
+                (e->cends[0]->Tmark == component ||
+                 e->cends[1]->Tmark == component)) {
+                Xrepeat_1_shrink (G, e->cends[0], e);
+                Xrepeat_1_shrink (G, e->cends[1], e);
+            }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xlocalshrink_b (Xgraph *G, int component)
+#else
+void Xlocalshrink_b (G, component)
+Xgraph *G;
+int component;
+#endif
+{
+    int i, hit;
+    Xedge *e, *f, *g;
+    Xedgeptr *ep;
+    Xnode *u, *v, *w;
+
+    for (e = G->edgelist, i = G->nedges; i; e++, i--) {
+        if (e->stay && e->x == 1.0 && (!component ||
+                                       (e->cends[0]->Tmark == component &&
+                                        e->cends[1]->Tmark == component))) {
+            u = e->cends[0];
+            v = e->cends[1];
+            hit = 0;
+            for (ep = u->cadj.head; ep && !hit; ep = ep->next) {
+                f = ep->this;
+                w = OTHERCURRENTEND (f, u);
+                if ((g = Xcurrentedge (v, w)) != (Xedge *) NULL)
+                    if (f->x + g->x > 1.0 - XEPSILON) {
+                        hit = 1;
+                        Xsimpleshrink (G, u, v);
+                    }
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xlocalshrink_c (Xgraph *G, int component)
+#else
+void Xlocalshrink_c (G, component)
+Xgraph *G;
+int component;
+#endif
+{
+    int i, hit;
+    Xedge *c, *d, *e, *f, *g, *h;
+    Xedgeptr *ep, *tp;
+    Xnode *u, *v, *w, *t;
+
+    for (e = G->edgelist, i = G->nedges; i; e++, i--)
+        if (e->stay && (!component || (e->cends[0]->Tmark == component
+                        && e->cends[1]->Tmark == component))) {
+            u = e->cends[0];
+            v = e->cends[1];
+            hit = 0;
+            for (ep = u->cadj.head; ep && !hit; ep = ep->next) {
+                f = ep->this;
+                if (f == e)
+                    continue;
+                w = OTHERCURRENTEND (f, u);
+                if (((g = Xcurrentedge (w, v)) != (Xedge *) NULL) &&
+                    e->x + f->x + g->x > 2.0 - XEPSILON) {
+                    for (tp = u->cadj.head; tp && !hit;
+                         tp = tp->next) {
+                        h = tp->this;
+                        if (h == e || h == f || h == g)
+                            continue;
+                        t = OTHERCURRENTEND (h, u);
+                        if (((c = Xcurrentedge (t, v)) != (Xedge *) NULL) &&
+                            ((d = Xcurrentedge (t, w)) != (Xedge *) NULL) &&
+                            h->x + c->x + d->x >
+                            1.0 - XEPSILON) {
+                            hit = 1;
+                            Xsimpleshrink (G, u, v);
+                            Xsimpleshrink (G, u, w);
+                        }
+                    }
+                }
+            }
+        }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xnode *globalshrink (Xgraph *G)
+#else
+static Xnode *globalshrink (G)
+Xgraph *G;
+#endif
+{
+    Xedge *e, *f, *g, *h;
+    Xedgeptr *ep, *ep2;
+    Xnode *u, *v, *w, *x;
+    int i;
+
+    XTmark_components (G);
+    for (e = G->edgelist, i = G->nedges; i; i--, e++)
+        if (e->stay && e->x == 1.0 && (u = e->cends[0])->Tmark
+            != (w = e->cends[1])->Tmark)
+            for (ep = u->cadj.head; ep; ep = ep->next) {
+                f = ep->this;
+                if (f == e)
+                    continue;
+                v = OTHERCURRENTEND (f, u);
+                for (ep2 = w->cadj.head; ep2; ep2 = ep2->next) {
+                    g = ep2->this;
+                    if (g == e)
+                        continue;
+                    x = OTHERCURRENTEND (g, w);
+                    if (x != v &&
+                        f->x + g->x > 1.0 - XEPSILON &&
+                        (h = Xcurrentedge (v, x)) != (Xedge *) NULL &&
+                        h->x == 1.0) {
+                        Xsimpleshrink (G, u, w);
+                        Xsimpleshrink (G, v, x);
+                        /* printf ("SHRINK\n"); fflush (stdout); */
+                        return u;
+                    }
+                }
+            }
+    return (Xnode *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int blockcombs_work (Xgraph *G, Xcplane **cplanelist, int pseudo,
+            double *x)
+#else
+static int blockcombs_work (G, cplanelist, pseudo, x)
+Xgraph *G;
+Xcplane **cplanelist;
+int pseudo;
+double *x;
+#endif
+{
+    Xnode *n, **nodestack, **top;
+    int lastnumber = 1, oldlast, combcount = 0;
+
+    /* printf ("blockcombs....\n"); fflush (stdout); */
+
+    if (x == (double *) NULL) {
+        printf ("Need x vector of Xblockcombs\n");
+        return 0;
+    }
+    if (!pseudo) {
+        Xloadx (G, x);
+        Xbuildpseudonodelist (G, 0);
+    }
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        n->active = 0;
+        n->mark = G->npseudonodes;
+    }
+
+    nodestack = CC_SAFE_MALLOC (G->npseudonodes, Xnode *);
+    if (!nodestack) {
+        fprintf (stderr, "out of memory in blockcombs\n");
+        exit (1);
+    }
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        if (!n->active) {
+            *nodestack = n;
+            top = nodestack + 1;
+            oldlast = lastnumber;
+            block_biconnect (G, n, (Xnode *) NULL, &lastnumber, &top,
+                             (Xblock **) NULL, (Xcutnode **) NULL, 0);
+            if (lastnumber - oldlast >= 3)
+                combcount += analyze_component (G, cplanelist,
+                                                n, oldlast, nodestack, x);
+        }
+        if (combcount >= FMPMAX)
+            break;
+    }
+    CC_FREE (nodestack, Xnode *);
+
+    if (!pseudo)
+        Xdestroypseudonodelist (G);
+/*
+    if (report)
+        printf ("%d blockcombs\n", combcount);
+*/
+
+    return combcount;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void block_biconnect (Xgraph *G, Xnode *v, Xnode *u, int *lastnumber,
+        Xnode ***top_pointer, Xblock **tblock, Xcutnode **tcut, int count_cut)
+#else
+static void block_biconnect (G, v, u, lastnumber, top_pointer, tblock, tcut,
+        count_cut)
+Xgraph *G;
+Xnode *v, *u;
+int *lastnumber;
+Xnode ***top_pointer;
+Xblock **tblock;
+Xcutnode **tcut;
+int count_cut;
+#endif
+{
+    Xedge *e;
+    Xedgeptr *ep;
+    Xnode *w, **top = *top_pointer;
+    Xnodeptr *np;
+
+    v->mark = v->active = (*lastnumber)++;
+    for (ep = v->cadj.head; ep; ep = ep->next) {
+        e = ep->this;
+        if (e->x > 1.0 - XEPSILON)
+            continue;
+        w = OTHERCURRENTEND (e, v);
+        if (!w->active) {
+            *top = w;
+            top++;
+            block_biconnect (G, w, v, lastnumber, &top, tblock, tcut,
+                             count_cut);
+            if (w->mark < v->mark)
+                v->mark = w->mark;
+            if (w->mark >= v->active) {
+                if (count_cut)
+                    nblocks++;
+                if (count_cut && v->magiclabel != G->magicnum) {
+                    if (v->magiclabel == G->magicnum - 1)
+                        v->magiclabel--;
+                    else {
+                        ncutnodes++;
+                        v->magiclabel = G->magicnum;
+                        if (tcut != (Xcutnode **) NULL) {
+                            (*tcut)->name = v;
+                            (*tcut)++;
+                        }
+                    }
+                }
+                if (tblock) {
+                    np = Xnodeptralloc ();
+                    np->this = v;
+                    np->next = (Xnodeptr *) NULL;
+                    (*tblock)->members = np;
+                }
+                while (*(top - 1) != v) {
+                    if (tblock) {
+                        np = Xnodeptralloc ();
+                        np->this = *(top - 1);
+                        np->next = (*tblock)->members;
+                        (*tblock)->members = np;
+                    }
+                    top--;
+                }
+                if (tblock)
+                    (*tblock)++;
+            }
+        } else if (w->active < v->mark && w != u) {
+            if (w->mark < v->mark)
+                v->mark = w->mark;
+        }
+    }
+    *top_pointer = top;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int XTmark_components (Xgraph *G)
+#else
+int XTmark_components (G)
+Xgraph *G;
+#endif
+{
+    int ccount = 1;
+    Xnode *n;
+
+    for (n = G->pseudonodelist->next; n; n = n->next)
+        n->Tmark = 0;
+
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        if (!n->Tmark) {
+            dfs_Tmark (n, ccount);
+            ccount++;
+        }
+    }
+    /* printf ("NUMBER OF COMPONENTS: %d\n", ccount - 1); */
+    return ccount;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dfs_Tmark (Xnode *start, int t)
+#else
+static void dfs_Tmark (start, t)
+Xnode *start;
+int t;
+#endif
+{
+    Xedgeptr *ep;
+    Xnode *n, *v;
+    Xnodeptr *next, *queue = (Xnodeptr *) NULL;
+
+    start->Tmark = t;
+    Xadd_nodeptr (&queue, start);
+
+    while (queue) {
+        n = queue->this;
+        next = queue->next;
+        Xnodeptrfree (queue);
+        queue = next;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            if (ep->this->x > 1.0 - XEPSILON)
+                continue;
+            if (!(v = OTHERCURRENTEND (ep->this, n))->Tmark) {
+                v->Tmark = t;
+                Xadd_nodeptr (&queue, v);
+            }
+        }
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int analyze_component (Xgraph *G, Xcplane **cplanelist, Xnode *n,
+            int first, Xnode **nodestack, double *x)
+#else
+static int analyze_component (G, cplanelist, n, first, nodestack, x)
+Xgraph *G;
+Xcplane **cplanelist;
+Xnode *n;
+int first;
+Xnode **nodestack;
+double *x;
+#endif
+{
+    int i, fake, combcount = 0, newstack = 0;
+    Xnode *v, **top;
+    Xblock *topblock, *b;
+    Xcutnode *topcutnode;
+
+    /*
+    printf ("analyze_component (blocks: %d  cuts: %d)...\n",
+             nblocks, ncutnodes);
+    fflush (stdout);
+    */
+
+    if (!nodestack) {
+        nodestack = CC_SAFE_MALLOC (G->npseudonodes, Xnode *);
+        if (!nodestack) {
+            fprintf (stderr, "out of memory in analyze_component\n");
+            exit (1);
+        }
+        newstack = 1;
+    }
+    *nodestack = n;
+    top = nodestack + 1;
+    if (first) {
+        for (v = G->pseudonodelist->next; v; v = v->next)
+            if (v->active >= first)
+                v->active = 0;
+    } else {
+        for (v = G->pseudonodelist->next; v; v = v->next) {
+            v->active = 0;
+            v->mark = G->npseudonodes;
+        }
+        first = 1;
+    }
+
+    nblocks = ncutnodes = 0;
+    G->magicnum += 2;
+    n->magiclabel = G->magicnum - 1;
+    fake = first;
+    block_biconnect (G, n, (Xnode *) NULL, &fake, &top, (Xblock **) NULL,
+                        (Xcutnode **) NULL, 1);
+
+    if (nblocks > 0) {
+        blocklist = CC_SAFE_MALLOC (nblocks, Xblock);
+        if (!blocklist) {
+            fprintf (stderr, "out of memory in analyze_component\n");
+            exit (1);
+        }
+    } else
+        blocklist = (Xblock *) NULL;
+
+    if (ncutnodes) {
+        cutnodelist = CC_SAFE_MALLOC (ncutnodes, Xcutnode);
+        if (!cutnodelist) {
+            fprintf (stderr, "out of memory in analyze_component\n");
+            exit (1);
+        }
+    } else
+        cutnodelist = (Xcutnode *) NULL;
+
+    for (i = 0; i < nblocks; i++) {
+        blocklist[i].members = (Xnodeptr *) NULL;
+        blocklist[i].neighbors = (Xblockptr *) NULL;
+        blocklist[i].one = (Xedgeptr *) NULL;
+        blocklist[i].cutnodes = (Xcutnodeptr *) NULL;
+    }
+
+    for (i = 0; i < ncutnodes; i++)
+        cutnodelist[i].blocks = (Xblockptr *) NULL;
+
+    topblock = blocklist;
+    topcutnode = cutnodelist;
+
+    for (v = G->pseudonodelist->next; v; v = v->next)
+        if (v->active >= first)
+            v->active = 0;
+
+    *nodestack = n;
+    top = nodestack + 1;
+    nblocks = ncutnodes = 0;
+    G->magicnum += 2;
+    n->magiclabel = G->magicnum - 1;
+    fake = first;
+    block_biconnect (G, n, (Xnode *) NULL, &fake, &top, &topblock,
+                           &topcutnode, 1);
+    for (i = nblocks, b = blocklist; i; i--, b++) {
+        blockweight (G, b);
+        blockone (G, b);
+    }
+    buildcutnodes (G);
+    buildallneighbors ();
+    combcount += connectedhandles (G, cplanelist, x);
+
+    /*
+    printf ("ALL CUTNODES: ");
+    fflush (stdout);
+    for (i = ncutnodes, topcutnode = cutnodelist; i; i--, topcutnode++)
+        printf ("%d ", topcutnode->name - G->nodelist);
+    printf ("\n");
+    printf ("BLOCKS:\n");
+    for (i = 0, topblock = blocklist; i < nblocks; i++, topblock++) {
+        printf ("%d: ", i);
+        fflush (stdout);
+        for (np = topblock->members; np; np = np->next)
+            printf (" %d", np->this - nodelist);
+        printf ("\nWeight: %lf\n", topblock->weight);
+        printf ("ONE: ");
+        fflush (stdout);
+        for (ep = topblock->one; ep; ep = ep->next) {
+            printf ("(%d, %d) ", ep->this->cends[0] - G->nodelist,
+                                 ep->this->cends[1] - G->nodelist);
+            fflush (stdout);
+        }
+        printf ("\n");
+        printf ("CUTNODES: ");
+        fflush (stdout);
+        for (cp = topblock->cutnodes; cp; cp = cp->next)
+            printf (" %d", cp->this->name - G->nodelist);
+        printf ("\n");
+    }
+    printf ("done\n");
+    fflush (stdout);
+    */
+
+    freeblocklist ();
+    freecutnodelist ();
+    if (newstack)
+        CC_FREE (nodestack, Xnode *);
+    return combcount;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void blockweight (Xgraph *G, Xblock *b)
+#else
+static void blockweight (G, b)
+Xgraph *G;
+Xblock *b;
+#endif
+{
+    int count = 0;
+    double inside = 0.0;
+    Xnode *n;
+    Xedge *e;
+    Xnodeptr *np;
+    Xedgeptr *ep;
+
+    G->magicnum++;
+    for (np = b->members; np; np = np->next) {
+        np->this->magiclabel = G->magicnum;
+        count++;
+    }
+
+    for (np = b->members; np; np = np->next) {
+        n = np->this;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (OTHERCURRENTEND (e, n)->magiclabel == G->magicnum)
+                inside += e->x;
+        }
+    }
+    inside /= 2.0;
+    b->x = inside;
+    b->weight = inside + 2.0 - count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void blockone (Xgraph *G, Xblock *b)
+#else
+static void blockone (G, b)
+Xgraph *G;
+Xblock *b;
+#endif
+{
+    Xnode *n;
+    Xedge *e;
+    Xnodeptr *np;
+    Xedgeptr *ep, *tp;
+
+    G->magicnum++;
+    for (np = b->members; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    for (np = b->members; np; np = np->next) {
+        n = np->this;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x == 1.0 && OTHERCURRENTEND (e, n)->magiclabel
+                != G->magicnum) {
+                tp = Xedgeptralloc ();
+                tp->this = e;
+                tp->next = b->one;
+                b->one = tp;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildcutnodes (Xgraph *G)
+#else
+static void buildcutnodes (G)
+Xgraph *G;
+#endif
+{
+    Xcutnode *c;
+    Xnode *nc;
+    Xnodeptr *np;
+    Xcutnodeptr *cp;
+    Xblock *b;
+    Xblockptr *bp;
+    int i, j, hit;
+
+    for (i = ncutnodes, c = cutnodelist; i; i--, c++) {
+        nc = c->name;
+        for (j = nblocks, b = blocklist; j; j--, b++) {
+            hit = 0;
+            for (np = b->members; np && !hit; np = np->next)
+                if (np->this == nc) {
+                    cp = Xcutnodeptralloc ();
+                    cp->this = c;
+                    cp->next = b->cutnodes;
+                    b->cutnodes = cp;
+
+                    bp = Xblockptralloc ();
+                    bp->this = b;
+                    bp->next = c->blocks;
+                    c->blocks = bp;
+                    bp->hood_weight = hoodweight (G, b, nc);
+                    hit++;
+                }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildallneighbors (void)
+#else
+static void buildallneighbors ()
+#endif
+{
+    int i;
+    Xblock *b;
+
+    for (i = nblocks, b = blocklist; i; i--, b++)
+        buildneighbors (b);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildneighbors (Xblock *b)
+#else
+static void buildneighbors (b)
+Xblock *b;
+#endif
+{
+    int i;
+    Xblock *d;
+    Xblockptr *bp;
+    Xcutnodeptr *cp;
+
+    for (i = nblocks, d = blocklist; i; i--, d++)
+        d->mark = 0;
+
+    for (cp = b->cutnodes; cp; cp = cp->next)
+        for (bp = cp->this->blocks; bp; bp = bp->next)
+            if (bp->this != b)
+                bp->this->mark = 1;
+
+    for (i = nblocks, d = blocklist; i; i--, d++)
+        if (d->mark) {
+            bp = Xblockptralloc ();
+            bp->this = d;
+            bp->next = b->neighbors;
+            b->neighbors = bp;
+        }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double hoodweight (Xgraph *G, Xblock *b, Xnode *n)
+#else
+static double hoodweight (G, b, n)
+Xgraph *G;
+Xblock *b;
+Xnode *n;
+#endif
+{
+    Xnode *m;
+    Xnodeptr *np;
+    Xedgeptr *ep, *tp;
+    Xedge *e;
+    double inside = 0.0;
+    int count = 1;
+
+    G->magicnum++;
+    for (np = b->members; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (ep = n->cadj.head; ep; ep = ep->next)
+        OTHERCURRENTEND (ep->this, n)->magiclabel++;
+    n->magiclabel++;
+    G->magicnum++;
+    for (ep = n->cadj.head; ep; ep = ep->next) {
+        m = OTHERCURRENTEND (ep->this, n);
+        if (m->magiclabel == G->magicnum) {
+            count++;
+            inside += ep->this->x;
+            for (tp = m->cadj.head; tp; tp = tp->next) {
+                e = tp->this;
+                if (OTHERCURRENTEND (e, m)->magiclabel == G->magicnum)
+                    inside += e->x;
+            }
+        }
+    }
+    inside /= 2.0;
+
+    return inside + 2.0 - count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void freeblocklist (void)
+#else
+static void freeblocklist ()
+#endif
+{
+    Xblock *b;
+    Xnodeptr *np, *next;
+    Xblockptr *bp, *bext;
+    Xcutnodeptr *cp, *cext;
+    Xedgeptr *ep, *eext;
+    int i;
+
+    for (b = blocklist, i = nblocks; i; i--, b++) {
+        for (np = b->members; np; np = next) {
+            next = np->next;
+            Xnodeptrfree (np);
+        }
+        for (bp = b->neighbors; bp; bp = bext) {
+            bext = bp->next;
+            Xblockptrfree (bp);
+        }
+        for (cp = b->cutnodes; cp; cp = cext) {
+            cext = cp->next;
+            Xcutnodeptrfree (cp);
+        }
+        for (ep = b->one; ep; ep = eext) {
+            eext = ep->next;
+            Xedgeptrfree (ep);
+        }
+    }
+    if (blocklist) {
+        CC_FREE (blocklist, Xblock);
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void freecutnodelist (void)
+#else
+static void freecutnodelist ()
+#endif
+{
+    Xcutnode *c;
+    Xblockptr *bp, *next;
+    int i;
+
+    if (ncutnodes) {
+        for (c = cutnodelist, i = ncutnodes; i; i--, c++)
+            for (bp = c->blocks; bp; bp = next) {
+                next = bp->next;
+                Xblockptrfree (bp);
+            }
+        CC_FREE (cutnodelist, Xcutnode);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int connectedhandles (Xgraph *G, Xcplane **cplanelist, double *x)
+#else
+static int connectedhandles (G, cplanelist, x)
+Xgraph *G;
+Xcplane **cplanelist;
+double *x;
+#endif
+{
+    int i, combcount = 0, searchcount = 0;
+    Xblock *b;
+
+    for (i = nblocks, b = blocklist; i; i--, b++)
+        b->mark = 0;
+
+    for (i = nblocks, b = blocklist; i; i--, b++) {
+        b->mark = 1;
+        if (processhandle (G, cplanelist, x))
+            combcount++;
+        if (combcount >= FMPMAX)
+            return combcount;
+
+        b->mark = 0;
+    }
+
+    handlesearch (G, cplanelist, x, &combcount, &searchcount);
+
+    /* printf ("(%d)  ", searchcount); fflush (stdout); */
+
+    return combcount;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void handlesearch (Xgraph *G, Xcplane **cplanelist, double *x,
+             int *combcount, int *searchcount)
+#else
+static void handlesearch (G, cplanelist, x, combcount, searchcount)
+Xgraph *G;
+Xcplane **cplanelist;
+double *x;
+int *combcount, *searchcount;
+#endif
+{
+    int i, k;
+    Xblock *b, *winner = (Xblock *) NULL, *runnerup = (Xblock *) NULL;
+    Xblockptr *bp;
+
+    for (i = nblocks, b = blocklist; i && !winner; i--, b++) {
+        if (!b->mark) {
+            for (k = 0, bp = b->neighbors; bp && k < 2; bp = bp->next)
+                if (!bp->this->mark)
+                    k++;
+            if (k == 1) {
+                winner = b;
+                for (bp = b->neighbors; bp; bp = bp->next)
+                    if (!bp->this->mark) {
+                        runnerup = bp->this;
+                        break;
+                    }
+                winner->mark = 1;
+                runnerup->mark = 1;
+            }
+        }
+    }
+    if (!winner)
+        return;
+    (*searchcount)++;
+    if (processhandle (G, cplanelist, x))
+        (*combcount)++;
+    if (*combcount >= FMPMAX || *searchcount >= SEARCHMAX)
+        return;
+
+    winner->mark = -1;
+    runnerup->mark = 0;
+    handlesearch (G, cplanelist, x, combcount, searchcount);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int processhandle (Xgraph *G, Xcplane **cplanelist, double *x)
+#else
+static int processhandle (G, cplanelist, x)
+Xgraph *G;
+Xcplane **cplanelist;
+double *x;
+#endif
+{
+    int i, nteeth = 0, handlecount = 0, midtake = 0, test;
+    double total = 0.0, midval = 2.0, mid = 0, handleweight = 0.0, max;
+    Xcutnode *c;
+    Xnode *n;
+    Xnodeptr *np, *nnp;
+    Xcutnodeptr *cp;
+    Xblock *b, *d, *bestblock = (Xblock *) NULL;
+    Xblockptr *bp;
+    Xedgeptr *ep;
+    Xedge *e;
+    int gotmid, besttype = 0, hit;
+    Xnodeptr *handle, *tooth;
+    Xnodeptrptr *teeth, *ntp;
+    int countcheck = 0;
+
+    /*
+    printf ("PH: ");
+    for (i = nblocks, b = blocklist; i; i--, b++)
+        if (b->mark == 1)
+            printf ("%d ", b - blocklist);
+    printf ("\n");
+    */
+    G->magicnum++;
+    for (n = G->pseudonodelist->next; n; n = n->next)
+        n->stacklabel = 0;
+    for (i = ncutnodes, c = cutnodelist; i; i--, c++)
+        c->mark = 0;
+    for (i = nblocks, b = blocklist; i; i--, b++) {
+        if (b->mark == 1) {
+            for (np = b->members; np; np = np->next)
+                np->this->stacklabel = 1;
+            for (cp = b->cutnodes; cp; cp = cp->next)
+                cp->this->mark = 1;
+        }
+    }
+    for (i = nblocks, b = blocklist; i; i--, b++) {
+        if (b->mark == 1) {
+            for (ep = b->one; ep; ep = ep->next) {
+                e = ep->this;
+                if ((e->cends[0]->stacklabel !=
+                     e->cends[1]->stacklabel) &&
+                    (e->cends[0]->magiclabel != G->magicnum ||
+                     e->cends[1]->magiclabel != G->magicnum)) {
+                    e->cends[0]->magiclabel = G->magicnum;
+                    e->cends[1]->magiclabel = G->magicnum;
+                    nteeth++;
+                    total += 1.0;
+                    midtake = 1;
+                    mid = 1.0;
+                    midval = 0.5;
+                }
+            }
+        }
+    }
+
+    for (i = G->nedges, e = G->edgelist; i; i--, e++) {
+        if (e->stay && e->cends[0]->stacklabel &&
+            e->cends[1]->stacklabel)
+            handleweight += e->x;
+    }
+
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        if (n->stacklabel)
+            handlecount++;
+    }
+
+    for (i = ncutnodes, c = cutnodelist; i; i--, c++) {
+        if (c->mark && c->name->magiclabel != G->magicnum) {
+            hit = 0;
+            max = 0.0;
+            for (bp = c->blocks; bp; bp = bp->next) {
+                d = bp->this;
+                if (d->mark != 1) {
+                    hit = 1;
+                    if (d->weight > max)
+                        max = d->weight;
+                    if (bp->hood_weight > max)
+                        max = bp->hood_weight;
+                }
+            }
+            if (max >= 0.5) {
+                nteeth++;
+                total += max;
+                if (midval > max - 0.5) {
+                    midval = max - 0.5;
+                    mid = max;
+                    midtake = 1;
+                }
+            } else if (hit && midval > 0.5 - max) {
+                midval = 0.5 - max;
+                mid = max;
+                midtake = 0;
+            }
+        }
+    }
+    if (nteeth < 2) {
+        return 0;
+    }
+    if (nteeth % 2 == 0) {
+        gotmid = 0;
+        if (!midtake) {
+            total += mid;
+            nteeth++;
+        } else {
+            total -= mid;
+            nteeth--;
+        }
+    } else
+        gotmid = 1;
+
+
+    total += handleweight + 2.0 - handlecount;
+    if (nteeth < 3 || total <= 1.5 + (0.5 * nteeth) + BLOTOLERANCE)
+        return 0;
+
+    G->magicnum++;
+    for (i = nblocks, b = blocklist; i; i--, b++)
+        if (b->mark == 1)
+            for (np = b->members; np; np = np->next)
+                for (nnp = np->this->base.head; nnp;
+                     nnp = nnp->next)
+                    nnp->this->magiclabel = G->magicnum;
+
+    handle = (Xnodeptr *) NULL;
+    for (i = G->nnodes, n = G->nodelist; i; i--, n++)
+        if (n->magiclabel == G->magicnum) {
+            np = Xnodeptralloc ();
+            np->this = n;
+            np->next = handle;
+            handle = np;
+        }
+    nteeth = 0;
+    teeth = (Xnodeptrptr *) NULL;
+
+    G->magicnum++;
+    for (i = nblocks, b = blocklist; i; i--, b++)
+        if (b->mark == 1)
+            for (ep = b->one; ep; ep = ep->next) {
+                e = ep->this;
+                if ((e->cends[0]->stacklabel !=
+                     e->cends[1]->stacklabel) &&
+                    (e->cends[0]->magiclabel != G->magicnum ||
+                     e->cends[1]->magiclabel != G->magicnum)) {
+                    e->cends[0]->magiclabel = G->magicnum;
+                    e->cends[1]->magiclabel = G->magicnum;
+                    if (!gotmid && mid == 1.0)
+                        gotmid = 1;
+                    else {
+                        nteeth++;
+                        tooth = (Xnodeptr *) NULL;
+                        Xmarktooth (ep->this, &tooth);
+                        Xadd_nodeptrptr (&teeth, tooth);
+                    }
+                }
+            }
+
+    for (i = ncutnodes, c = cutnodelist; i; i--, c++)
+        if (c->mark && c->name->magiclabel != G->magicnum) {
+            max = 0.0;
+            hit = 0;
+            for (bp = c->blocks; bp; bp = bp->next) {
+                d = bp->this;
+                if (d->mark != 1) {
+                    hit = 1;
+                    if (d->weight > max) {
+                        bestblock = d;
+                        besttype = 0;
+                        max = d->weight;
+                    }
+                    if (bp->hood_weight > max) {
+                        bestblock = d;
+                        besttype = 1;
+                        max = bp->hood_weight;
+                    }
+                }
+            }
+            if (max >= 0.5) {
+                if (!gotmid && max == mid)
+                    gotmid = 1;
+                else {
+                    nteeth++;
+                    tooth = (Xnodeptr *) NULL;
+                    if (besttype)
+                        markblock (bestblock, c,
+                                        &tooth);
+                    else
+                        markblock (bestblock, (Xcutnode *) NULL,
+                                        &tooth);
+                    Xadd_nodeptrptr (&teeth, tooth);
+                }
+            } else if (hit && !gotmid && max == mid) {
+                gotmid = 1;
+                nteeth++;
+                tooth = (Xnodeptr *) NULL;
+                if (besttype)
+                    markblock (bestblock, c,
+                                    &tooth);
+                else
+                    markblock (bestblock, (Xcutnode *) NULL,
+                                    &tooth);
+                Xadd_nodeptrptr (&teeth, tooth);
+            }
+        }
+    Xcleancomb (G, &handle, &teeth, &nteeth, x);
+    if (!Xtemp_combfluff (G, &handle, &teeth))
+        return 0;
+    test = Xtemp_combcheck (G, handle, teeth) &&
+           Xloadcplane (cplanelist, handle, (Xnodeptrptr *) NULL, teeth,
+                        countcheck);
+    if (!test) {
+        Xnodeptr_list_free (handle);
+        for (ntp = teeth; ntp; ntp = ntp->next)
+            Xnodeptr_list_free (ntp->this);
+        Xnodeptrptr_list_free (teeth);
+    }
+    return test;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int markblock (Xblock *b, Xcutnode *c, Xnodeptr **list)
+#else
+static int markblock (b, c, list)
+Xblock *b;
+Xcutnode *c;
+Xnodeptr **list;
+#endif
+{
+    Xnode *n, *m;
+    Xnodeptr *np, *nnp;
+    Xedgeptr *ep;
+    int count = 0, hit;
+
+    *list = (Xnodeptr *) NULL;
+    if (c == (Xcutnode *) NULL)
+        for (np = b->members; np; np = np->next) {
+            n = np->this;
+            for (nnp = n->base.head; nnp; nnp = nnp->next) {
+                Xadd_tooth (nnp->this, list);
+                count++;
+            }
+        }
+    else
+        for (np = b->members; np; np = np->next) {
+            n = np->this;
+            if (n == c->name)
+                hit = 1;
+            else
+                hit = 0;
+            for (ep = c->name->cadj.head; ep && !hit; ep = ep->next) {
+                m = OTHERCURRENTEND (ep->this, c->name);
+                if (m == n)
+                    hit = 1;
+            }
+            if (hit) {
+                for (nnp = n->base.head; nnp; nnp = nnp->next) {
+                    Xadd_tooth (nnp->this, list);
+                    count++;
+                }
+            }
+        }
+    return count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xedge *Xcurrentedge (Xnode *n1, Xnode *n2)
+#else
+Xedge *Xcurrentedge (n1, n2)
+Xnode *n1, *n2;
+#endif
+{
+    Xedgeptr *ep;
+
+    for (ep = n1->cadj.head; ep; ep = ep->next)
+        if (OTHERCURRENTEND (ep->this, n1) == n2)
+            return ep->this;
+
+    return (Xedge *) NULL;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xadd_tooth (Xnode *t, Xnodeptr **list)
+#else
+void Xadd_tooth (t, list)
+Xnode *t;
+Xnodeptr **list;
+#endif
+{
+    Xnodeptr *np;
+
+    np = Xnodeptralloc ();
+    np->this = t;
+    np->next = *list;
+    *list = np;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xmarktooth (Xedge *e, Xnodeptr **list)
+#else
+int Xmarktooth (e, list)
+Xedge *e;
+Xnodeptr **list;
+#endif
+{
+    int count;
+
+    *list = (Xnodeptr *) NULL;
+    count = Xmarktoothend (e->cends[0], list) +
+        Xmarktoothend (e->cends[1], list);
+
+    return count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xmarktoothend (Xnode *n, Xnodeptr **list)
+#else
+int Xmarktoothend (n, list)
+Xnode *n;
+Xnodeptr **list;
+#endif
+{
+    Xnodeptr *np;
+    int count = 0;
+
+    for (np = n->base.head; np; np = np->next) {
+        count++;
+        Xadd_tooth (np->this, list);
+    }
+
+    return count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xrepeat_1_shrink (Xgraph *G, Xnode *n, Xedge *e)
+#else
+int Xrepeat_1_shrink (G, n, e)
+Xgraph *G;
+Xnode *n;
+Xedge *e;
+#endif
+{
+    int hit, count = 0;
+    Xedgeptr *ep;
+    Xedge *f;
+
+    do {
+        for (ep = n->cadj.head, hit = 0; ep && !hit; ep = ep->next) {
+            f = ep->this;
+            if (f->x == 1.0 && f != e) {
+                Xsimpleshrink (G, n, OTHERCURRENTEND (f, n));
+                hit = 1;
+                count++;
+            }
+        }
+    } while (hit);
+
+    return count;
+}
+
+
+
+/*********************** New Clique Tree Stuff *********************/
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xbasiccliques (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xbasiccliques (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    return Xsearchbasiccliques (G, list, 0, x);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xsearchbasiccliques (Xgraph *G, Xcplane **list, int pseudo, double *x)
+#else
+int Xsearchbasiccliques (G, list, pseudo, x)
+Xgraph *G;
+Xcplane **list;
+int pseudo;
+double *x;
+#endif
+{
+    int lastnumber = 1, oldlast, cliquecount = 0;
+    Xnode *n, **nodestack, **top;
+
+/*
+    printf ("searchbasiccliques ...\n");
+    fflush (stdout);
+*/
+
+    if (x == (double *) NULL) {
+        printf ("need x vector of Xsearchbasiccliques\n");
+        return 0;
+    }
+    if (!pseudo) {
+        Xloadx (G, x);
+        Xbuildpseudonodelist (G, 0);
+    }
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        n->active = 0;
+        n->mark = G->npseudonodes;
+    }
+
+    nodestack = CC_SAFE_MALLOC (G->npseudonodes, Xnode *);
+    if (!nodestack) {
+        fprintf (stderr, "out of memory in Xsearchbasiccliques\n");
+        exit (1);
+    }
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        if (!n->active) {
+            *nodestack = n;
+            top = nodestack + 1;
+            oldlast = lastnumber;
+            block_biconnect (G, n, (Xnode *) NULL, &lastnumber, &top,
+                                   (Xblock **) NULL, (Xcutnode **) NULL, 0);
+            if (lastnumber - oldlast >= 3)
+                cliquecount += component_basicclique (G, list,
+                                                  n, oldlast, nodestack, x);
+        }
+        if (cliquecount >= FMPMAX)
+            break;
+    }
+    CC_FREE (nodestack, Xnode *);
+
+    if (!pseudo)
+        Xdestroypseudonodelist (G);
+
+    /* printf ("%d potential new cliquetrees\n", cliquecount); */
+
+    return cliquecount;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int component_basicclique (Xgraph *G, Xcplane **list, Xnode *n,
+            int first, Xnode **nodestack, double *x)
+#else
+static int component_basicclique (G, list, n, first, nodestack, x)
+Xgraph *G;
+Xcplane **list;
+Xnode *n;
+int first;
+Xnode **nodestack;
+double *x;
+#endif
+{
+    int i, fake, cliquecount = 0, newstack = 0;
+    Xnode *v, **top;
+    Xblock *topblock, *b;
+    Xcutnode *topcutnode;
+
+    if (!nodestack) {
+        nodestack = CC_SAFE_MALLOC (G->npseudonodes, Xnode *);
+        if (!nodestack) {
+            fprintf (stderr, "out of memory in component_basicclique\n");
+            exit (1);
+        }
+        newstack = 1;
+    }
+    *nodestack = n;
+    top = nodestack + 1;
+    if (first) {
+        for (v = G->pseudonodelist->next; v; v = v->next)
+            if (v->active >= first)
+                v->active = 0;
+    } else {
+        for (v = G->pseudonodelist->next; v; v = v->next) {
+            v->active = 0;
+            v->mark = G->npseudonodes;
+        }
+        first = 1;
+    }
+
+    nblocks = ncutnodes = 0;
+    G->magicnum += 2;
+    n->magiclabel = G->magicnum - 1;
+    fake = first;
+    block_biconnect (G, n, (Xnode *) NULL, &fake, &top, (Xblock **) NULL,
+                           (Xcutnode **) NULL, 1);
+
+    if (nblocks > 0) {
+        blocklist = CC_SAFE_MALLOC (nblocks, Xblock);
+        if (!blocklist) {
+            fprintf (stderr, "out of memory in component_basicclique\n");
+            exit (1);
+        }
+    } else
+        blocklist = (Xblock *) NULL;
+
+    if (ncutnodes > 0) {
+        cutnodelist = CC_SAFE_MALLOC (ncutnodes, Xcutnode);
+        if (!cutnodelist) {
+            fprintf (stderr, "out of memory in component_basicclique\n");
+            exit (1);
+        }
+    } else
+        cutnodelist = (Xcutnode *) NULL;
+
+    for (i = 0; i < nblocks; i++) {
+        blocklist[i].members = (Xnodeptr *) NULL;
+        blocklist[i].neighbors = (Xblockptr *) NULL;
+        blocklist[i].one = (Xedgeptr *) NULL;
+        blocklist[i].cutnodes = (Xcutnodeptr *) NULL;
+    }
+
+    for (i = 0; i < ncutnodes; i++)
+        cutnodelist[i].blocks = (Xblockptr *) NULL;
+
+    topblock = blocklist;
+    topcutnode = cutnodelist;
+
+    for (v = G->pseudonodelist->next; v; v = v->next)
+        if (v->active >= first)
+            v->active = 0;
+
+    *nodestack = n;
+    top = nodestack + 1;
+    nblocks = ncutnodes = 0;
+    G->magicnum += 2;
+    n->magiclabel = G->magicnum - 1;
+    fake = first;
+    block_biconnect (G, n, (Xnode *) NULL, &fake, &top, &topblock,
+                     &topcutnode, 1);
+    for (i = nblocks, b = blocklist; i; i--, b++) {
+        blockweight (G, b);
+        blockone (G, b);
+    }
+    buildcutnodes (G);
+    buildallneighbors ();
+
+    for (i = nblocks, b = blocklist; i; i--, b++)
+        cliquecount += Xbasicclique (G, list, x, b);
+
+
+    freeblocklist ();
+    freecutnodelist ();
+    if (newstack)
+        CC_FREE (nodestack, Xnode *);
+    return cliquecount;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xbasicclique (Xgraph *G, Xcplane **list, double *x, Xblock *bigtooth)
+#else
+int Xbasicclique (G, list, x, bigtooth)
+Xgraph *G;
+Xcplane **list;
+double *x;
+Xblock *bigtooth;
+#endif
+{
+    Xblockptr *bp, *bnext, *combs;
+    Xblock *b, *minb = (Xblock *) NULL;
+    Xcutnode *c;
+    Xcutnodeptr *cp;
+    double min, t, slack, toothslack;
+    int count, goodcount, nhandles;
+    Xnodeptr *np, *tooth, *handle;
+    Xnodeptrptr *teeth, *handles;
+    int test;
+
+    /* printf ("basiclique (%d)\n", bigtooth - blocklist); fflush (stdout); */
+
+    toothslack = -(bigtooth->weight) + 1.0;
+
+    if (toothslack <= 0.001)
+        return 0;
+    for (count = 0, np = bigtooth->members; np; np = np->next)
+        count++;
+    if (count < 3)
+        return 0;
+
+
+    combs = (Xblockptr *) NULL;
+    for (cp = bigtooth->cutnodes; cp; cp = cp->next) {
+        c = cp->this;
+        min = 100.0;
+        minb = (Xblock *) NULL;
+        for (bp = c->blocks; bp; bp = bp->next) {
+            b = bp->this;
+            if (b == bigtooth)
+                continue;
+            if (combslack (G, b, bigtooth, &t, (Xnodeptrptr **) NULL))
+                if (t < min) {
+                    min = t;
+                    minb = b;
+                }
+        }
+        if (minb) {
+            bp = Xblockptralloc ();
+            bp->this = minb;
+            bp->hood_weight = min;
+            bp->next = combs;
+            combs = bp;
+        }
+    }
+    goodcount = 0;
+    for (count = 0, bp = combs; bp; bp = bp->next) {
+        if (bp->hood_weight >= toothslack)
+            bp->this->mark = 0;
+        else {
+            bp->this->mark = 1;
+            goodcount++;
+        }
+        count++;
+    }
+
+    if (count <= 1) {
+        for (bp = combs; bp; bp = bnext) {
+            bnext = bp->next;
+            Xblockptrfree (bp);
+        }
+        return 0;
+    } else if (goodcount == 1) {
+        min = 100.0;
+        for (bp = combs; bp; bp = bp->next)
+            if (!bp->this->mark && bp->hood_weight < min) {
+                min = bp->hood_weight;
+                minb = bp->this;
+            }
+        minb->mark = 1;
+    } else if (goodcount == 0) {
+        min = 100.0;
+        for (bp = combs; bp; bp = bp->next)
+            if (!bp->this->mark && bp->hood_weight < min) {
+                min = bp->hood_weight;
+                minb = bp->this;
+            }
+        minb->mark = 1;
+        min = 100.0;
+        for (bp = combs; bp; bp = bp->next)
+            if (!bp->this->mark && bp->hood_weight < min) {
+                min = bp->hood_weight;
+                minb = bp->this;
+            }
+        minb->mark = 1;
+    }
+    for (slack = 0.0, nhandles = 0, bp = combs; bp; bp = bp->next)
+        if (bp->this->mark) {
+            nhandles++;
+            slack += bp->hood_weight;
+        }
+    slack -= ((nhandles - 1) * toothslack);
+
+/*
+    printf ("NEW CLIQUE SLACK: %f\n", slack);
+    fflush (stdout);
+*/
+
+    if (slack >= -BLOTOLERANCE) {
+        for (bp = combs; bp; bp = bnext) {
+            bnext = bp->next;
+            Xblockptrfree (bp);
+        }
+        return 0;
+    }
+    teeth = (Xnodeptrptr *) NULL;
+    handles = (Xnodeptrptr *) NULL;
+    markblock (bigtooth, (Xcutnode *) NULL, &tooth);
+    Xadd_nodeptrptr (&teeth, tooth);
+
+    for (bp = combs; bp; bp = bp->next)
+        if (bp->this->mark) {
+            markblock (bp->this, (Xcutnode *) NULL, &handle);
+            Xadd_nodeptrptr (&handles, handle);
+            combslack (G, bp->this, bigtooth, &t, &teeth);
+        }
+    for (bp = combs; bp; bp = bnext) {
+        bnext = bp->next;
+        Xblockptrfree (bp);
+    }
+    if (!Xcliquefluff (G, &handles, &teeth)) {
+        printf ("DE FLUFFED TO 0\n");
+        fflush (stdout);
+        return 0;
+    }
+    if (!Xviolated_clique_flow (G, handles, teeth, x)) {
+        printf ("BANG!\n");
+        fflush (stdout);
+        Xfreeteeth (handles);
+        Xfreeteeth (teeth);
+        return 0;
+    } else {
+        test = Xloadcplane (list, (Xnodeptr *) NULL, handles, teeth, 0);
+        if (!test) {
+            Xfreeteeth (handles);
+            Xfreeteeth (teeth);
+        }
+        return test;
+    }
+
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int combslack (Xgraph *G, Xblock *handle, Xblock *fixtooth,
+            double *slack, Xnodeptrptr **teeth)
+#else
+static int combslack (G, handle, fixtooth, slack, teeth)
+Xgraph *G;
+Xblock *handle, *fixtooth;
+double *slack;
+Xnodeptrptr **teeth;
+#endif
+{
+    int nteeth, hood = 0;
+    double max, total;
+    Xedge *e;
+    Xedgeptr *ep;
+    Xnode *n;
+    Xnodeptr *np;
+    Xcutnode *c;
+    Xcutnodeptr *cp;
+    Xblock *b, *maxb = (Xblock *) NULL;
+    Xblockptr *bp;
+    Xnodeptr *tooth;
+
+    /*
+    printf ("combslack (%d, %d) ... \n", handle - blocklist,
+                                         fixtooth - * blocklist);
+    fflush (stdout);
+    */
+
+    nteeth = 1;
+    total = fixtooth->weight + handle->weight;
+
+    for (n = G->pseudonodelist->next; n; n = n->next)
+        n->stacklabel = 0;
+    for (np = fixtooth->members; np; np = np->next)
+        np->this->stacklabel = 1;
+    for (bp = fixtooth->neighbors; bp; bp = bp->next)
+        for (np = bp->this->members; np; np = np->next)
+            np->this->stacklabel = 1;
+
+    G->magicnum++;
+    for (ep = handle->one; ep; ep = ep->next) {
+        e = ep->this;
+        if (e->cends[0]->stacklabel != e->cends[1]->stacklabel) {
+            e->cends[0]->magiclabel = G->magicnum;
+            e->cends[1]->magiclabel = G->magicnum;
+            nteeth++;
+            total += 1.0;
+            if (teeth) {
+                Xmarktooth (e, &tooth);
+                Xadd_nodeptrptr (teeth, tooth);
+            }
+        }
+    }
+    for (np = fixtooth->members; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    for (cp = handle->cutnodes; cp; cp = cp->next) {
+        c = cp->this;
+        if (c->name->magiclabel != G->magicnum) {
+            max = 0.0;
+            for (bp = c->blocks; bp; bp = bp->next) {
+                b = bp->this;
+                if (b != handle) {
+                    if (b->weight > max) {
+                        hood = 0;
+                        maxb = b;
+                        max = b->weight;
+                    }
+                    if (bp->hood_weight > max) {
+                        hood = 1;
+                        maxb = b;
+                        max = bp->hood_weight;
+                    }
+                }
+            }
+            if (max >= 0.5) {
+                nteeth++;
+                total += max;
+                if (teeth) {
+                    if (hood)
+                        markblock (maxb, c, &tooth);
+                    else
+                        markblock (maxb, (Xcutnode *) NULL, &tooth);
+                    Xadd_nodeptrptr (teeth, tooth);
+                }
+            }
+        }
+    }
+
+    if (!(nteeth % 2))
+        return 0;
+    else {
+        *slack = 1.5 + (0.5 * nteeth) - total;
+        return 1;
+    }
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xblossom.c b/contrib/blossom/concorde97/XSTUFF/Xblossom.c
new file mode 100644
index 0000000000000000000000000000000000000000..376b5d8008314deef0e68f75930587c04803144f
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xblossom.c
@@ -0,0 +1,1028 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*  int                                                                   */
+/*      Xexactblossoms_run (Xgraph *G, Xcplane **list, double *x),        */
+/*      Xexactblossomcheck (Xgraph *G, Xcplane **list, int pseudo,        */
+/*            double *x),                                                 */
+/*      Xolaf (Xgraph *G, int olaf_select);                               */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    buildcadj_from_pseudoedgelist (Xgraph *G),
+    buildcadj_from_edgelist (Xgraph *G),
+    buildpseudonodelist_from_scratch (Xgraph *G),
+    removedegreezero (Xgraph *G),
+    splitem (Xgraph *G, Xnode *n),
+    splitedge (Xgraph *G, Xedge *e, Xnode *n),
+    destroysplitgraph (Xgraph *G),
+    freesplitcadj (Xgraph *G),
+    freesplitedges (Xgraph *G),
+    freesplitters (Xgraph *G),
+    markcuttree_cut (Xcuttree_node *n, int v, int pseudo),
+    marknode (Xnode *n, int v),
+    dumpchildren (Xgraph *G, Xcuttree_node *n),
+    dump_cuttree (Xcuttree_node *t, Xnode *n),
+    T1 (Xgraph *G),
+    T2 (Xgraph *G),
+    T3 (Xgraph *G),
+    T4 (Xgraph *G),
+    T5 (Xgraph *G);
+
+static int
+    checkcuttree (Xgraph *G, Xcplane **cplanelist, Xcuttree_node *root,
+          int pseudo, double *x),
+    searchtree (Xgraph *G, Xcplane **cplanelist, Xcuttree_node *n,
+          int pseudo, double *x, double *val_last, int *n_last),
+    loadcuttree_blossom (Xgraph *G, Xcplane **cplanelist, int v),
+    loadcuttree_comb (Xgraph *G, Xcplane **list, int v, double *x),
+    cuttree_tooth (Xedge *e, int v),
+    isita_fattooth (Xedge *e),
+    oneend (Xedge *e, int v);
+
+#else
+
+static void
+    buildcadj_from_pseudoedgelist (),
+    buildcadj_from_edgelist (),
+    buildpseudonodelist_from_scratch (),
+    removedegreezero (),
+    splitem (),
+    splitedge (),
+    destroysplitgraph (),
+    freesplitcadj (),
+    freesplitedges (),
+    freesplitters (),
+    markcuttree_cut (),
+    marknode (),
+    dumpchildren (),
+    dump_cuttree (),
+    T1 (),
+    T2 (),
+    T3 (),
+    T4 (),
+    T5 ();
+
+static int
+    checkcuttree (),
+    searchtree (),
+    loadcuttree_blossom (),
+    loadcuttree_comb (),
+    cuttree_tooth (),
+    isita_fattooth (),
+    oneend ();
+
+#endif
+
+#ifdef   DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    dumpsplitgraph (Xgraph *G);
+#else
+static void
+    dumpsplitgraph ();
+#endif
+#endif
+
+
+#define ONEMINUS 0.999999
+#define ZEROPLUS 0.000001
+
+static int npseudoedges;
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xexactblossoms_run (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xexactblossoms_run (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    return Xexactblossomcheck (G, list, 0, x);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xexactblossomcheck (Xgraph *G, Xcplane **cplanelist, int pseudo, double *x)
+#else
+int Xexactblossomcheck (G, cplanelist, pseudo, x)
+Xgraph *G;
+Xcplane **cplanelist;
+int pseudo;
+double *x;
+#endif
+{
+    int i, j, npseudo_save = 0;
+    Xnode *n, **pseudo_save = (Xnode **) NULL, **p;
+    Xedge *e;
+    static Xedge pseudoedgedummy;
+    Xcuttree_node *root;
+
+    if (!pseudo) {
+        Xloadx (G, x);
+        buildpseudonodelist_from_scratch (G);
+        for (i = G->nedges, e = G->edgelist; i; i--, e++) {
+            e->cends[0] = e->ends[0];
+            e->cends[1] = e->ends[1];
+            e->stay = 1;
+        }
+        buildcadj_from_edgelist (G);
+    } else {
+        pseudo_save = CC_SAFE_MALLOC (G->npseudonodes, Xnode *);
+        if (!pseudo_save) {
+            fprintf (stderr, "out of memory in Xexactblossomcheck\n");
+            exit (1);
+        }
+        for (n = G->pseudonodelist->next, p = pseudo_save; n; n = n->next, p++)
+            *p = n;
+        npseudo_save = G->npseudonodes;
+    }
+
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        n->pe = (Xedge *) NULL;
+        n->mark = 0;
+    }
+    for (i = G->nedges, e = G->edgelist; i; i--, e++) {
+        if (!e->stay) {
+            continue;
+        } else if (e->x > ONEMINUS) {
+            e->splitter = G->nodelist;     /* just to kill the edge */
+            e->cends[0]->mark = 1 - e->cends[0]->mark;
+            e->cends[1]->mark = 1 - e->cends[1]->mark;
+        } else if (e->x < ZEROPLUS) {
+            e->splitter = G->nodelist;
+        } else {
+            e->splitter = (Xnode *) NULL;
+        }
+    }
+
+
+    G->pseudoedgelist = &pseudoedgedummy;
+    G->pseudoedgelist->next = (Xedge *) NULL;
+    npseudoedges = 0;
+
+    G->magicnum++;
+    for (n = G->pseudonodelist->next; n; n = n->next)
+        if (n->magiclabel != G->magicnum)
+            splitem (G, n);
+
+    freesplitcadj (G);
+    buildcadj_from_pseudoedgelist (G);
+    removedegreezero (G);
+
+    root = Xgomory_hu (G);
+
+    if (root) {
+        j = checkcuttree (G, cplanelist, root, pseudo, x);
+/*
+        printf ("%d exact blossoms\n", j);
+        fflush (stdout);
+*/
+        Xcuttree_free (root);
+    } else
+        j = 0;
+
+    destroysplitgraph (G);
+    if (pseudo) {
+        G->npseudonodes = npseudo_save;
+        n = G->pseudonodelist;
+        for (i = npseudo_save, p = pseudo_save; i; i--, p++) {
+            n->next = *p;
+            n->next->prev = n;
+            n = n->next;
+        }
+        n->next = (Xnode *) NULL;
+        CC_FREE (pseudo_save, Xnode *);
+        buildcadj_from_edgelist (G);
+    }
+    return j;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildcadj_from_pseudoedgelist (Xgraph *G)
+#else
+static void buildcadj_from_pseudoedgelist (G)
+Xgraph *G;
+#endif
+{
+    Xedge *e;
+    Xedgeptr *ep;
+
+    for (e = G->pseudoedgelist->next; e; e = e->next) {
+        ep = Xedgeptralloc ();
+        ep->next = (e->cends[0])->cadj.head;
+        ep->this = e;
+        (e->cends[0])->cadj.head = ep;
+        if ((e->cends[0])->cadj.tail == (Xedgeptr *) NULL)
+            (e->cends[0])->cadj.tail = ep;
+        ep = Xedgeptralloc ();
+        ep->next = (e->cends[1])->cadj.head;
+        ep->this = e;
+        (e->cends[1])->cadj.head = ep;
+        if ((e->cends[1])->cadj.tail == (Xedgeptr *) NULL)
+            (e->cends[1])->cadj.tail = ep;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildcadj_from_edgelist (Xgraph *G)
+#else
+static void buildcadj_from_edgelist (G)
+Xgraph *G;
+#endif
+{
+    Xedge *e;
+    Xedgeptr *ep;
+    int i;
+
+    for (i = G->nedges, e = G->edgelist; i; i--, e++) {
+        if (!e->stay)
+            continue;
+        ep = Xedgeptralloc ();
+        ep->next = (e->cends[0])->cadj.head;
+        ep->this = e;
+        (e->cends[0])->cadj.head = ep;
+        if ((e->cends[0])->cadj.tail == (Xedgeptr *) NULL)
+            (e->cends[0])->cadj.tail = ep;
+        ep = Xedgeptralloc ();
+        ep->next = (e->cends[1])->cadj.head;
+        ep->this = e;
+        (e->cends[1])->cadj.head = ep;
+        if ((e->cends[1])->cadj.tail == (Xedgeptr *) NULL)
+            (e->cends[1])->cadj.tail = ep;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void buildpseudonodelist_from_scratch (Xgraph *G)
+#else
+static void buildpseudonodelist_from_scratch (G)
+Xgraph *G;
+#endif
+{
+    static Xnode pseudonodedummy;
+    int i;
+    Xnode *n;
+
+    G->pseudonodelist = &pseudonodedummy;
+    pseudonodedummy.prev = (Xnode *) NULL;
+    pseudonodedummy.next = G->nodelist;
+    for (i = 0, n = G->nodelist; i < G->nnodes; i++, n++) {
+        n->cadj.head = n->cadj.tail = (Xedgeptr *) NULL;
+        n->prev = n - 1;
+        n->next = n + 1;
+    }
+    G->nodelist->prev = G->pseudonodelist;
+    G->nodelist[G->nnodes - 1].next = (Xnode *) NULL;
+    G->npseudonodes = G->nnodes;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void removedegreezero (Xgraph *G)
+#else
+static void removedegreezero (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n, *next;
+
+    for (n = G->pseudonodelist->next; n; n = next)
+        if (n->cadj.head == (Xedgeptr *) NULL) {
+            if ((next = n->next) != (Xnode *) NULL) {
+                n->next->prev = n->prev;
+                n->prev->next = n->next;
+            } else
+                n->prev->next = (Xnode *) NULL;
+            G->npseudonodes--;
+        } else
+            next = n->next;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void splitem (Xgraph *G, Xnode *n)
+#else
+static void splitem (G, n)
+Xgraph *G;
+Xnode *n;
+#endif
+{
+    Xedgeptr *ep;
+    Xedge *e, *last;
+    Xnode *child;
+
+    n->magiclabel = G->magicnum;
+    for (ep = n->cadj.head; ep; ep = ep->next) {
+        e = ep->this;
+        if (!e->splitter) {
+            child = OTHERCURRENTEND (e, n);
+            if (child->magiclabel != G->magicnum)
+                splitem (G, child);
+        }
+    }
+    for (ep = n->cadj.head, last = (Xedge *) NULL; ep; ep = ep->next) {
+        e = ep->this;
+        if (!e->splitter) {
+            if (last)
+                splitedge (G, last, n);
+            last = e;
+        }
+    }
+
+    if (last) {
+        if (n->mark)
+            splitedge (G, last, n);
+        else
+            splitedge (G, last, OTHERCURRENTEND (last, n));
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void splitedge (Xgraph *G, Xedge *e, Xnode *n)
+#else
+static void splitedge (G, e, n)
+Xgraph *G;
+Xedge *e;
+Xnode *n;
+#endif
+{
+    Xnode *n1;
+    Xedge *e1;
+
+    n->mark = 1 - n->mark;
+
+    n1 = Xnodealloc ();
+    n1->magiclabel = 0;
+    n1->stacklabel = 0;
+    e->splitter = n1;
+    n1->pe = e;
+    n1->snext = n;              /* points to the end which is marked odd */
+    n1->mark = 1;
+    n1->cadj.head = n1->cadj.tail = (Xedgeptr *) NULL;
+
+    n1->base.head = Xnodeptralloc ();
+    n1->base.tail = n1->base.head;
+    n1->base.head->next = (Xnodeptr *) NULL;
+    n1->base.head->this = n1;
+
+    n1->next = G->pseudonodelist->next;
+    n1->prev = G->pseudonodelist;
+    G->pseudonodelist->next->prev = n1;
+    G->pseudonodelist->next = n1;
+    G->npseudonodes++;
+
+
+    e1 = Xedgealloc ();
+    e1->cends[0] = n;
+    e1->cends[1] = n1;
+    e1->stay = 1;
+    e1->x = 1.0 - e->x;
+    e1->next = G->pseudoedgelist->next;
+    G->pseudoedgelist->next = e1;
+    npseudoedges++;
+
+
+    e1 = Xedgealloc ();
+    e1->cends[0] = OTHERCURRENTEND (e, n);
+    e1->cends[1] = n1;
+    e1->stay = 1;
+    e1->x = e->x;
+    e1->next = G->pseudoedgelist->next;
+    G->pseudoedgelist->next = e1;
+    npseudoedges++;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void destroysplitgraph (Xgraph *G)
+#else
+static void destroysplitgraph (G)
+Xgraph *G;
+#endif
+{
+    freesplitcadj (G);
+    freesplitedges (G);
+    freesplitters (G);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void freesplitcadj (Xgraph *G)
+#else
+static void freesplitcadj (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n;
+    Xedgeptr *e, *enext;
+
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        for (e = n->cadj.head; e; e = enext) {
+            enext = e->next;
+            Xedgeptrfree (e);
+        }
+        n->cadj.head = n->cadj.tail = (Xedgeptr *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void freesplitedges (Xgraph *G)
+#else
+static void freesplitedges (G)
+Xgraph *G;
+#endif
+{
+    Xedge *e, *enext;
+
+    for (e = G->pseudoedgelist->next; e; e = enext) {
+        enext = e->next;
+        Xedgefree (e);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void freesplitters (Xgraph *G)
+#else
+static void freesplitters (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n, *nnext, *prev;
+    Xnodeptr *np, *npnext;
+
+    for (n = G->pseudonodelist->next, prev = G->pseudonodelist; n; n = nnext) {
+        nnext = n->next;
+        if (n->pe) {
+            prev->next = nnext;
+            if (nnext)
+                nnext->prev = prev;
+            for (np = n->base.head; np; np = npnext) {
+                npnext = np->next;
+                Xnodeptrfree (np);
+            }
+            Xnodefree (n);
+        } else
+            prev = n;
+    }
+}
+
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void dumpsplitgraph (Xgraph *G)
+#else
+static void dumpsplitgraph (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n;
+    Xedge *e;
+    int i;
+
+    printf ("NODES: %d\n", G->npseudonodes);
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        printf ("NODE %d  mark = %d", n - G->nodelist, n->mark);
+        if (n->pe)
+            printf (" from %d\n", n->pe - G->edgelist);
+        else
+            printf ("\n");
+    }
+
+    printf ("EDGES: %d\n", npseudoedges);
+    for (i = 0, e = G->pseudoedgelist->next; e; e = e->next, i++) {
+        printf ("(%d %d %f) ", e->cends[0] - G->nodelist,
+                e->cends[1] - G->nodelist,
+                e->x);
+        if (i % 10 == 9)
+            printf ("\n");
+    }
+    if (i % 10)
+        printf ("\n");
+    fflush (stdout);
+}
+#endif /* DEBUG */
+
+
+
+/***********************************************************************/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkcuttree (Xgraph *G, Xcplane **cplanelist, Xcuttree_node *root,
+            int pseudo, double *x)
+#else
+static int checkcuttree (G, cplanelist, root, pseudo, x)
+Xgraph *G;
+Xcplane **cplanelist;
+Xcuttree_node *root;
+int pseudo;
+double *x;
+#endif
+{
+    int nviolated;
+    int n_last = 0;
+    double val_last = 1.0;
+
+    if (x == (double *) NULL) {
+        printf ("need x vector in checkcuttree\n");
+        fflush (stdout);
+        return 0;
+    }
+
+    nviolated = searchtree (G, cplanelist, root, pseudo, x, &val_last, &n_last);
+    return nviolated;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int searchtree (Xgraph *G, Xcplane **cplanelist, Xcuttree_node *n,
+            int pseudo, double *x, double *val_last, int *n_last)
+#else
+static int searchtree (G, cplanelist, n, pseudo, x, val_last, n_last)
+Xgraph *G;
+Xcplane **cplanelist;
+Xcuttree_node *n;
+int pseudo;
+double *x;
+double *val_last;               /* these guys are a hack to try to stop
+                                 * repeats */
+int *n_last;
+#endif
+{
+    Xcuttree_node *c;
+    int i = 0;
+
+    if (n->ndescendants % 2 == 1  &&  n->ndescendants > 1  ) {
+        if (n->cutval < 1.0 - XBLOTOLERANCE) {
+            G->magicnum++;
+            markcuttree_cut (n, G->magicnum, pseudo);
+            if (pseudo) {
+                i += loadcuttree_comb (G, cplanelist, G->magicnum, x);
+            } else
+                i += loadcuttree_blossom (G, cplanelist, G->magicnum);
+        }
+    }
+    for (c = n->child; c; c = c->sibling)
+        i += searchtree (G, cplanelist, c, pseudo, x, val_last, n_last);
+
+    return i;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void markcuttree_cut (Xcuttree_node *n, int v, int pseudo)
+#else
+static void markcuttree_cut (n, v, pseudo)
+Xcuttree_node *n;
+int v, pseudo;
+#endif
+{
+    Xcuttree_node *c;
+    Xnodeptr *np;
+
+    for (np = n->nlist.head; np; np = np->next)
+        if (pseudo) {
+            marknode (np->this, v);
+        } else
+            np->this->magiclabel = v;
+
+    for (c = n->child; c; c = c->sibling)
+        markcuttree_cut (c, v, pseudo);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int loadcuttree_blossom (Xgraph *G, Xcplane **cplanelist, int v)
+#else
+static int loadcuttree_blossom (G, cplanelist, v)
+Xgraph *G;
+Xcplane **cplanelist;
+int v;
+#endif
+{
+    int i, test;
+    Xedge *e;
+    Xnode *n;
+    Xnodeptr *handle, *np;
+    Xedgeptr *teeth, *ep;
+
+    teeth = (Xedgeptr *) NULL;
+    for (i = G->nedges, e = G->edgelist; i; i--, e++)
+        if (oneend (e, v) && cuttree_tooth (e, v)) {
+            ep = Xedgeptralloc ();
+            ep->this = e;
+            ep->next = teeth;
+            teeth = ep;
+        }
+    handle = (Xnodeptr *) NULL;
+    for (i = G->nnodes, n = G->nodelist; i; i--, n++)
+        if (n->magiclabel == v) {
+            np = Xnodeptralloc ();
+            np->this = n;
+            np->next = handle;
+            handle = np;
+        }
+    test = Xtemp_doblossom (G, cplanelist, handle, teeth);
+    Xedgeptr_list_free (teeth);
+    return test;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int loadcuttree_comb (Xgraph *G, Xcplane **cplanelist, int v, double *x)
+#else
+static int loadcuttree_comb (G, cplanelist, v, x)
+Xgraph *G;
+Xcplane **cplanelist;
+int v;
+double *x;
+#endif
+{
+    int i, nteeth, test, hit = 0, countcheck = 1;
+    Xnode *n;
+    Xedge *e;
+    Xnodeptr *np, *handle;
+    Xnodeptrptr *teeth, *ntp;
+
+
+    for (i = G->nedges, e = G->edgelist; i; i--, e++) {
+        if (e->stay && oneend (e, v) &&
+            cuttree_tooth (e, v) && isita_fattooth (e)) {
+            hit = 1;
+            break;
+        }
+    }
+    if (!hit)
+        return 0;
+
+    handle = (Xnodeptr *) NULL;
+    for (i = G->nnodes, n = G->nodelist; i; i--, n++)
+        if (n->magiclabel == v) {
+            np = Xnodeptralloc ();
+            np->this = n;
+            np->next = handle;
+            handle = np;
+        }
+    teeth = (Xnodeptrptr *) NULL;
+    for (nteeth = 0, i = G->nedges, e = G->edgelist; i; i--, e++) {
+        if (!e->stay)
+            continue;
+        if (oneend (e, v) && cuttree_tooth (e, v)) {
+            nteeth++;
+            ntp = Xnodeptrptralloc ();
+            ntp->this = (Xnodeptr *) NULL;
+            ntp->next = teeth;
+            teeth = ntp;
+            Xmarktooth (e, &(ntp->this));
+        }
+    }
+
+    Xcleancomb (G, &handle, &teeth, &nteeth, x);
+    if (!Xtemp_combfluff (G, &handle, &teeth))
+        return 0;
+    test = Xloadcplane (cplanelist, handle, (Xnodeptrptr *) NULL, teeth,
+                        countcheck);
+    if (!test) {
+        Xnodeptr_list_free (handle);
+        for (ntp = teeth; ntp; ntp = ntp->next)
+            Xnodeptr_list_free (ntp->this);
+        Xnodeptrptr_list_free (teeth);
+    }
+    return test;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cuttree_tooth (Xedge *e, int v)
+#else
+static int cuttree_tooth (e, v)
+Xedge *e;
+int v;
+#endif
+{
+    if (e->x > ONEMINUS)
+        return 1;
+    if (e->x < ZEROPLUS)
+        return 0;
+
+    if (e->splitter->magiclabel == v) {
+        if (e->splitter->snext->magiclabel == v)
+            return 0;
+        else
+            return 1;
+    } else {
+        if (e->splitter->snext->magiclabel == v)
+            return 1;
+        else
+            return 0;
+    }
+
+    /* David: is this the same as return (e->splitter->magiclabel == v) ^
+     * (e->splitter->snext->magiclabel == v)   */
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int isita_fattooth (Xedge *e)
+#else
+static int isita_fattooth (e)
+Xedge *e;
+#endif
+{
+    return (e->cends[0]->base.head->next ||
+            e->cends[1]->base.head->next);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int oneend (Xedge *e, int v)
+#else
+static int oneend (e, v)
+Xedge *e;
+int v;
+#endif
+{
+    if ((e->ends[0]->magiclabel == v && e->ends[1]->magiclabel != v) ||
+        (e->ends[0]->magiclabel != v && e->ends[1]->magiclabel == v))
+        return 1;
+    else
+        return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void marknode (Xnode *n, int v)
+#else
+static void marknode (n, v)
+Xnode *n;
+int v;
+#endif
+{
+    Xnodeptr *np;
+
+    n->magiclabel = v;
+    for (np = n->base.head; np; np = np->next) {
+        np->this->magiclabel = v;
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dumpchildren (Xgraph *G, Xcuttree_node *n)
+#else
+static void dumpchildren (G, n)
+Xgraph *G;
+Xcuttree_node *n;
+#endif
+{
+    Xcuttree_node *c;
+    Xnodeptr *cp;
+
+    for (cp = n->nlist.head; cp; cp = cp->next) {
+        printf ("%d ", (int) (cp->this - G->nodelist));
+        if (cp->this->pe)
+            printf ("splits  %d = (%d %d) ",
+                        (int) (cp->this->pe - G->edgelist),
+                        (int) (cp->this->pe->ends[0] - G->nodelist),
+                        (int) (cp->this->pe->ends[1] - G->nodelist));
+    }
+    printf ("Special: %d\n", (int) (n->special - G->nodelist));
+    for (c = n->child; c; c = c->sibling)
+        dumpchildren (G, c);
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_cuttree (Xcuttree_node *t, Xnode *n)
+#else
+static void dump_cuttree (t, n)
+Xcuttree_node *t;
+Xnode *n;
+#endif
+{
+    Xcuttree_node *p;
+    Xnodeptr *pn;
+
+    printf ("(%f, %d, %d, <", t->cutval, t->ndescendants,
+                   (int) (t->special - n));
+    for (pn = t->nlist.head; pn; pn = pn->next)
+        printf ("%d ", (int) (pn->this - n));
+    printf ("> )\n");
+    for (p = t->child; p; p = p->sibling)
+        dump_cuttree (p, n);
+    printf ("*");
+    fflush (stdout);
+}
+
+/**********************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xolaf (Xgraph *G, int olaf_select)
+#else
+int Xolaf (G, olaf_select)
+Xgraph *G;
+int olaf_select;
+#endif
+{
+    Xnode *n;
+    int oldpseudonodes = G->npseudonodes;
+
+    for (n = G->pseudonodelist->next; n; n = n->next)
+        n->Tmark = 0;
+
+    switch (olaf_select) {
+    case 1:
+        T1 (G);
+        T2 (G);
+        T3 (G);
+        break;
+    case 2:
+        T1 (G);
+        T4 (G);
+        T3 (G);
+        break;
+    case 3:
+        T1 (G);
+        T5 (G);
+        T3 (G);
+        break;
+    case 4:
+        T1 (G);
+        T4 (G);
+        T5 (G);
+        break;
+    default:
+        printf ("Hey pal, don't call olaf with %d\n", olaf_select);
+        break;
+    }
+    return oldpseudonodes - G->npseudonodes;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void T1 (Xgraph *G)
+#else
+static void T1 (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    Xedge *e;
+    Xnode *u, *v;
+
+    for (e = G->edgelist, i = G->nedges; i; e++, i--) {
+        if (e->stay && e->x == 1.0) {
+            u = e->cends[0];
+            v = e->cends[1];
+            if (Xrepeat_1_shrink (G, u, e) + Xrepeat_1_shrink (G, v, e)) {
+                u->Tmark = 1;
+                v->Tmark = 1;
+            }
+        }
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static void T2 (Xgraph *G)
+#else
+static void T2 (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    Xedge *e, *f, *g;
+    Xedgeptr *ep;
+    Xnode *u, *v, *w;
+
+    for (e = G->edgelist, i = G->nedges; i; e++, i--) {
+        if (e->stay && e->x == 1.0 && !(u = e->cends[0])->Tmark
+            && !(v = e->cends[1])->Tmark) {
+            for (ep = u->cadj.head; ep && !u->Tmark; ep = ep->next) {
+                f = ep->this;
+                w = OTHERCURRENTEND (f, u);
+                if (!w->Tmark && (g = Xcurrentedge (v, w)) != (Xedge *) NULL)
+                    if (f->x + g->x > 1.0 - XEPSILON) {
+                        Xsimpleshrink (G, u, v);
+                        u->Tmark = 1;
+                        w->Tmark = 1;
+                    }
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void T3 (Xgraph *G)
+#else
+static void T3 (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    Xedge *c, *d, *e, *f, *g, *h;
+    Xedgeptr *ep, *ep2;
+    Xnode *u, *v, *w, *x;
+
+    for (e = G->edgelist, i = G->nedges; i; e++, i--) {
+        /* e->x == 1 remove */
+        if (e->stay && !(u = e->cends[0])->Tmark
+            && !(w = e->cends[1])->Tmark) {
+            for (ep = u->cadj.head; ep && !u->Tmark; ep = ep->next) {
+                f = ep->this;
+                v = OTHERCURRENTEND (f, u);
+                if (!v->Tmark) {
+                    for (ep2 = w->cadj.head; ep2 &&
+                         !w->Tmark; ep2 = ep2->next) {
+                        g = ep2->this;
+                        x = OTHERCURRENTEND (g, w);
+                        if (!x->Tmark &&
+                            x != v &&
+                            (h = Xcurrentedge (v, x)) != (Xedge *) NULL &&
+                            (d = Xcurrentedge (u, x)) != (Xedge *) NULL &&
+                            (c = Xcurrentedge (w, v)) != (Xedge *) NULL &&
+                            c->x + d->x + e->x + f->x + g->x + h->x >=
+                                                           3.0 - XEPSILON) {
+                            Xsimpleshrink (G, u, w);
+                            Xsimpleshrink (G, u, v);
+                            Xsimpleshrink (G, u, x);
+                            u->Tmark = 1;
+                            w->Tmark = 1;
+                            v->Tmark = 1;
+                            x->Tmark = 1;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void T4 (Xgraph *G)
+#else
+static void T4 (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    Xedge *e, *f, *g, *h;
+    Xedgeptr *ep, *ep2;
+    Xnode *u, *v, *w, *x;
+
+    for (e = G->edgelist, i = G->nedges; i; e++, i--) {
+        if (e->stay && e->x == 1.0 && !(u = e->cends[0])->Tmark
+            && !(w = e->cends[1])->Tmark) {
+            for (ep = u->cadj.head; ep && !u->Tmark; ep = ep->next) {
+                f = ep->this;
+                v = OTHERCURRENTEND (f, u);
+                if (!v->Tmark) {
+                    for (ep2 = w->cadj.head; ep2 &&
+                         !w->Tmark; ep2 = ep2->next) {
+                        g = ep2->this;
+                        x = OTHERCURRENTEND (g, w);
+                        if (!x->Tmark &&
+                            x != v &&
+                            f->x + g->x == 1.0 &&
+                            (h = Xcurrentedge (v, x)) != (Xedge *) NULL &&
+                            h->x == 1.0) {
+                            Xsimpleshrink (G, u, w);
+                            Xsimpleshrink (G, v, x);
+                            u->Tmark = 1;
+                            w->Tmark = 1;
+                            v->Tmark = 1;
+                            x->Tmark = 1;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void T5 (Xgraph *G)
+#else
+static void T5 (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    Xedge *e, *f, *g;
+    Xedgeptr *ep;
+    Xnode *u, *v, *w;
+
+    for (e = G->edgelist, i = G->nedges; i; e++, i--) {
+        if (e->stay && e->x == 1.0 && !(u = e->cends[0])->Tmark
+            && !(v = e->cends[1])->Tmark) {
+            for (ep = u->cadj.head; ep && !u->Tmark; ep = ep->next) {
+                f = ep->this;
+                w = OTHERCURRENTEND (f, u);
+                if (!w->Tmark && (g = Xcurrentedge (v, w)) != (Xedge *) NULL)
+                    if (f->x + g->x <= 0.5 + XEPSILON) {
+                        Xsimpleshrink (G, u, v);
+                        u->Tmark = 1;
+                        w->Tmark = 1;
+                    }
+            }
+        }
+    }
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xcclean.c b/contrib/blossom/concorde97/XSTUFF/Xcclean.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd70f9991451d340a61729a5976c22c7df62e3ad
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xcclean.c
@@ -0,0 +1,1348 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    void                                                                */
+/*        cleancomb ();                                                   */
+/*                                                                        */
+/*    int                                                                 */
+/*        checkcomb (),                                                   */
+/*        cliquefluff (),                                                 */
+/*        temp_combfluff (),                                              */
+/*        combfluff (),                                                   */
+/*        histok (),                                                      */
+/*        checkclique ();                                                 */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    complement_nodeptrlist (Xgraph *G, Xnodeptr *list, Xnodeptr **new),
+    get_smaller_cliquetree (Xgraph *G, Xnodeptrptr **newhandles,
+        Xnodeptrptr **newteeth, Xnodeptrptr *handles, Xnodeptrptr *teeth,
+        Xnodeptr *specialhandle),
+    clean_handle (Xgraph *G, Xnodeptr **handle, Xnodeptrptr **teeth,
+                  int *nteeth, int *degree, double *x),
+    clean_stretch (Xgraph *G, Xnode *a, Xnode *b, Xnodeptr **toss,
+                   Xnodeptr **tooth, int *degree, double *x),
+    clean_tooth (Xgraph *G, Xnodeptr *handle, Xnodeptr *tooth,
+                 Xnodeptr **newtooth, double *x, int *degree),
+    process_clean_tooth_node (Xgraph *G, Xnode *n, double *x, int *degree,
+                              Xnodeptr **toss),
+    clean_handle_connect_dfs (Xgraph *G, Xnode *n, double *x, int k);
+
+static int
+    checkclique_work (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth,
+                                 int flipped),
+    check_for_intersecting_teeth (Xgraph *G, Xnodeptr *handle,
+                                  Xnodeptrptr *teeth),
+    setmarks (Xgraph *G, int *vec, Xnodeptr *p, int from, int to),
+    check_cavity (Xgraph *G, Xnodeptr *p, int *vec),
+    verify_13 (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth),
+    clean_handle_connect (Xgraph *G, Xnodeptr *handle, double *x);
+
+#else
+
+static void
+    complement_nodeptrlist (),
+    get_smaller_cliquetree (),
+    clean_handle (),
+    clean_stretch (),
+    clean_tooth (),
+    process_clean_tooth_node (),
+    clean_handle_connect_dfs ();
+
+static int
+    checkclique_work (),
+    check_for_intersecting_teeth (),
+    setmarks (),
+    check_cavity (),
+    verify_13 (),
+    clean_handle_connect ();
+
+#endif
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcheckcomb (Xgraph *G, Xnodeptr *handle, Xnodeptrptr *teeth)
+#else
+int Xcheckcomb (G, handle, teeth)
+Xgraph *G;
+Xnodeptr *handle;
+Xnodeptrptr *teeth;
+#endif
+{
+    int nteeth, count, in, out;
+    Xnodeptr *np;
+    Xnodeptrptr *ntp;
+
+    for (nteeth = 0, ntp = teeth; ntp; ntp = ntp->next)
+        nteeth++;
+    if (nteeth % 2 == 0) {
+        return 0;
+    }
+    G->magicnum++;
+    for (count = 0, np = handle; np; np = np->next, count++)
+        np->this->magiclabel = G->magicnum;
+
+    if (count < 3) {
+        return 0;
+    }
+    for (count = 0, ntp = teeth; count < nteeth; ntp = ntp->next, count++) {
+        in = out = 0;
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum)
+                in = 1;
+            else
+                out = 1;
+        if (!in || !out) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcliquefluff (Xgraph *G, Xnodeptrptr **handles, Xnodeptrptr **teeth)
+#else
+int Xcliquefluff (G, handles, teeth)
+Xgraph *G;
+Xnodeptrptr **handles, **teeth;
+#endif
+{
+    /* Returns 1 if new clique-tree is loaded in handles and teeth */
+    /* Returns 0 if clique-tree should be killed, wiping out the cut. */
+
+    int nteeth, nhandles, nonpendant, hit, hit1, hit2, cavity;
+    Xnodeptrptr *ntp, *mtp;
+    Xnodeptrptr *nonpendant_teeth, *pendant_teeth;
+    Xnodeptrptr *handle1_teeth, *handle2_teeth;
+    Xnodeptrptr *handle1, *handle2;
+    Xnodeptr *np;
+
+    for (nhandles = 0, ntp = *handles; ntp; ntp = ntp->next)
+        nhandles++;
+    for (nteeth = 0, ntp = *teeth; ntp; ntp = ntp->next)
+        nteeth++;
+
+    if (nhandles == 1)
+        return Xcombfluff (G, handles, teeth, 0);
+
+    if (nteeth % 2 == 0 || nteeth < 3 || nhandles != 2) {
+        Xfreeteeth (*teeth);
+        Xfreeteeth (*handles);
+        /* printf ("FF Wrong Number of Handles or Teeth\n"); */
+        return 0;
+    }
+    /* COLLECT NONPENDANT TEETH */
+
+    nonpendant_teeth = (Xnodeptrptr *) NULL;
+    pendant_teeth = (Xnodeptrptr *) NULL;
+    nonpendant = 0;
+    for (ntp = *teeth; ntp; ntp = ntp->next) {
+        G->magicnum++;
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+        for (mtp = *handles, hit = 0; mtp && hit < 2; mtp = mtp->next)
+            for (np = mtp->this; np; np = np->next)
+                if (np->this->magiclabel == G->magicnum) {
+                    hit++;
+                    break;
+                }
+        if (hit >= 2) {
+            nonpendant++;
+            Xadd_nodeptrptr (&nonpendant_teeth, ntp->this);
+        } else
+            Xadd_nodeptrptr (&pendant_teeth, ntp->this);
+    }
+
+    if (nonpendant != 1) {
+        Xnodeptrptr_list_free (nonpendant_teeth);
+        Xnodeptrptr_list_free (pendant_teeth);
+        Xfreeteeth (*teeth);
+        Xfreeteeth (*handles);
+        return 0;
+    }
+    /* DO NOT ALLOW NONPENDANT TEETH TO MEET ANY OTHER TEETH */
+
+    G->magicnum++;
+    for (ntp = pendant_teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+    for (ntp = nonpendant_teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum) {
+                Xnodeptrptr_list_free (nonpendant_teeth);
+                Xnodeptrptr_list_free (pendant_teeth);
+                Xfreeteeth (*teeth);
+                Xfreeteeth (*handles);
+                /* printf ("FF Nonpendant Teeth Meet\n"); */
+                return 0;
+            } else
+                np->this->magiclabel = G->magicnum;
+
+    /* DIVIDE THE NONPENDANT TEETH AMONGST THE TWO HANDLES */
+
+    G->magicnum++;
+    handle1 = (Xnodeptrptr *) NULL;
+    Xadd_nodeptrptr (&handle1, (*handles)->this);
+    handle1_teeth = (Xnodeptrptr *) NULL;
+    for (np = handle1->this; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (ntp = pendant_teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum) {
+                Xadd_nodeptrptr (&handle1_teeth, ntp->this);
+                break;
+            }
+    G->magicnum++;
+    handle2 = (Xnodeptrptr *) NULL;
+    Xadd_nodeptrptr (&handle2, (*handles)->next->this);
+    handle2_teeth = (Xnodeptrptr *) NULL;
+    for (np = handle2->this; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (ntp = pendant_teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum) {
+                Xadd_nodeptrptr (&handle2_teeth, ntp->this);
+                break;
+            }
+    /* WE NO LONGER NEED THE ORIGINAL HANDLE & TEETH LISTS */
+
+    Xnodeptrptr_list_free (*handles);
+    Xnodeptrptr_list_free (*teeth);
+    Xnodeptrptr_list_free (pendant_teeth);
+
+    /* DON'T ALLOW ANY TOOTH TO MEET A TOOTH HITTING THE OTHER HANDLE */
+
+    G->magicnum++;
+    for (ntp = handle1_teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+    for (ntp = handle2_teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum) {
+                Xfreeteeth (handle1_teeth);
+                Xfreeteeth (handle2_teeth);
+                Xfreeteeth (handle1);
+                Xfreeteeth (handle2);
+                Xfreeteeth (nonpendant_teeth);
+                /* printf ("FF Cross Teeth Meet\n"); */
+                return 0;
+            }
+
+    /* USE THE COMB CODE TO CLEAN THE TEETH MEETING EACH HANDLE */
+
+    if (!Xcombfluff (G, &handle1, &handle1_teeth, 1)) {
+        Xfreeteeth (handle2);
+        Xfreeteeth (handle2_teeth);
+        Xfreeteeth (nonpendant_teeth);
+        /* printf ("FF Comb Fluff of First Handle Failed\n"); */
+        return 0;
+    } else if (!Xcombfluff (G, &handle2, &handle2_teeth, 1)) {
+        Xfreeteeth (handle1);
+        Xfreeteeth (handle1_teeth);
+        Xfreeteeth (nonpendant_teeth);
+        /* printf ("FF Comb Fluff of Second Handle Failed\n"); */
+        return 0;
+    }
+    if (!handle1 || !handle2 || !handle1_teeth || !handle2_teeth) {
+        /* printf ("OH OH IN FLUFF\n"); */
+        return 0;
+    }
+
+    /* CHECK THAT NEW HANDLES DO NOT MEET */
+
+    G->magicnum++;
+    for (np = handle1->this; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    G->magicnum++;
+    for (np = handle2->this; np; np = np->next)
+        if (np->this->magiclabel == G->magicnum - 1) {
+            Xfreeteeth (handle1);
+            Xfreeteeth (handle2);
+            Xfreeteeth (handle1_teeth);
+            Xfreeteeth (handle2_teeth);
+            Xfreeteeth (nonpendant_teeth);
+            /*  printf ("FF New Handles Meet\n"); */
+            return 0;
+        } else
+            np->this->magiclabel = G->magicnum;
+
+    /* CHECK THAT NONPENDANT TOOTH HAS A CAVITY */
+
+    for (np = nonpendant_teeth->this, hit1 = 0, hit2 = 0, cavity = 0; np;
+                                                              np = np->next) {
+        if (np->this->magiclabel == G->magicnum - 1)
+            hit1++;
+        else if (np->this->magiclabel == G->magicnum)
+            hit2++;
+        else
+            cavity++;
+    }
+
+    if (!hit1 || !hit2 || !cavity) {
+        Xfreeteeth (handle1);
+        Xfreeteeth (handle2);
+        Xfreeteeth (handle1_teeth);
+        Xfreeteeth (handle2_teeth);
+        Xfreeteeth (nonpendant_teeth);
+        /* printf ("FF Nonpendant Tooth No Longer Has a Cavity\n"); */
+        return 0;
+    }
+
+    /* PUT THE NEW CLIQUE TREE TOGETHER */
+
+    handle1->next = handle2;
+    *handles = handle1;
+
+    ntp = handle1_teeth;
+    while (ntp->next)
+        ntp = ntp->next;
+    if (!ntp) {
+        /* printf ("OH OH 2 IN FLUFF\n"); */
+        return 0;
+    }
+    ntp->next = handle2_teeth;
+    nonpendant_teeth->next = handle1_teeth;
+    *teeth = nonpendant_teeth;
+
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xtemp_combfluff (Xgraph *G, Xnodeptr **handle, Xnodeptrptr **teeth)
+#else
+int Xtemp_combfluff (G, handle, teeth)
+Xgraph *G;
+Xnodeptr **handle;
+Xnodeptrptr **teeth;
+#endif
+{
+    Xnodeptrptr *temphandle;
+
+    temphandle = (Xnodeptrptr *) NULL;
+    Xadd_nodeptrptr (&temphandle, *handle);
+    if (!Xcliquefluff (G, &temphandle, teeth)) {
+        return 0;
+    } else {
+        *handle = temphandle->this;
+        Xnodeptrptrfree (temphandle);
+        return 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xtemp_combcheck (Xgraph *G, Xnodeptr *handle, Xnodeptrptr *teeth)
+#else
+int Xtemp_combcheck (G, handle, teeth)
+Xgraph *G;
+Xnodeptr *handle;
+Xnodeptrptr *teeth;
+#endif
+{
+    int rval;
+    Xnodeptrptr *temphandle;
+
+    temphandle = (Xnodeptrptr *) NULL;
+    Xadd_nodeptrptr (&temphandle, handle);
+
+    rval = Xcheckclique (G, temphandle, teeth);
+    Xnodeptrptrfree (temphandle);
+    return rval;
+}
+
+#define SET_NOTEST -2
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcombfluff (Xgraph *G, Xnodeptrptr **handles, Xnodeptrptr **teeth,
+                int cliquetest)
+#else
+int Xcombfluff (G, handles, teeth, cliquetest)
+Xgraph *G;
+Xnodeptrptr **handles;
+Xnodeptrptr **teeth;
+int cliquetest;
+#endif
+{
+    int *in_hand;
+    int *in_tooth;
+    int i, j;
+    int nhand;
+    int nteeth;
+    int newteeth;
+    Xnodeptr **teeth_array;
+    Xnodeptr *p;
+    Xnodeptrptr *np;
+    int v;
+
+    for (np = *handles, nhand = 0; np; np = np->next)
+        nhand++;
+    for (np = *teeth, nteeth = 0; np; np = np->next)
+        nteeth++;
+    if (nhand != 1) {
+        /*
+        printf ("FF Fluff Comb called with more (or less) than one handle\n");
+        */
+        Xfreeteeth (*handles);
+        Xfreeteeth (*teeth);
+        return 0;
+    }
+    if (nteeth == 3 && !cliquetest) {
+        if (verify_13 (G, *handles, *teeth)) {
+            return 1;
+        } else {
+            for (np = *handles; np; np = np->next) {
+                Xnodeptr_list_free (np->this);
+            }
+            for (np = *teeth; np; np = np->next) {
+                Xnodeptr_list_free (np->this);
+            }
+            Xnodeptrptr_list_free (*handles);
+            Xnodeptrptr_list_free (*teeth);
+            *handles = (Xnodeptrptr *) NULL;
+            *teeth = (Xnodeptrptr *) NULL;
+            /* printf ("FF Fluff Comb\n"); */
+            return 0;
+        }
+    }
+    in_hand = CC_SAFE_MALLOC (G->nnodes, int);
+    in_tooth = CC_SAFE_MALLOC (G->nnodes, int);
+    if (!in_hand || !in_tooth) {
+        fprintf (stderr, "out of memory in Xcombfluff\n");
+        exit (1);
+    }
+
+    for (i = 0; i < G->nnodes; i++) {
+        in_hand[i] = 0;
+        in_tooth[i] = -1;
+    }
+
+    if (setmarks (G, in_hand, (*handles)->this, 0, 1) != SET_NOTEST) {
+        fprintf (stderr, "A setmarks failed\n");
+        exit (1);
+    }
+    Xnodeptr_list_free ((*handles)->this);
+
+    teeth_array = CC_SAFE_MALLOC (nteeth, Xnodeptr *);
+    if (!teeth_array) {
+        fprintf (stderr, "out of memory in Xcombfluff\n");
+        exit (1);
+    }
+
+    for (np = *teeth, i = 0; np; np = np->next, i++) {
+        teeth_array[i] = np->this;
+    }
+    Xnodeptrptr_list_free (*teeth);
+
+    for (i = 0; i < nteeth; i++) {
+        v = setmarks (G, in_tooth, teeth_array[i], -1, i);
+        if (v != SET_NOTEST) {
+            j = in_tooth[v];
+            if (setmarks (G, in_tooth, teeth_array[i], i, -1) != v ||
+                setmarks (G, in_tooth, teeth_array[j], j, -1) != SET_NOTEST) {
+                fprintf (stderr, "B setmarks failed\n");
+                exit (1);
+            }
+            if (in_hand[v]) {
+                setmarks (G, in_hand, teeth_array[i], SET_NOTEST, 0);
+                setmarks (G, in_hand, teeth_array[j], SET_NOTEST, 0);
+            } else {
+                setmarks (G, in_hand, teeth_array[i], SET_NOTEST, 1);
+                setmarks (G, in_hand, teeth_array[j], SET_NOTEST, 1);
+            }
+            Xnodeptr_list_free (teeth_array[i]);
+            Xnodeptr_list_free (teeth_array[j]);
+            teeth_array[i] = (Xnodeptr *) NULL;
+            teeth_array[j] = (Xnodeptr *) NULL;
+        }
+    }
+    *teeth = (Xnodeptrptr *) NULL;
+    for (i = 0, newteeth = 0; i < nteeth; i++) {
+        if (teeth_array[i]) {
+            if (check_cavity (G, teeth_array[i], in_hand)) {
+                newteeth++;
+                Xadd_nodeptrptr (teeth, teeth_array[i]);
+            } else {
+                Xnodeptr_list_free (teeth_array[i]);
+                teeth_array[i] = (Xnodeptr *) NULL;
+            }
+        }
+    }
+
+    if (newteeth > 1 && (((!cliquetest && (newteeth & 1) == 1)) ||
+                           (cliquetest && (newteeth & 1) == 0))) {
+        p = (Xnodeptr *) NULL;
+        for (i = 0; i < G->nnodes; i++) {
+            if (in_hand[i]) {
+                Xadd_nodeptr (&p, &(G->nodelist[i]));
+            }
+        }
+        *handles = (Xnodeptrptr *) NULL;
+        Xadd_nodeptrptr (handles, p);
+        CC_FREE (in_hand, int);
+        CC_FREE (in_tooth, int);
+        CC_FREE (teeth_array, Xnodeptr *);
+        return 1;
+    } else {
+        for (np = *teeth; np; np = np->next) {
+            Xnodeptr_list_free (np->this);
+        }
+        Xnodeptrptr_list_free (*teeth);
+        *teeth = (Xnodeptrptr *) NULL;
+        *handles = (Xnodeptrptr *) NULL;
+        CC_FREE (in_hand, int);
+        CC_FREE (in_tooth, int);
+        CC_FREE (teeth_array, Xnodeptr *);
+        /* printf ("FF Fluff Comb\n"); */
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int setmarks (Xgraph *G, int *vec, Xnodeptr *p, int from, int to)
+#else
+static int setmarks (G, vec, p, from, to)
+Xgraph *G;
+int *vec;
+Xnodeptr *p;
+int from, to;
+#endif
+{
+    if (from == SET_NOTEST) {
+        while (p) {
+            vec[p->this - G->nodelist] = to;
+            p = p->next;
+        }
+    } else {
+        while (p) {
+            if (vec[p->this - G->nodelist] != from) {
+                return p->this - G->nodelist;
+            }
+            vec[p->this - G->nodelist] = to;
+            p = p->next;
+        }
+    }
+    return SET_NOTEST;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_cavity (Xgraph *G, Xnodeptr *p, int *vec)
+#else
+static int check_cavity (G, p, vec)
+Xgraph *G;
+Xnodeptr *p;
+int *vec;
+#endif
+{
+    int got_hand = 0;
+    int got_cavity = 0;
+
+    while (p) {
+        if (vec[p->this - G->nodelist]) {
+            if (got_cavity)
+                return 1;
+            got_hand++;
+        } else {
+            if (got_hand)
+                return 1;
+            got_cavity++;
+        }
+        p = p->next;
+    }
+    return 0;
+}
+
+#define HANDLE 1
+#define TOOTH1 2
+#define TOOTH2 4
+#define TOOTH3 8
+#define NREGIONS 16
+
+#ifdef CC_PROTOTYPE_ANSI
+static int verify_13 (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth)
+#else
+static int verify_13 (G, handles, teeth)
+Xgraph *G;
+Xnodeptrptr *handles;
+Xnodeptrptr *teeth;
+#endif
+{
+    unsigned int *node_stat;
+    unsigned int flip;
+    unsigned int hist[NREGIONS];
+    unsigned int hist2[NREGIONS];
+    int i;
+    Xnodeptr *p;
+    Xnodeptrptr *pp;
+    int nhand;
+    int nteeth;
+
+    node_stat = CC_SAFE_MALLOC (G->nnodes, unsigned int);
+    if (!node_stat) {
+        fprintf (stderr, "out of memory in verify_13\n");
+        exit (1);
+    }
+
+    for (i = 0; i < G->nnodes; i++) {
+        node_stat[i] = 0;
+    }
+    for (pp = handles, nhand = 0; pp; pp = pp->next, nhand++) {
+        for (p = pp->this; p; p = p->next) {
+            node_stat[p->this - G->nodelist] |= (1 << nhand);
+        }
+    }
+    for (pp = teeth, nteeth = 0; pp; pp = pp->next, nteeth++) {
+        for (p = pp->this; p; p = p->next) {
+            node_stat[p->this - G->nodelist] |= 1 << (nhand + nteeth);
+        }
+    }
+    if (nhand != 1 || nteeth != 3) {
+        CC_FREE (node_stat, unsigned int);
+        return 0;
+    }
+    for (i = 0; i < NREGIONS; i++) {
+        hist[i] = 0;
+    }
+    for (i = 0; i < G->nnodes; i++) {
+        hist[node_stat[i]]++;
+    }
+    for (flip = 0; flip < NREGIONS; flip++) {
+        for (i = 0; i < NREGIONS; i++) {
+            hist2[i] = hist[i ^ flip];
+        }
+        if (Xhistok (hist2)) {
+            CC_FREE (node_stat, unsigned int);
+            return 1;
+        }
+    }
+    CC_FREE (node_stat, unsigned int);
+    /* printf ("CC Verify special failed to find a good flip\n"); */
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xhistok (unsigned int *hist)
+#else
+int Xhistok (hist)
+unsigned int *hist;
+#endif
+{
+    if (!hist[TOOTH1])
+        return 0;               /* tooth 1 has a cavity */
+    if (!hist[TOOTH2])
+        return 0;               /* tooth 2 has a cavity */
+    if (!hist[TOOTH3])
+        return 0;               /* tooth 3 has a cavity */
+    if (!hist[TOOTH1 | HANDLE])
+        return 0;               /* tooth 1 intersects the handle */
+    if (!hist[TOOTH2 | HANDLE])
+        return 0;               /* tooth 1 intersects the handle */
+    if (!hist[TOOTH3 | HANDLE])
+        return 0;               /* tooth 1 intersects the handle */
+    if (hist[TOOTH1 | TOOTH2] ||/* Nothing else happens */
+        hist[TOOTH1 | TOOTH3] ||
+        hist[TOOTH2 | TOOTH3] ||
+        hist[TOOTH1 | TOOTH2 | TOOTH3] ||
+        hist[TOOTH1 | TOOTH2 | HANDLE] ||
+        hist[TOOTH1 | TOOTH3 | HANDLE] ||
+        hist[TOOTH2 | TOOTH3 | HANDLE] ||
+        hist[TOOTH1 | TOOTH2 | TOOTH3 | HANDLE]) {
+        return 0;
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcheckclique (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth)
+#else
+int Xcheckclique (G, handles, teeth)
+Xgraph *G;
+Xnodeptrptr *handles, *teeth;
+#endif
+{
+    return checkclique_work (G, handles, teeth, 0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkclique_work (Xgraph *G, Xnodeptrptr *handles,
+                             Xnodeptrptr *teeth, int flipped)
+#else
+static int checkclique_work (G, handles, teeth, flipped)
+Xgraph *G;
+Xnodeptrptr *handles, *teeth;
+int flipped;
+#endif
+{
+    int nteeth, nhandles, nonpendant, hit, cavity, inhit;
+    Xnodeptr *np, *mp, *newtooth;
+    Xnodeptrptr *ntp, *mtp, *nonpendant_teeth, *pendant_teeth;
+    Xnodeptrptr *newhandles, *newteeth;
+    int special13, rval;
+
+    for (nteeth = 0, ntp = teeth; ntp; ntp = ntp->next)
+        nteeth++;
+    if (nteeth % 2 == 0) {
+        /* printf ("CC Even Number of Teeth: %d\n", nteeth); */
+        return 0;
+    }
+    for (nhandles = 0, ntp = handles; ntp; ntp = ntp->next)
+        nhandles++;
+
+    if (nhandles == 0) {
+        /* printf ("CC No Handles\n"); */
+        return 0;
+    }
+    if (nhandles == 1 && nteeth == 3)
+        special13 = 1;
+    else
+        special13 = 0;
+
+
+    /* EASY STUFF - Emtpy cliques, bad node numbers, etc. */
+
+    for (ntp = handles; ntp; ntp = ntp->next) {
+        if (!ntp->this) {
+            /* printf ("CC Empty Handle\n"); */
+            return 0;
+        }
+        for (hit = 0, np = ntp->this; np; np = np->next) {
+            if ((np->this - G->nodelist) < 0 ||
+                (np->this - G->nodelist) >= G->nnodes) {
+                /* printf ("CC Invalid node number in handle\n"); */
+                return 0;
+            } else
+                hit++;
+        }
+        if (hit >= G->nnodes) {
+            /* printf ("CC Handle is entire graph\n"); */
+            return 0;
+        }
+    }
+
+    for (ntp = teeth; ntp; ntp = ntp->next) {
+        if (!ntp->this) {
+            /* printf ("CC Empty Tooth\n"); */
+            return 0;
+        }
+        for (hit = 0, np = ntp->this; np; np = np->next) {
+            if ((np->this - G->nodelist) < 0 ||
+                (np->this - G->nodelist) >= G->nnodes) {
+                /* printf ("CC Invalid node number in tooth\n"); */
+                return 0;
+            } else
+                hit++;
+        }
+        if (hit >= G->nnodes) {
+            /* printf ("CC Tooth is entire graph\n"); */
+            return 0;
+        }
+    }
+
+    /* HANDLES SHOULD NEVER INTERSECT */
+
+    G->magicnum++;
+    for (ntp = handles; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum) {
+                if (special13)
+                    return verify_13 (G, handles, teeth);
+                else {
+                    /* printf ("CC Handles Meet\n"); */
+                    return 0;
+                }
+            } else
+                np->this->magiclabel = G->magicnum;
+
+
+    /* INSIST THAT EVERY TOOTH HAVE A CAVITY, UNLESS WE HAVE THE 1-3 */
+    /* CASE, WHERE WE ALLOW THE INVERTED TOOTH TO HAVE NO CAVITY.    */
+
+    for (ntp = teeth; ntp; ntp = ntp->next) {
+        cavity = inhit = 0;
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel != G->magicnum)
+                cavity++;
+            else
+                inhit++;
+        if (!cavity || !inhit) {
+            if (special13)
+                return verify_13 (G, handles, teeth);
+            else {
+                /* printf ("CC Tooth has no cavity\n"); */
+                return 0;
+            }
+        }
+    }
+
+    /* EVERY HANDLE HITS AN ODD NUMBER OF TEETH */
+
+    for (ntp = handles; ntp; ntp = ntp->next) {
+        G->magicnum++;
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+        for (hit = 0, mtp = teeth; mtp; mtp = mtp->next)
+            for (mp = mtp->this; mp; mp = mp->next)
+                if (mp->this->magiclabel == G->magicnum) {
+                    hit++;
+                    break;
+                }
+        if (hit % 2 == 0) {
+            if (special13)
+                return verify_13 (G, handles, teeth);
+            else {
+                /* printf ("CC Handle hits even num of teeth\n"); */
+                return 0;
+            }
+        }
+    }
+
+    /* TEETH IN COMBS CANNOT INTERSECT UNLESS 1-3 CASE */
+
+    if (nhandles == 1) {
+        G->magicnum++;
+        for (ntp = teeth; ntp; ntp = ntp->next) {
+            for (np = ntp->this; np; np = np->next) {
+                if (np->this->magiclabel == G->magicnum) {
+                    if (special13)
+                        return verify_13 (G, handles, teeth);
+                    else {
+                        /* printf ("CC Teeth in Comb\n"); */
+                        return 0;
+                    }
+/*
+                }
+*/
+
+                } else {
+                    np->this->magiclabel = G->magicnum;
+                }
+
+
+/******************** BUG *************************************
+  SHOULD HAVE:  } else {
+                    np->this->magiclabel = G->magicnum;
+                }
+**************************************************************/
+
+            }
+        }
+        return 1;
+    }
+    /* Deal with a multihandled cliquetree by finding a handle to */
+    /* delete and check that the remainder is a valid cliquetree. */
+
+
+    nonpendant_teeth = (Xnodeptrptr *) NULL;
+    pendant_teeth = (Xnodeptrptr *) NULL;
+    nonpendant = 0;
+    for (ntp = teeth; ntp; ntp = ntp->next) {
+        G->magicnum++;
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+        for (mtp = handles, hit = 0; mtp && hit < 2; mtp = mtp->next)
+            for (np = mtp->this; np; np = np->next)
+                if (np->this->magiclabel == G->magicnum) {
+                    hit++;
+                    break;
+                }
+        if (hit >= 2) {
+            nonpendant++;
+            Xadd_nodeptrptr (&nonpendant_teeth, ntp->this);
+        } else
+            Xadd_nodeptrptr (&pendant_teeth, ntp->this);
+    }
+
+    if (nonpendant > nhandles - 1) {
+        /*
+        printf ("CC %d handles, but %d nonpendant teeth\n",
+                    nhandles, nonpendant);
+        */
+        Xnodeptrptr_list_free (nonpendant_teeth);
+        Xnodeptrptr_list_free (pendant_teeth);
+        Xprintcliquetree (G, handles, teeth);
+        return 0;
+    }
+    for (ntp = handles; ntp; ntp = ntp->next) {
+        G->magicnum++;
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+        for (mtp = nonpendant_teeth, hit = 0; mtp && hit < 2; mtp = mtp->next)
+            for (np = mtp->this; np; np = np->next)
+                if (np->this->magiclabel == G->magicnum) {
+                    hit++;
+                    break;
+                }
+        if (!hit) {
+            /* printf ("CC Handle meets no nonpendant tooth\n"); */
+            Xnodeptrptr_list_free (nonpendant_teeth);
+            Xnodeptrptr_list_free (pendant_teeth);
+            return 0;
+        } else if (hit == 1) {
+            if (check_for_intersecting_teeth (G, ntp->this, teeth)) {
+                get_smaller_cliquetree (G, &newhandles, &newteeth,
+                                        handles, teeth, ntp->this);
+                rval = checkclique_work (G, newhandles, newteeth, flipped);
+                Xnodeptrptr_list_free (nonpendant_teeth);
+                Xnodeptrptr_list_free (pendant_teeth);
+                Xnodeptrptr_list_free (newhandles);
+                Xnodeptrptr_list_free (newteeth);
+                if (!rval) {
+                    printf ("CC Bad Recursion\n");
+                    Xprintcliquetree (G, handles, teeth);
+                    fflush (stdout);
+                }
+                return rval;
+            }
+        }
+    }
+
+    if (nhandles > 2) {
+        /* printf ("CC No good handle (%d) to reduce\n", nhandles); */
+    }
+
+    /* TRY FLIPPING THE NONPENDANT TOOTH IN TWO HANDLED CASE */
+
+    if (nhandles == 2 && !flipped) {
+        complement_nodeptrlist (G, nonpendant_teeth->this, &newtooth);
+        Xadd_nodeptrptr (&pendant_teeth, newtooth);
+        rval = checkclique_work (G, handles, pendant_teeth, 1);
+        Xnodeptr_list_free (newtooth);
+        Xnodeptrptr_list_free (nonpendant_teeth);
+        Xnodeptrptr_list_free (pendant_teeth);
+        if (rval) {
+            /* printf ("CC Needed to Flip the nonpendant tooth.\n"); */
+        } else {
+            /* printf ("CC FLIP DID NOT HELP\n"); */
+        }
+        return rval;
+    } else {
+        Xnodeptrptr_list_free (nonpendant_teeth);
+        Xnodeptrptr_list_free (pendant_teeth);
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void complement_nodeptrlist (Xgraph *G, Xnodeptr *list, Xnodeptr **new)
+#else
+static void complement_nodeptrlist (G, list, new)
+Xgraph *G;
+Xnodeptr *list, **new;
+#endif
+{
+    Xnodeptr *np;
+    int i;
+    Xnode *n;
+
+    *new = (Xnodeptr *) NULL;
+    G->magicnum++;
+    for (np = list; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (i = G->nnodes, n = G->nodelist; i; i--, n++)
+        if (n->magiclabel != G->magicnum)
+            Xadd_nodeptr (new, n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void get_smaller_cliquetree (Xgraph *G, Xnodeptrptr **newhandles,
+    Xnodeptrptr **newteeth, Xnodeptrptr *handles, Xnodeptrptr *teeth,
+    Xnodeptr *specialhandle)
+#else
+static void get_smaller_cliquetree (G, newhandles, newteeth, handles,
+    teeth, specialhandle)
+Xgraph *G;
+Xnodeptrptr **newhandles, **newteeth, *handles, *teeth;
+Xnodeptr *specialhandle;
+#endif
+{
+    Xnodeptrptr *ntp, *mtp;
+    Xnodeptr *np;
+    int hit;
+
+    *newhandles = (Xnodeptrptr *) NULL;
+    for (ntp = handles; ntp; ntp = ntp->next)
+        if (ntp->this != specialhandle)
+            Xadd_nodeptrptr (newhandles, ntp->this);
+    *newteeth = (Xnodeptrptr *) NULL;
+    for (ntp = teeth; ntp; ntp = ntp->next) {
+        G->magicnum++;
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+        for (mtp = *newhandles, hit = 0; mtp && !hit; mtp = mtp->next) {
+            for (np = mtp->this; np; np = np->next)
+                if (np->this->magiclabel == G->magicnum) {
+                    hit++;
+                    break;
+                }
+        }
+        if (hit)
+            Xadd_nodeptrptr (newteeth, ntp->this);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_for_intersecting_teeth (Xgraph *G, Xnodeptr *handle,
+                                         Xnodeptrptr *teeth)
+#else
+static int check_for_intersecting_teeth (G, handle, teeth)
+Xgraph *G;
+Xnodeptr *handle;
+Xnodeptrptr *teeth;
+#endif
+{
+    Xnodeptrptr *ntp;
+    Xnodeptr *np;
+    Xnodeptrptr *handle_teeth;
+
+    G->magicnum++;
+    for (np = handle; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    handle_teeth = (Xnodeptrptr *) NULL;
+    for (ntp = teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum) {
+                Xadd_nodeptrptr (&handle_teeth, ntp->this);
+                break;
+            }
+    G->magicnum++;
+    for (ntp = handle_teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            if (np->this->magiclabel == G->magicnum) {
+                Xnodeptrptr_list_free (handle_teeth);
+                return 0;
+            } else
+                np->this->magiclabel = G->magicnum;
+
+    Xnodeptrptr_list_free (handle_teeth);
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcleancomb (Xgraph *G, Xnodeptr **handle, Xnodeptrptr **teeth,
+                int *nteeth, double *x)
+#else
+void Xcleancomb (G, handle, teeth, nteeth, x)
+Xgraph *G;
+Xnodeptr **handle;
+Xnodeptrptr **teeth;
+int *nteeth;
+double *x;
+#endif
+{
+    int *degree;
+    Xnodeptrptr *newteeth, *ntp, *newtp;
+
+    /* The cleaned comb goes back into handle and teeth. */
+
+    if (x == (double *) NULL)
+        return;
+
+    newteeth = (Xnodeptrptr *) NULL;
+
+    degree = CC_SAFE_MALLOC (G->nnodes, int);
+    if (!degree) {
+        fprintf (stderr, "out of memory in cleancomb\n");
+        exit (1);
+    }
+    for (ntp = *teeth; ntp; ntp = ntp->next) {
+        newtp = Xnodeptrptralloc ();
+        newtp->this = (Xnodeptr *) NULL;
+        newtp->next = newteeth;
+        newteeth = newtp;
+        clean_tooth (G, *handle, ntp->this, &(newtp->this), x, degree);
+    }
+
+    Xfreeteeth (*teeth);
+
+    *teeth = newteeth;
+
+    clean_handle (G, handle, teeth, nteeth, degree, x);
+
+    CC_FREE (degree, int);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clean_handle (Xgraph *G, Xnodeptr **handle, Xnodeptrptr **teeth,
+                          int *nteeth, int *degree, double *x)
+#else
+static void clean_handle (G, handle, teeth, nteeth, degree, x)
+Xgraph *G;
+Xnodeptr **handle;
+Xnodeptrptr **teeth;
+int *nteeth, *degree;
+double *x;
+#endif
+{
+    Xnodeptr *np, *toss = (Xnodeptr *) NULL;
+    Xnodeptrptr *ntp;
+    Xnodeptr *tooth1, *tooth2, *newhandle;
+    Xnode *n, *n1;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    if (!clean_handle_connect (G, *handle, x))
+        return;
+
+    G->magicnum++;
+    for (np = *handle; np; np = np->next) {
+        np->this->magiclabel = G->magicnum;
+        degree[np->this - G->nodelist] = 0;
+    }
+    for (np = *handle; np; np = np->next) {
+        n = np->this;
+        for (ep = n->adj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (x[e - G->edgelist] > .9999 &&
+                e->ends[0]->magiclabel == G->magicnum &&
+                e->ends[1]->magiclabel == G->magicnum)
+                (degree[n - G->nodelist])++;
+        }
+    }
+    for (ntp = *teeth; ntp; ntp = ntp->next)
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum - 1;
+
+    for (np = *handle; np; np = np->next) {
+        n = np->this;
+        if (degree[n - G->nodelist] != 2 || n->magiclabel != G->magicnum)
+            continue;
+        for (ep = n->adj.head; ep; ep = ep->next) {
+            e = ep->this;
+            n1 = OTHEREND (e, n);
+            if (x[e - G->edgelist] > .9999 &&
+                n1->magiclabel == G->magicnum &&
+                degree[n1 - G->nodelist] == 2) {
+                Xadd_nodeptr (&toss, n);
+                Xadd_nodeptr (&toss, n1);
+                degree[n - G->nodelist] = 0;
+                degree[n1 - G->nodelist] = 0;
+                clean_stretch (G, n, n1, &toss, &tooth1, degree, x);
+                clean_stretch (G, n1, n, &toss, &tooth2, degree, x);
+                Xadd_nodeptrptr (teeth, tooth1);
+                Xadd_nodeptrptr (teeth, tooth2);
+                (*nteeth) += 2;
+                break;
+            }
+        }
+    }
+    G->magicnum++;
+    for (np = toss; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    Xnodeptr_list_free (toss);
+
+    newhandle = (Xnodeptr *) NULL;
+    for (np = *handle; np; np = np->next)
+        if (np->this->magiclabel != G->magicnum)
+            Xadd_nodeptr (&newhandle, np->this);
+    Xnodeptr_list_free (*handle);
+    *handle = newhandle;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clean_stretch (Xgraph *G, Xnode *a, Xnode *b, Xnodeptr **toss,
+                           Xnodeptr **tooth, int *degree, double *x)
+#else
+static void clean_stretch (G, a, b, toss, tooth, degree, x)
+Xgraph *G;
+Xnode *a, *b;
+Xnodeptr **toss, **tooth;
+int *degree;
+double *x;
+#endif
+{
+    Xnode *c;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    for (ep = a->adj.head; ep; ep = ep->next) {
+        e = ep->this;
+        if (x[e - G->edgelist] > .9999 && ((c = OTHEREND (e, a)) != b)) {
+            if (degree[c - G->nodelist] == 2 &&
+                c->magiclabel == G->magicnum) {
+                Xadd_nodeptr (toss, c);
+                degree[c - G->nodelist] = 0;
+                clean_stretch (G, c, a, toss, tooth, degree, x);
+            } else {
+                *tooth = (Xnodeptr *) NULL;
+                Xadd_nodeptr (tooth, a);
+                Xadd_nodeptr (tooth, c);
+            }
+            return;
+        }
+    }
+    printf ("ERROR IN CLEAN_STRETCH\n");
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clean_tooth (Xgraph *G, Xnodeptr *handle, Xnodeptr *tooth,
+                         Xnodeptr **newtooth, double *x, int *degree)
+#else
+static void clean_tooth (G, handle, tooth, newtooth, x, degree)
+Xgraph *G;
+Xnodeptr *handle, *tooth, **newtooth;
+double *x;
+int *degree;
+#endif
+{
+    Xnodeptr *np, *np1, *toss;
+    Xnode *n;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    G->magicnum++;
+    for (np = tooth; np; np = np->next) {
+        degree[np->this - G->nodelist] = 0;
+        np->this->magiclabel = G->magicnum;
+    }
+
+    for (np = tooth; np; np = np->next) {
+        n = np->this;
+        for (ep = n->adj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (x[e - G->edgelist] > XEPSILON &&
+                e->ends[0]->magiclabel == e->ends[1]->magiclabel)
+                (degree[n - G->nodelist])++;
+        }
+    }
+
+    G->magicnum++;
+    for (np = handle; np; np = np->next) {
+        np->this->magiclabel = G->magicnum;
+    }
+
+    toss = (Xnodeptr *) NULL;
+
+    for (np = tooth; np; np = np->next) {
+        n = np->this;
+        if (n->magiclabel == G->magicnum - 1 && degree[n - G->nodelist] == 1)
+            process_clean_tooth_node (G, n, x, degree, &toss);
+    }
+    G->magicnum++;
+
+    for (np = toss; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    Xnodeptr_list_free (toss);
+
+    *newtooth = (Xnodeptr *) NULL;
+    for (np = tooth; np; np = np->next)
+        if (np->this->magiclabel != G->magicnum) {
+            np1 = Xnodeptralloc ();
+            np1->this = np->this;
+            np1->next = *newtooth;
+            *newtooth = np1;
+        }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void process_clean_tooth_node (Xgraph *G, Xnode *n, double *x,
+                                      int *degree, Xnodeptr **toss)
+#else
+static void process_clean_tooth_node (G, n, x, degree, toss)
+Xgraph *G;
+Xnode *n;
+double *x;
+int *degree;
+Xnodeptr **toss;
+#endif
+{
+    Xedgeptr *ep;
+    Xedge *e;
+    Xnodeptr *np;
+    Xnode *n1;
+    double t;
+
+    for (ep = n->adj.head; ep; ep = ep->next) {
+        e = ep->this;
+        t = x[e - G->edgelist];
+        if (t > XEPSILON &&
+            e->ends[0]->magiclabel == e->ends[1]->magiclabel) {
+            if (t > 0.9999) {
+                np = Xnodeptralloc ();
+                np->this = n;
+                np->next = *toss;
+                *toss = np;
+                n->magiclabel = G->magicnum - 2;
+                n1 = OTHEREND (e, n);
+                if (degree[n1 - G->nodelist] == 2)
+                    process_clean_tooth_node (G, n1, x, degree, toss);
+            }
+            return;
+        }
+    }
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int clean_handle_connect (Xgraph *G, Xnodeptr *handle, double *x)
+#else
+static int clean_handle_connect (G, handle, x)
+Xgraph *G;
+Xnodeptr *handle;
+double *x;
+#endif
+{
+    Xnodeptr *np;
+
+    if (handle == (Xnodeptr *) NULL)
+        return 0;
+
+    G->magicnum++;
+    for (np = handle; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    clean_handle_connect_dfs (G, handle->this, x, G->magicnum);
+
+    for (np = handle; np; np = np->next)
+        if (np->this->magiclabel == G->magicnum)
+            return 0;
+
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clean_handle_connect_dfs (Xgraph *G, Xnode *start, double *x, int k)
+#else
+static void clean_handle_connect_dfs (G, start, x, k)
+Xgraph *G;
+Xnode *start;
+double *x;
+int k;
+#endif
+{
+    Xedgeptr *ep;
+    Xedge *e;
+    Xnode *n, *n1;
+    Xnodeptr *next, *queue = (Xnodeptr *) NULL;
+
+    start->magiclabel = k - 1;
+    Xadd_nodeptr (&queue, start);
+
+    while (queue) {
+        n = queue->this;
+        next = queue->next;
+        Xnodeptrfree (queue);
+        queue = next;
+
+        for (ep = n->adj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (x[e - G->edgelist] > 0.005) {
+                n1 = OTHEREND (e, n);
+                if (n1->magiclabel == k) {
+                    n1->magiclabel = k - 1;
+                    Xadd_nodeptr (&queue, n1);
+                }
+            }
+        }
+    }
+}
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xclique.c b/contrib/blossom/concorde97/XSTUFF/Xclique.c
new file mode 100644
index 0000000000000000000000000000000000000000..a89741e0863c65d52da9832800d94520d15024fc
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xclique.c
@@ -0,0 +1,1174 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*  int                                                                   */
+/*      Xcliquetree (Xgraph *G, Xcplane **list, double *x),               */
+/*      Xcliquetree_work (Xgraph *G, Xcplane **list, int pseudo,          */
+/*                        double *x, int type_of_grow)                    */
+/*                                                                        */
+/**************************************************************************/
+
+
+#include "machdefs.h"
+#include "Xsubtour.h"
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    split_T (Xgraph *G, Xnodeptr *T, Xnodeptr *U, Xnodeptr **u1,
+          Xnodeptr **u2, Xnodeptr **u3, Xnodeptr **u4, Xnodeptr **u5),
+    clique_dfs (Xgraph *G, Xnode *start, int z, int storenodes,
+          Xnodeptr **list),
+    unscan_remove (Xgraph *G, Xedgeptr **unscan, Xnodeptr *T),
+    remove_from_nodeptr (Xnode *n, Xnodeptr **list),
+    add_nodeptr_list (Xnodeptr **addto, Xnodeptr *takefrom),
+    label_nodeptr_list (Xnodeptr *list, int z),
+    pseudonodelist_to_nodelist (Xnodeptr *p, Xnodeptr **l);
+
+static int
+    clique_setup (Xgraph *G, int ct, Xnodeptr **u1, Xnodeptr **u2,
+          Xnodeptr **u3, Xnodeptr **u4, Xnodeptr **u5, int type_of_grow),
+    process_T (Xgraph *G, Xnodeptr **T, Xedge *e, Xnodeptr *U,
+          Xnodeptr **u1, Xnodeptr **u2, int type_of_grow),
+    grow (Xgraph *G, Xnodeptr **T, Xedge *e, Xnodeptr *U),
+    grow2 (Xgraph *G, Xnodeptr **T, Xedge *e, Xnodeptr *U),
+    grabcomponents (Xgraph *G, int z, Xnodeptr *T, Xnodeptr *U,
+          Xnodeptr **u1, Xnodeptr **u2),
+    improve (Xgraph *G, Xnodeptr **u1, Xnodeptr **u2, Xnodeptr **u3,
+          Xnodeptr **u4, Xnodeptr **u5),
+    grab_from_u5 (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2, Xnodeptr *u3,
+          Xnodeptr *u4, Xnodeptr *u5, Xnodeptr **pick, Xnode **v),
+    grab_from_mate (Xgraph *G, Xnodeptr *mate, Xnodeptr *u3,
+          Xnodeptr *u4, Xnodeptr *u5, Xnode **w),
+    clique_violated (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2,
+           Xnodeptr *u3, Xnodeptr *u4, Xnodeptr *u5),
+    clique_fringe (Xnode *n, int ct),
+    check_special_cliquetree (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2,
+           Xnodeptr *u3, Xnodeptr *u4, Xnodeptr *u5, Xcplane **list, double *x),
+    load_special_cliquetree (Xgraph *G, Xnodeptr *H1, Xnodeptr *H2,
+           Xnodeptr *T, Xedgeptr *pteeth, Xcplane **list, double *x);
+
+static double
+    crossvalue (Xgraph *G, Xnodeptr *s1, Xnodeptr *s2, Xnodeptr *s3),
+    single_crossvalue (Xgraph *G, Xnode *v, Xnodeptr *s1,
+           Xnodeptr *s2, Xnodeptr *s3),
+    clique_slack (Xgraph *G, Xnodeptr *s);
+
+static Xnode
+    *best_w (Xgraph *G, Xnodeptr *T, Xnodeptr *ui, Xnode *hitter);
+
+#else
+
+static void
+    split_T (),
+    clique_dfs (),
+    unscan_remove (),
+    remove_from_nodeptr (),
+    add_nodeptr_list (),
+    label_nodeptr_list (),
+    pseudonodelist_to_nodelist ();
+
+static int
+    clique_setup (),
+    process_T (),
+    grow (),
+    grow2 (),
+    grabcomponents (),
+    improve (),
+    grab_from_u5 (),
+    grab_from_mate (),
+    clique_violated (),
+    clique_fringe (),
+    check_special_cliquetree (),
+    load_special_cliquetree ();
+
+static double
+    crossvalue (),
+    single_crossvalue (),
+    clique_slack ();
+
+static Xnode
+    *best_w ();
+
+#endif
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    nodeptr_print (Xgraph *G, Xnodeptr *s),
+    dump_special_cliquetree (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2,
+          Xnodeptr *u3, Xnodeptr *u4, Xnodeptr *u5);
+#else
+static void
+    nodeptr_print (),
+    dump_special_cliquetree ();
+#endif
+#endif
+
+#define ONEMINUS 0.999999
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcliquetree (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xcliquetree (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    int hit = 0;
+
+    hit += Xcliquetree_work (G, list, 0, x, 0);
+    if (hit < XCUTNUM)
+        hit += Xcliquetree_work (G, list, 0, x, 1);
+
+    return hit;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcliquetree_work (Xgraph *G, Xcplane **list, int pseudo, double *x,
+     int type_of_grow)
+#else
+int Xcliquetree_work (G, list, pseudo, x, type_of_grow)
+Xgraph *G;
+Xcplane **list;
+int pseudo;
+double *x;
+int type_of_grow;
+#endif
+{
+    int ncomponents, ct, hit, roll, realcount = 0;
+    Xnodeptr *u1, *u2, *u3, *u4, *u5;
+
+    if (!pseudo) {
+        Xloadx (G, x);
+        Xbuildpseudonodelist (G, 0);
+    }
+    ncomponents = XTmark_components (G);
+    for (ct = 1; ct <= ncomponents; ct++) {
+        u1 = u2 = u3 = u4 = u5 = (Xnodeptr *) NULL;
+        if (!clique_setup (G, ct, &u1, &u2, &u3, &u4, &u5, type_of_grow))
+            continue;
+        hit = 0;
+        do {
+            roll = improve (G, &u1, &u2, &u3, &u4, &u5);
+            if (clique_violated (G, u1, u2, u3, u4, u5))
+                hit = 1;
+        } while (!hit && roll);
+        if (hit) {
+            realcount +=
+                check_special_cliquetree (G, u1, u2, u3, u4, u5, list, x);
+        }
+        Xnodeptr_list_free (u1);
+        Xnodeptr_list_free (u2);
+        Xnodeptr_list_free (u3);
+        Xnodeptr_list_free (u4);
+        Xnodeptr_list_free (u5);
+    }
+
+    if (!pseudo) {
+        Xdestroypseudonodelist (G);
+        /* printf ("%d clique trees\n", realcount); */
+    }
+
+    return realcount;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int clique_setup (Xgraph *G, int ct, Xnodeptr **u1, Xnodeptr **u2,
+            Xnodeptr **u3, Xnodeptr **u4, Xnodeptr **u5, int type_of_grow)
+#else
+static int clique_setup (G, ct, u1, u2, u3, u4, u5, type_of_grow)
+Xgraph *G;
+int ct;
+Xnodeptr **u1, **u2, **u3, **u4, **u5;
+int type_of_grow;
+#endif
+{
+    Xnodeptr *np, *tp, *U = (Xnodeptr *) NULL, *T;
+    Xnode *n;
+    Xedgeptr *ep, *unscan = (Xedgeptr *) NULL;
+    Xedge *e;
+    int i, k;
+
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        n->mark = 0;
+        if (n->Tmark == ct || clique_fringe (n, ct)) {
+            tp = Xnodeptralloc ();
+            tp->this = n;
+            tp->next = U;
+            U = tp;
+        }
+    }
+    G->magicnum++;
+    for (k = 0, np = U; np; np = np->next) {
+        np->this->magiclabel = G->magicnum;
+        k++;
+    }
+    if (k < 7) {
+        Xnodeptr_list_free (U);
+        return 0;
+    }
+    for (k = 0, np = U; np; np = np->next) {
+        n = np->this;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->x > ONEMINUS &&
+                OTHERCURRENTEND (e, n)->magiclabel != G->magicnum) {
+                n->mark = 1;
+                k++;
+            }
+        }
+    }
+
+    if (k < 4) {
+        Xnodeptr_list_free (U);
+        return 0;
+    }
+    if (k % 2) {
+        Xnodeptr_list_free (U);
+        return 0;
+    }
+    for (i = G->nedges, e = G->edgelist; i; i--, e++)
+        if (e->stay && e->cends[0]->magiclabel == G->magicnum &&
+            e->cends[1]->magiclabel == G->magicnum &&
+            e->cends[0]->mark == 0 &&
+            e->cends[1]->mark == 0) {
+            ep = Xedgeptralloc ();
+            ep->this = e;
+            ep->next = unscan;
+            unscan = ep;
+        }
+    while (unscan) {
+        e = unscan->this;
+        ep = unscan;
+        unscan = unscan->next;
+        Xedgeptrfree (ep);
+        if (process_T (G, &T, e, U, u1, u2, type_of_grow)) {
+            split_T (G, T, U, u1, u2, u3, u4, u5);
+            Xnodeptr_list_free (U);
+            Xnodeptr_list_free (T);
+            Xedgeptr_list_free (unscan);
+            return 1;
+        } else {
+            unscan_remove (G, &unscan, T);
+            Xnodeptr_list_free (T);
+        }
+    }
+    Xnodeptr_list_free (U);
+    Xedgeptr_list_free (unscan);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void split_T (Xgraph *G, Xnodeptr *T, Xnodeptr *U, Xnodeptr **u1,
+             Xnodeptr **u2, Xnodeptr **u3, Xnodeptr **u4, Xnodeptr **u5)
+#else
+static void split_T (G, T, U, u1, u2, u3, u4, u5)
+Xgraph *G;
+Xnodeptr *T, *U, **u1, **u2, **u3, **u4, **u5;
+#endif
+{
+    Xnodeptr *np, *tp, *next;
+    Xnode *n, *w1, *w2;
+
+    G->magicnum++;
+    for (np = T; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    for (np = *u1, *u1 = (Xnodeptr *) NULL; np; np = next) {
+        next = np->next;
+        if (np->this->magiclabel == G->magicnum)
+            Xnodeptrfree (np);
+        else {
+            np->next = *u1;
+            *u1 = np;
+        }
+    }
+    for (np = *u2, *u2 = (Xnodeptr *) NULL; np; np = next) {
+        next = np->next;
+        if (np->this->magiclabel == G->magicnum)
+            Xnodeptrfree (np);
+        else {
+            np->next = *u2;
+            *u2 = np;
+        }
+    }
+
+    w1 = best_w (G, T, *u1, (Xnode *) NULL);
+    np = Xnodeptralloc ();
+    np->this = w1;
+    np->next = (Xnodeptr *) NULL;
+    *u3 = np;
+
+    w2 = best_w (G, T, *u2, w1);
+    np = Xnodeptralloc ();
+    np->this = w2;
+    np->next = (Xnodeptr *) NULL;
+    *u4 = np;
+
+    G->magicnum++;
+    for (np = *u1; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (np = *u2; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (np = *u3; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (np = *u4; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    *u5 = (Xnodeptr *) NULL;
+    for (np = U; np; np = np->next) {
+        n = np->this;
+        if (n->magiclabel != G->magicnum) {
+            tp = Xnodeptralloc ();
+            tp->this = n;
+            tp->next = *u5;
+            *u5 = tp;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xnode *best_w (Xgraph *G, Xnodeptr *T, Xnodeptr *ui, Xnode *hitter)
+#else
+static Xnode *best_w (G, T, ui, hitter)
+Xgraph *G;
+Xnodeptr *T, *ui;
+Xnode *hitter;
+#endif
+{
+    Xnodeptr *np;
+    Xnode *n, *w = (Xnode *) NULL;
+    Xedgeptr *ep;
+    Xedge *e;
+    double adj, bestadj = -1.0;
+
+    G->magicnum++;
+    for (np = ui; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    for (np = T; np; np = np->next) {
+        n = np->this;
+        if (n == hitter)
+            continue;
+        adj = 0.0;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (OTHERCURRENTEND (e, n)->magiclabel ==
+                G->magicnum)
+                adj += e->x;
+        }
+        if (adj > bestadj) {
+            bestadj = adj;
+            w = n;
+        }
+    }
+    return w;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int process_T (Xgraph *G, Xnodeptr **T, Xedge *e, Xnodeptr *U,
+            Xnodeptr **u1, Xnodeptr **u2, int type_of_grow)
+#else
+static int process_T (G, T, e, U, u1, u2, type_of_grow)
+Xgraph *G;
+Xnodeptr **T;
+Xedge *e;
+Xnodeptr *U, **u1, **u2;
+int type_of_grow;
+#endif
+{
+    Xnodeptr *np;
+    Xnode *n;
+    Xedgeptr *ep;
+    Xedge *f;
+    int iU;
+
+    if (!type_of_grow) {
+        if (grow (G, T, e, U) < 3)
+            return 0;
+    } else {
+        if (grow2 (G, T, e, U) < 3)
+            return 0;
+    }
+
+    iU = ++(G->magicnum);
+    for (np = U; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    G->magicnum++;
+    for (np = *T; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    G->magicedgenum++;
+    for (np = U; np; np = np->next) {
+        n = np->this;
+        if (n->magiclabel == G->magicnum)
+            continue;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            f = ep->this;
+            if ((OTHERCURRENTEND (f, n))->magiclabel >= iU)
+                f->magiclabel = G->magicedgenum;
+        }
+    }
+    if (grabcomponents (G, G->magicedgenum, *T, U, u1, u2))
+        return 1;
+
+    iU = ++(G->magicnum);
+    for (np = U; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    G->magicnum++;
+    for (np = *T; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    G->magicedgenum++;
+    for (np = U; np; np = np->next) {
+        n = np->this;
+        if (n->magiclabel == G->magicnum)
+            continue;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            f = ep->this;
+            if ((OTHERCURRENTEND (f, n))->magiclabel == iU)
+                f->magiclabel = G->magicedgenum;
+        }
+    }
+
+    if (grabcomponents (G, G->magicedgenum, *T, U, u1, u2))
+        return 1;
+    else
+        return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grow (Xgraph *G, Xnodeptr **T, Xedge *e, Xnodeptr *U)
+#else
+static int grow (G, T, e, U)
+Xgraph *G;
+Xnodeptr **T;
+Xedge *e;
+Xnodeptr *U;
+#endif
+{
+    Xnodeptr *np, *tp;
+    Xnode *n;
+    Xedgeptr *ep;
+    Xedge *f;
+    int count, adcount, hit;
+    double adval;
+
+    np = Xnodeptralloc ();
+    tp = Xnodeptralloc ();
+    np->this = e->cends[0];
+    tp->this = e->cends[1];
+    np->next = (Xnodeptr *) NULL;
+    tp->next = np;
+    *T = tp;
+    count = 2;
+
+    G->magicnum++;
+    e->cends[0]->magiclabel = G->magicnum;
+    e->cends[1]->magiclabel = G->magicnum;
+
+    do {
+        hit = 0;
+        for (np = U; np; np = np->next) {
+            n = np->this;
+            if (n->magiclabel != G->magicnum && n->mark == 0) {
+                adcount = 0;
+                adval = 0.0;
+                for (ep = n->cadj.head; ep; ep = ep->next) {
+                    f = ep->this;
+                    if (OTHERCURRENTEND (f, n)->magiclabel
+                        == G->magicnum) {
+                        adcount++;
+                        adval += f->x;
+                    }
+                }
+                if (adcount >= 2 && adval >= 1.0) {
+                    tp = Xnodeptralloc ();
+                    tp->this = n;
+                    tp->next = *T;
+                    *T = tp;
+                    n->magiclabel = G->magicnum;
+                    hit++;
+                }
+            }
+        }
+        count += hit;
+    } while (hit);
+
+    return count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grow2 (Xgraph *G, Xnodeptr **T, Xedge *e, Xnodeptr *U)
+#else
+static int grow2 (G, T, e, U)
+Xgraph *G;
+Xnodeptr **T;
+Xedge *e;
+Xnodeptr *U;
+#endif
+{
+    Xnodeptr *np, *tp;
+    Xnode *n;
+    Xedgeptr *ep;
+    Xedge *f;
+    int count, hit;
+    double adval, slack;
+
+    np = Xnodeptralloc ();
+    tp = Xnodeptralloc ();
+    np->this = e->cends[0];
+    tp->this = e->cends[1];
+    np->next = (Xnodeptr *) NULL;
+    tp->next = np;
+    *T = tp;
+    count = 2;
+
+    G->magicnum++;
+    e->cends[0]->magiclabel = G->magicnum;
+    e->cends[1]->magiclabel = G->magicnum;
+    slack = 1.0 - e->x;
+
+    do {
+        hit = 0;
+        for (np = U; np; np = np->next) {
+            n = np->this;
+            if (n->magiclabel != G->magicnum && n->mark == 0) {
+                adval = 0.0;
+                for (ep = n->cadj.head; ep; ep = ep->next) {
+                    f = ep->this;
+                    if (OTHERCURRENTEND (f, n)->magiclabel
+                        == G->magicnum) {
+                        adval += f->x;
+                    }
+                }
+                if (slack + (1.0 - adval) < 0.5) {
+                    tp = Xnodeptralloc ();
+                    tp->this = n;
+                    tp->next = *T;
+                    *T = tp;
+                    n->magiclabel = G->magicnum;
+                    hit++;
+                    slack += (1.0 - adval);
+                }
+            }
+        }
+        count += hit;
+    } while (hit);
+
+    return count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grabcomponents (Xgraph *G, int z, Xnodeptr *T, Xnodeptr *U,
+            Xnodeptr **u1, Xnodeptr **u2)
+#else
+static int grabcomponents (G, z, T, U, u1, u2)
+Xgraph *G;
+int z;
+Xnodeptr *T, *U, **u1, **u2;
+#endif
+{
+    Xnodeptr *np, *tp, *all = (Xnodeptr *) NULL;
+    Xnode *n;
+    Xedgeptr *ep;
+    int componentcount, k;
+
+    G->magicnum++;
+    label_nodeptr_list (T, G->magicnum);
+
+    for (np = U; np; np = np->next) {
+        n = np->this;
+        if (n->magiclabel != G->magicnum)
+            Xadd_nodeptr (&all, n);
+        else
+            for (ep = n->cadj.head; ep; ep = ep->next)
+                if (ep->this->magiclabel == z) {
+                    Xadd_nodeptr (&all, n);
+                    break;
+                }
+    }
+    if (!all) {
+        printf ("Eak in grabcomponents\n");
+        return 0;
+    }
+    G->magicnum++;
+    componentcount = 0;
+    for (np = all; componentcount <= 2 && np; np = np->next)
+        if (np->this->magiclabel != G->magicnum) {
+            clique_dfs (G, np->this, z, 0, (Xnodeptr **) NULL);
+            componentcount++;
+        }
+    if (componentcount != 2) {
+        Xnodeptr_list_free (all);
+        return 0;
+    } else {
+        G->magicnum++;
+        *u1 = (Xnodeptr *) NULL;
+        clique_dfs (G, all->this, z, 1, u1);
+        for (k = 0, tp = *u1; tp; tp = tp->next) {
+            if (tp->this->mark)
+                k++;
+        }
+        if (k < 2 || k % 2 != 0) {
+            Xnodeptr_list_free (all);
+            Xnodeptr_list_free (*u1);
+            *u1 = (Xnodeptr *) NULL;
+            return 0;
+        }
+        np = all->next;
+        while (np->this->magiclabel == G->magicnum)
+            np = np->next;
+        *u2 = (Xnodeptr *) NULL;
+        clique_dfs (G, np->this, z, 1, u2);
+        for (k = 0, tp = *u2; tp; tp = tp->next)
+            if (tp->this->mark)
+                k++;
+        if (k < 2 || k % 2 != 0) {
+            Xnodeptr_list_free (all);
+            Xnodeptr_list_free (*u1);
+            Xnodeptr_list_free (*u2);
+            *u1 = *u2 = (Xnodeptr *) NULL;
+            return 0;
+        } else {
+            Xnodeptr_list_free (all);
+            return 1;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void clique_dfs (Xgraph *G, Xnode *start, int z, int storenodes,
+             Xnodeptr **list)
+#else
+static void clique_dfs (G, start, z, storenodes, list)
+Xgraph *G;
+Xnode *start;
+int z, storenodes;
+Xnodeptr **list;
+#endif
+{
+    Xedgeptr *ep;
+    Xnodeptr *np;
+    Xnode *n, *v;
+    Xnodeptr *next, *queue = (Xnodeptr *) NULL;
+
+    start->magiclabel = G->magicnum;
+    Xadd_nodeptr (&queue, start);
+
+    while (queue) {
+        n = queue->this;
+        next = queue->next;
+        Xnodeptrfree (queue);
+        queue = next;
+        if (storenodes) {
+            np = Xnodeptralloc ();
+            np->this = n;
+            np->next = *list;
+            *list = np;
+        }
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            if (ep->this->magiclabel == z) {
+                v = OTHERCURRENTEND (ep->this, n);
+                if (v->magiclabel != G->magicnum) {
+                    v->magiclabel = G->magicnum;
+                    Xadd_nodeptr (&queue, v);
+                }
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void unscan_remove (Xgraph *G, Xedgeptr **unscan, Xnodeptr *T)
+#else
+static void unscan_remove (G, unscan, T)
+Xgraph *G;
+Xedgeptr **unscan;
+Xnodeptr *T;
+#endif
+{
+    Xnodeptr *np;
+    Xedgeptr *ep, *next;
+
+    G->magicnum++;
+    for (np = T; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+
+    for (ep = *unscan, *unscan = (Xedgeptr *) NULL; ep; ep = next) {
+        next = ep->next;
+        if (ep->this->cends[0]->magiclabel == G->magicnum &&
+            ep->this->cends[1]->magiclabel == G->magicnum)
+            Xedgeptrfree (ep);
+        else {
+            ep->next = *unscan;
+            *unscan = ep;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int improve (Xgraph *G, Xnodeptr **u1, Xnodeptr **u2, Xnodeptr **u3,
+            Xnodeptr **u4, Xnodeptr **u5)
+#else
+static int improve (G, u1, u2, u3, u4, u5)
+Xgraph *G;
+Xnodeptr **u1, **u2, **u3, **u4, **u5;
+#endif
+{
+    int win, gotone = 0;
+    Xnodeptr *pick;
+    Xnode *v, *w;
+
+    while ((*u5)->next != (Xnodeptr *) NULL) {
+        win = grab_from_u5 (G, *u1, *u2, *u3, *u4, *u5, &pick, &v);
+        if (!win)
+            return gotone;
+        gotone = 1;
+        if (pick == *u1) {
+            remove_from_nodeptr (v, u5);
+            Xadd_nodeptr (u3, v);
+            while ((*u3)->next != (Xnodeptr *) NULL &&
+                   grab_from_mate (G, *u3, *u3, *u4, *u5, &w)) {
+                remove_from_nodeptr (w, u3);
+                Xadd_nodeptr (u1, w);
+            }
+        } else {
+            remove_from_nodeptr (v, u5);
+            Xadd_nodeptr (u4, v);
+            while ((*u4)->next != (Xnodeptr *) NULL &&
+                   grab_from_mate (G, *u4, *u3, *u4, *u5, &w)) {
+                remove_from_nodeptr (w, u4);
+                Xadd_nodeptr (u2, w);
+            }
+        }
+    }
+    return gotone;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grab_from_u5 (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2, Xnodeptr *u3,
+            Xnodeptr *u4, Xnodeptr *u5, Xnodeptr **pick, Xnode **v)
+#else
+static int grab_from_u5 (G, u1, u2, u3, u4, u5, pick, v)
+Xgraph *G;
+Xnodeptr *u1, *u2, *u3, *u4, *u5, **pick;
+Xnode **v;
+#endif
+{
+    Xnodeptr *np;
+    Xnode *n;
+    double t, best = -1.0;
+
+    for (np = u5; np; np = np->next) {
+        n = np->this;
+        t = single_crossvalue (G, n, u1, u3, (Xnodeptr *) NULL);
+        if (t > best) {
+            best = t;
+            *pick = u1;
+            *v = n;
+        }
+        t = single_crossvalue (G, n, u2, u4, (Xnodeptr *) NULL);
+        if (t > best) {
+            best = t;
+            *pick = u2;
+            *v = n;
+        }
+    }
+
+    return (best >= 1.0);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int grab_from_mate (Xgraph *G, Xnodeptr *mate, Xnodeptr *u3,
+            Xnodeptr *u4, Xnodeptr *u5, Xnode **w)
+#else
+static int grab_from_mate (G, mate, u3, u4, u5, w)
+Xgraph *G;
+Xnodeptr *mate, *u3, *u4, *u5;
+Xnode **w;
+#endif
+{
+    Xnodeptr *np;
+
+    for (np = mate; np; np = np->next)
+        if (single_crossvalue (G, np->this, u3, u4, u5) <= 1.0) {
+            *w = np->this;
+            return 1;
+        }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int clique_violated (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2,
+            Xnodeptr *u3, Xnodeptr *u4, Xnodeptr *u5)
+#else
+static int clique_violated (G, u1, u2, u3, u4, u5)
+Xgraph *G;
+Xnodeptr *u1, *u2, *u3, *u4, *u5;
+#endif
+{
+    double y;
+
+    y = crossvalue (G, u1, (Xnodeptr *) NULL, u2) + crossvalue (G, u1, u2, u5) +
+        crossvalue (G, u1, (Xnodeptr *) NULL, u4) +
+        crossvalue (G, u2, (Xnodeptr *) NULL, u3) +
+        clique_slack (G, u3) + clique_slack (G, u4);
+    /* printf ("CLIQUE VALUE: %f\n", y); fflush (stdout); */
+    return (y < 1.0 - XEPSILON);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double crossvalue (Xgraph *G, Xnodeptr *s1, Xnodeptr *s2, Xnodeptr *s3)
+#else
+static double crossvalue (G, s1, s2, s3)
+Xgraph *G;
+Xnodeptr *s1, *s2, *s3;
+#endif
+{
+    double val = 0.0;
+    Xnodeptr *np;
+    Xnode *n;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    G->magicnum++;
+    for (np = s1; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    if (s2)
+        for (np = s2; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+    for (np = s3; np; np = np->next) {
+        n = np->this;
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (OTHERCURRENTEND (e, n)->magiclabel == G->magicnum)
+                val += e->x;
+        }
+    }
+    return val;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double single_crossvalue (Xgraph *G, Xnode *v, Xnodeptr *s1,
+               Xnodeptr *s2, Xnodeptr *s3)
+#else
+static double single_crossvalue (G, v, s1, s2, s3)
+Xgraph *G;
+Xnode *v;
+Xnodeptr *s1, *s2, *s3;
+#endif
+{
+    double val = 0.0;
+    Xnodeptr *np;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    G->magicnum++;
+    for (np = s1; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (np = s2; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (np = s3; np; np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (ep = v->cadj.head; ep; ep = ep->next) {
+        e = ep->this;
+        if (OTHERCURRENTEND (e, v)->magiclabel == G->magicnum)
+            val += e->x;
+    }
+    return val;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static double clique_slack (Xgraph *G, Xnodeptr *s)
+#else
+static double clique_slack (G, s)
+Xgraph *G;
+Xnodeptr *s;
+#endif
+{
+    double val = 0.0, c = 0.0;
+    Xnodeptr *np;
+    Xedgeptr *ep;
+    Xedge *e;
+
+    G->magicnum++;
+    for (np = s; np; np = np->next) {
+        np->this->magiclabel = G->magicnum;
+        c += 1.0;
+    }
+    for (np = s; np; np = np->next)
+        for (ep = np->this->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->cends[0]->magiclabel == G->magicnum &&
+                e->cends[1]->magiclabel == G->magicnum)
+                val += e->x;
+        }
+    val *= 0.5;
+    return c - 1.0 - val;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int clique_fringe (Xnode *n, int ct)
+#else
+static int clique_fringe (n, ct)
+Xnode *n;
+int ct;
+#endif
+{
+    Xedgeptr *ep;
+    Xedge *e;
+
+    for (ep = n->cadj.head; ep; ep = ep->next) {
+        e = ep->this;
+        if (e->x <= ONEMINUS ||
+            OTHERCURRENTEND (e, n)->Tmark != ct)
+            return 0;
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void remove_from_nodeptr (Xnode *n, Xnodeptr **list)
+#else
+static void remove_from_nodeptr (n, list)
+Xnode *n;
+Xnodeptr **list;
+#endif
+{
+    Xnodeptr *np, *next;
+
+    for (np = *list, *list = (Xnodeptr *) NULL; np; np = next) {
+        next = np->next;
+        if (np->this == n)
+            Xnodeptrfree (np);
+        else {
+            np->next = *list;
+            *list = np;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void add_nodeptr_list (Xnodeptr **addto, Xnodeptr *takefrom)
+#else
+static void add_nodeptr_list (addto, takefrom)
+Xnodeptr **addto, *takefrom;
+#endif
+{
+    Xnodeptr *np, *tp;
+
+    for (np = takefrom; np; np = np->next) {
+        tp = Xnodeptralloc ();
+        tp->this = np->this;
+        tp->next = *addto;
+        *addto = tp;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void label_nodeptr_list (Xnodeptr *list, int z)
+#else
+static void label_nodeptr_list (list, z)
+Xnodeptr *list;
+int z;
+#endif
+{
+    Xnodeptr *np;
+
+    for (np = list; np; np = np->next)
+        np->this->magiclabel = z;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_special_cliquetree (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2,
+            Xnodeptr *u3, Xnodeptr *u4, Xnodeptr *u5, Xcplane **list, double *x)
+#else
+static int check_special_cliquetree (G, u1, u2, u3, u4, u5, list, x)
+Xgraph *G;
+Xnodeptr *u1, *u2, *u3, *u4, *u5;
+Xcplane **list;
+double *x;
+#endif
+{
+    Xnodeptr *H1 = (Xnodeptr *) NULL, *H2 = (Xnodeptr *) NULL,
+             *T = (Xnodeptr *) NULL, *np;
+    Xedgeptr *ep, *et, *pteeth = (Xedgeptr *) NULL;
+    int nteeth = 0, test;
+    Xnode *n;
+    Xedge *e;
+
+    add_nodeptr_list (&H1, u1);
+    add_nodeptr_list (&H1, u3);
+
+    add_nodeptr_list (&H2, u2);
+    add_nodeptr_list (&H2, u4);
+
+    add_nodeptr_list (&T, u3);
+    add_nodeptr_list (&T, u4);
+    add_nodeptr_list (&T, u5);
+    nteeth++;
+
+    G->magicnum++;
+    label_nodeptr_list (u1, G->magicnum);
+    label_nodeptr_list (u2, G->magicnum);
+    label_nodeptr_list (u3, G->magicnum);
+    label_nodeptr_list (u4, G->magicnum);
+    label_nodeptr_list (u5, G->magicnum);
+
+    for (np = u1; np; np = np->next) {
+        n = np->this;
+        if (n->mark)
+            for (ep = n->cadj.head; ep; ep = ep->next) {
+                e = ep->this;
+                if (e->x > ONEMINUS &&
+                    OTHERCURRENTEND (e, n)->magiclabel != G->magicnum) {
+                    et = Xedgeptralloc ();
+                    et->this = e;
+                    et->next = pteeth;
+                    pteeth = et;
+                    nteeth++;
+                }
+            }
+    }
+    for (np = u2; np; np = np->next) {
+        n = np->this;
+        if (n->mark)
+            for (ep = n->cadj.head; ep; ep = ep->next) {
+                e = ep->this;
+                if (e->x > ONEMINUS &&
+                    OTHERCURRENTEND (e, n)->magiclabel != G->magicnum) {
+                    et = Xedgeptralloc ();
+                    et->this = e;
+                    et->next = pteeth;
+                    pteeth = et;
+                    nteeth++;
+                }
+            }
+    }
+    if (nteeth % 2 == 0) {
+        printf ("Even number of teeth in a clique-tree\n");
+        Xnodeptr_list_free (H1);
+        Xnodeptr_list_free (H2);
+        Xnodeptr_list_free (T);
+        Xedgeptr_list_free (pteeth);
+        return 0;
+    } else {
+        test = load_special_cliquetree (G, H1, H2, T, pteeth, list, x);
+        Xnodeptr_list_free (H1);
+        Xnodeptr_list_free (H2);
+        Xnodeptr_list_free (T);
+        Xedgeptr_list_free (pteeth);
+        return test;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int load_special_cliquetree (Xgraph *G, Xnodeptr *H1, Xnodeptr *H2,
+            Xnodeptr *T, Xedgeptr *pteeth, Xcplane **list, double *x)
+#else
+static int load_special_cliquetree (G, H1, H2, T, pteeth, list, x)
+Xgraph *G;
+Xnodeptr *H1, *H2, *T;
+Xedgeptr *pteeth;
+Xcplane **list;
+double *x;
+#endif
+{
+    int test;
+    Xnodeptr *tooth, *tH1, *tH2, *tT;
+    Xnodeptrptr *handles, *teeth;
+    Xedgeptr *ep;
+
+    pseudonodelist_to_nodelist (H1, &tH1);
+    pseudonodelist_to_nodelist (H2, &tH2);
+    pseudonodelist_to_nodelist (T, &tT);
+
+    handles = (Xnodeptrptr *) NULL;
+    Xadd_nodeptrptr (&handles, tH1);
+    Xadd_nodeptrptr (&handles, tH2);
+
+    teeth = (Xnodeptrptr *) NULL;
+    Xadd_nodeptrptr (&teeth, tT);
+    for (ep = pteeth; ep; ep = ep->next) {
+        tooth = (Xnodeptr *) NULL;
+        Xmarktooth (ep->this, &(tooth));
+        Xadd_nodeptrptr (&teeth, tooth);
+    }
+
+    if (!Xcliquefluff (G, &handles, &teeth)) {
+        return 0;
+    }
+    if (!Xviolated_clique_flow (G, handles, teeth, x)) {
+        /* printf ("BANG!\n"); */
+        Xfreeteeth (handles);
+        Xfreeteeth (teeth);
+        return 0;
+    }
+    test = Xloadcplane (list, (Xnodeptr *) NULL, handles, teeth, 0);
+    if (!test) {
+        Xfreeteeth (handles);
+        Xfreeteeth (teeth);
+    }
+    return test;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void pseudonodelist_to_nodelist (Xnodeptr *p, Xnodeptr **l)
+#else
+static void pseudonodelist_to_nodelist (p, l)
+Xnodeptr *p, **l;
+#endif
+{
+    Xnodeptr *mp, *np;
+
+    (*l) = (Xnodeptr *) NULL;
+    for (np = p; np; np = np->next)
+        for (mp = np->this->base.head; mp; mp = mp->next)
+            Xadd_nodeptr (l, mp->this);
+}
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_special_cliquetree (Xgraph *G, Xnodeptr *u1, Xnodeptr *u2,
+             Xnodeptr *u3, Xnodeptr *u4, Xnodeptr *u5)
+#else
+static void dump_special_cliquetree (G, u1, u2, u3, u4, u5)
+Xgraph *G;
+Xnodeptr *u1, *u2, *u3, *u4, *u5;
+#endif
+{
+    printf ("U1: ");
+    nodeptr_print (u1);
+    printf ("U2: ");
+    nodeptr_print (u2);
+    printf ("U3: ");
+    nodeptr_print (u3);
+    printf ("U4: ");
+    nodeptr_print (u4);
+    printf ("U5: ");
+    nodeptr_print (u5);
+}
+#endif /* DEBUG */
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void nodeptr_print (Xgraph *G, Xnodeptr *s)
+#else
+static void nodeptr_print (G, s)
+Xgraph *G;
+Xnodeptr *s;
+#endif
+{
+    Xnodeptr *np;
+
+    for (np = s; np; np = np->next)
+        printf ("%3d%c ", np->this - G->nodelist, np->this->mark ? '*' : ' ');
+    printf ("\n");
+}
+#endif /* DEBUG */
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xcuthash.c b/contrib/blossom/concorde97/XSTUFF/Xcuthash.c
new file mode 100644
index 0000000000000000000000000000000000000000..da2e6b05403880065a071cffc7143989bf214610
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xcuthash.c
@@ -0,0 +1,122 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    void                                                                */
+/*       init_hash_values ();                                             */
+/*                                                                        */
+/*    unsigned long                                                       */
+/*       cut_hash_value (),                                               */
+/*       comb_hash_value (),                                              */
+/*       clique_hash_value ();                                            */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+
+/*
+   This code needs two fields added to a node.  They are unsigned long rand1
+   and unsigned long rand2.
+*/
+
+static unsigned long hashfunc1[256];
+static unsigned long hashfunc2[256];
+static unsigned long hashfunc3[256];
+static unsigned long hashfunc4[256];
+
+#define TOOTHHASHFUNC(x) (hashfunc1[(x)&0xff] ^ hashfunc2[((x)>>8)&0xff] ^ \
+                      hashfunc3[((x)>>16)&0xff] ^ hashfunc4[((x)>>24)&0xff])
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xinit_hash_values (Xgraph *G)
+#else
+void Xinit_hash_values (G)
+Xgraph *G;
+#endif
+{
+    int i;
+
+    for (i = 0; i < G->nnodes; i++) {
+        G->nodelist[i].rand1 = (int) CCutil_lprand ();
+        G->nodelist[i].rand2 = (int) CCutil_lprand ();
+    }
+    for (i = 0; i < 256; i++) {
+        hashfunc1[i] = CCutil_lprand ();
+        hashfunc2[i] = CCutil_lprand ();
+        hashfunc3[i] = CCutil_lprand ();
+        hashfunc4[i] = CCutil_lprand ();
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+unsigned long Xcut_hash_value (Xnodeptr *h)
+#else
+unsigned long Xcut_hash_value (h)
+Xnodeptr *h;
+#endif
+{
+    Xnodeptr *p;
+    unsigned long hashval = 0;
+
+    for (p = h; p; p = p->next)
+        hashval ^= p->this->rand1;
+
+    return hashval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+unsigned long Xcomb_hash_value (Xnodeptr *h, Xnodeptrptr *t)
+#else
+unsigned long Xcomb_hash_value (h, t)
+Xnodeptr *h;
+Xnodeptrptr *t;
+#endif
+{
+    Xnodeptr *p;
+    Xnodeptrptr *q;
+    unsigned long hashval = 0;
+    unsigned long toothhash;
+
+    for (p = h; p; p = p->next)
+        hashval ^= p->this->rand1;
+    for (q = t; q; q = q->next) {
+        toothhash = 0;
+        for (p = q->this; p; p = p->next)
+            toothhash ^= p->this->rand2;
+        hashval ^= TOOTHHASHFUNC (toothhash);
+    }
+    return hashval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+unsigned long Xclique_hash_value (Xnodeptrptr *h, Xnodeptrptr *t)
+#else
+unsigned long Xclique_hash_value (h, t)
+Xnodeptrptr *h;
+Xnodeptrptr *t;
+#endif
+{
+    Xnodeptr *p;
+    Xnodeptrptr *q;
+    unsigned long hashval = 0;
+    unsigned long toothhash;
+    unsigned long handlehash;
+
+    for (q = h; q; q = q->next) {
+        handlehash = 0;
+        for (p = q->this; p; p = p->next)
+            handlehash ^= p->this->rand1;
+        hashval ^= TOOTHHASHFUNC (handlehash);
+    }
+    for (q = t; q; q = q->next) {
+        toothhash = 0;
+        for (p = q->this; p; p = p->next)
+            toothhash ^= p->this->rand2;
+        hashval ^= TOOTHHASHFUNC (toothhash);
+    }
+    return hashval;
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xcutload.c b/contrib/blossom/concorde97/XSTUFF/Xcutload.c
new file mode 100644
index 0000000000000000000000000000000000000000..14e22541fd7e1bc67d4e360268da8a4140506698
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xcutload.c
@@ -0,0 +1,295 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    void                                                                */
+/*        cliquetree_slack_rhs_flow (),                                   */
+/*        destroycutlinks (),                                             */
+/*        freecplanelist ();                                              */
+/*    int                                                                 */
+/*        cutchecksout (),                                                */
+/*        temp_doblossom (),                                              */
+/*        violated_clique_flow (),                                        */
+/*        loadcplane (),                                                  */
+/*        loadcplane_cut (),                                              */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcutchecksout (Xgraph *G, int x)
+#else
+int Xcutchecksout (G, x)
+Xgraph *G;
+int x;
+#endif
+{
+    double weight = 0.0;
+    int i;
+    Xedge *e;
+
+    for (i = G->nedges, e = G->edgelist; i; i--, e++)
+        if ((e->ends[0]->magiclabel == x) !=
+            (e->ends[1]->magiclabel == x))
+            weight += e->x;
+
+    return (weight <= 2.0 - XEPSILON);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xtemp_doblossom (Xgraph *G, Xcplane **cplanelist, Xnodeptr *handle,
+                     Xedgeptr *teeth)
+#else
+int Xtemp_doblossom (G, cplanelist, handle, teeth)
+Xgraph *G;
+Xcplane **cplanelist;
+Xnodeptr *handle;
+Xedgeptr *teeth;
+#endif
+{
+    Xnodeptrptr *temp_teeth, *ntp;
+    Xedgeptr *ep;
+    int nteeth, i, returnval;
+    int countcheck = 1;
+
+    for (nteeth = 0, ep = teeth; ep; ep = ep->next)
+        nteeth++;
+
+    if (nteeth % 2 == 0) {
+        fprintf (stderr, "EVEN NUMBER OF TEETH on a blossom\n");
+        Xnodeptr_list_free (handle);
+        return 0;
+    }
+    temp_teeth = (Xnodeptrptr *) NULL;
+    for (i = 0, ep = teeth; i < nteeth; i++, ep = ep->next) {
+        ntp = Xnodeptrptralloc ();
+        ntp->this = (Xnodeptr *) NULL;
+        ntp->next = temp_teeth;
+        temp_teeth = ntp;
+
+        Xadd_nodeptr (&(ntp->this), ep->this->ends[0]);
+        Xadd_nodeptr (&(ntp->this), ep->this->ends[1]);
+    }
+
+    if (!Xtemp_combfluff (G, &handle, &temp_teeth)) {
+        return 0;
+    }
+
+    returnval = Xloadcplane (cplanelist, handle, (Xnodeptrptr *) NULL,
+                             temp_teeth, countcheck);
+    if (!returnval) {
+        Xfreeteeth (temp_teeth);
+        Xnodeptr_list_free (handle);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcliquetree_slack_rhs_flow (Xgraph *G, Xnodeptrptr *handles,
+             Xnodeptrptr *teeth, double *x, double *slack, double *rhs)
+#else
+void Xcliquetree_slack_rhs_flow (G, handles, teeth, x, slack, rhs)
+Xgraph *G;
+Xnodeptrptr *handles, *teeth;
+double *x;
+double *slack, *rhs;
+#endif
+{
+    int i;
+    Xedge *e;
+    Xnodeptrptr *ntp, *mtp;
+    Xnodeptr *np;
+    int nteeth;
+    int H, T, TI;
+    double sum;
+
+    /* Puts cliquetree coef on the flow variables, computes rhs of */
+    /* the cliquetree, and computes slack if x is given.           */
+
+    for (i = G->nedges, e = G->edgelist; i; i--, e++)
+        e->flow = 0.0;
+
+    for (ntp = handles, H = 0; ntp; ntp = ntp->next) {
+        H += Xinduced_edges_flow (G, ntp->this);
+    }
+    for (ntp = teeth, nteeth = 0, T = 0; ntp; ntp = ntp->next) {
+        nteeth++;
+        T += Xinduced_edges_flow (G, ntp->this);
+    }
+
+    /* TI will be the sum over all teeth of the number of handles */
+    /* a given tooth meets.                                           */
+
+    for (ntp = teeth, TI = 0; ntp; ntp = ntp->next) {
+        G->magicnum++;
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+        for (mtp = handles; mtp; mtp = mtp->next) {
+            for (np = mtp->this; np; np = np->next) {
+                if (np->this->magiclabel == G->magicnum) {
+                    TI++;
+                    break;
+                }
+            }
+        }
+    }
+
+    *rhs = H + T - TI - ((nteeth + 1) / 2);
+
+    if (x) {
+        for (i = G->nedges, e = G->edgelist, sum = 0.0; i; i--, e++)
+            if (e->flow >= 1.0)
+                sum += (e->flow * x[e - G->edgelist]);
+        *slack = *rhs - sum;
+    } else {
+        *slack = 0.0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xviolated_clique_flow (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth,
+                           double *x)
+#else
+int Xviolated_clique_flow (G, handles, teeth, x)
+Xgraph *G;
+Xnodeptrptr *handles;
+Xnodeptrptr *teeth;
+double *x;
+#endif
+{
+    double slack, rhs;
+
+    if (!Xcheckclique (G, handles, teeth))
+        return 0;
+
+    Xcliquetree_slack_rhs_flow (G, handles, teeth, x, &slack, &rhs);
+
+    if (slack > -XEPSILON) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+#define MAXCOMBSIZE 150
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xloadcplane (Xcplane **list, Xnodeptr *h, Xnodeptrptr *H,
+                 Xnodeptrptr *t, int countcheck)
+#else
+int Xloadcplane (list, h, H, t, countcheck)
+Xcplane **list;
+Xnodeptr *h;
+Xnodeptrptr *H;
+Xnodeptrptr *t;
+int countcheck;
+#endif
+{
+    unsigned long val;
+    Xcplane *c;
+    Xnodeptr *np;
+    Xnodeptrptr *ntp;
+    int count;
+
+    if (t == (Xnodeptrptr *) NULL)
+        val = Xcut_hash_value (h);
+    else if (H == (Xnodeptrptr *) NULL)
+        val = Xcomb_hash_value (h, t);
+    else
+        val = Xclique_hash_value (H, t);
+
+    for (c = *list; c; c = c->next)
+        if (c->val == val)
+            break;
+    if (c == (Xcplane *) NULL) {
+        if (t != (Xnodeptrptr *) NULL && h != (Xnodeptr *) NULL && countcheck) {
+            count = 0;
+            for (np = h; np; np = np->next)
+                count++;
+            for (ntp = t; ntp; ntp = ntp->next)
+                for (np = ntp->this; np; np = np->next)
+                    count++;
+            if (count > MAXCOMBSIZE)
+                return 0;
+        }
+        c = Xcplanealloc ();
+        c->val = val;
+        c->handle = h;
+        c->handles = H;
+        c->teeth = t;
+        c->next = *list;
+        *list = c;
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xloadcplane_cut (Xgraph *G, Xcplane **list, int num)
+#else
+int Xloadcplane_cut (G, list, num)
+Xgraph *G;
+Xcplane **list;
+int num;
+#endif
+{
+    Xnodeptr *handle, *np;
+    Xnode *n;
+    int i, cnt = 0, test, countcheck = 1;
+
+    for (i = 0; i < G->nnodes; i++)
+        if (G->nodelist[i].magiclabel == num)
+            cnt++;
+
+    if (cnt < 3 || cnt > G->nnodes - 2)
+        return 0;
+
+    if (cnt <= G->nnodes / 2) {
+        for (handle = (Xnodeptr *) NULL, i = G->nnodes, n = G->nodelist; i;
+             n++, i--) {
+            if (n->magiclabel == num) {
+                np = Xnodeptralloc ();
+                np->this = n;
+                np->next = handle;
+                handle = np;
+            }
+        }
+    } else {
+        for (handle = (Xnodeptr *) NULL, i = G->nnodes, n = G->nodelist; i;
+             n++, i--) {
+            if (n->magiclabel != num) {
+                np = Xnodeptralloc ();
+                np->this = n;
+                np->next = handle;
+                handle = np;
+            }
+        }
+    }
+    test = Xloadcplane (list, handle, (Xnodeptrptr *) NULL,
+                       (Xnodeptrptr *) NULL, countcheck);
+    if (!test) {
+        Xnodeptr_list_free (handle);
+    }
+    return test;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xfreecplanelist (Xcplane **list)
+#else
+void Xfreecplanelist (list)
+Xcplane **list;
+#endif
+{
+    Xcplane *c, *cnext;
+
+    for (c = *list; c; c = cnext) {
+        cnext = c->next;
+        Xfreecplanestruct (c);
+    }
+    *list = (Xcplane *) NULL;
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xcutpool.h b/contrib/blossom/concorde97/XSTUFF/Xcutpool.h
new file mode 100644
index 0000000000000000000000000000000000000000..984561542bdbf8658483a1b973483827831bc6e2
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xcutpool.h
@@ -0,0 +1,17 @@
+#ifndef __XCUTPOOL_H
+#define __XCUTPOOL_H
+
+typedef struct Xportablecut {
+    int nhandles;
+    int *handles;  /* each handle terminated with a -1 */
+    int nteeth;
+    int *teeth;    /* each tooth  terminated with a -1 */
+} Xportablecut;
+
+typedef struct Xportableclique {
+    int size;
+    int *nodes;
+    double cutval;
+} Xportableclique;
+
+#endif /* __XCUTPOOL_H */
diff --git a/contrib/blossom/concorde97/XSTUFF/Xcuts.c b/contrib/blossom/concorde97/XSTUFF/Xcuts.c
new file mode 100644
index 0000000000000000000000000000000000000000..73d07f65c90f44ee42b9a5c1154bc26278706210
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xcuts.c
@@ -0,0 +1,141 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*  int                                                                   */
+/*      Xolaf_combs (Xgraph *G, Xcplane *list, double *x),                */
+/*      Xblobcuts (Xgraph *G, Xcplane **list, double *x);                 */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    run_olaf (Xgraph *G, Xcplane **list, double *x, int olaf_select, int count),
+    dfs (Xgraph *G, Xnode *start);
+
+#else
+
+static int
+    run_olaf (),
+    dfs ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xolaf_combs (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xolaf_combs (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    int cnt;
+
+    cnt =  run_olaf (G, list, x, 3, 4);
+    if (cnt >= XCUTNUM)
+        return cnt;
+    cnt += run_olaf (G, list, x, 1, 1);
+    if (cnt >= XCUTNUM)
+        return cnt;
+    cnt += run_olaf (G, list, x, 2, 1);
+    if (cnt >= XCUTNUM)
+        return cnt;
+    cnt += run_olaf (G, list, x, 4, 1);
+
+    return cnt;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int run_olaf (Xgraph *G, Xcplane **list, double *x, int olaf_select,
+            int count)
+#else
+static int run_olaf (G, list, x, olaf_select, count)
+Xgraph *G;
+Xcplane **list;
+double *x;
+int olaf_select, count;
+#endif
+{
+    int hit, cuts, round;
+
+    Xloadx (G, x);
+    hit = round = 0;
+    Xbuildpseudonodelist (G, 0);
+    while (round < count && hit < XCUTNUM && Xolaf (G, olaf_select)) {
+        hit += (cuts = Xexactblossomcheck (G, list, 1, x));
+        printf ("    [%d olaf(%d) combs]\n", cuts, olaf_select);
+        fflush (stdout);
+        round++;
+    }
+    Xdestroypseudonodelist (G);
+    return hit;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xblobcuts (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xblobcuts (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    int i;
+
+    if (dfs (G, &(G->nodelist[0])) != G->nnodes) {
+        printf ("  cannot run blobcuts on disconnected graph\n");
+        fflush (stdout);
+        return 0;
+    }
+    Xpancakex (G, x);
+    i = Xblobsviolated (G, list);
+    Xfreepancake ();
+
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int dfs (Xgraph *G, Xnode *start)
+#else
+static int dfs (G, start)
+Xgraph *G;
+Xnode *start;
+#endif
+{
+    int i = 0;
+    Xedgeptr *epp;
+    Xedge *ep;
+    Xnode *n, *n1;
+    Xnodeptr *next, *queue = (Xnodeptr *) NULL;
+
+    G->magicnum++;
+    start->magiclabel = G->magicnum;
+    Xadd_nodeptr (&queue, start);
+
+    while (queue) {
+        i++;
+        n = queue->this;
+        next = queue->next;
+        Xnodeptrfree (queue);
+        queue = next;
+        for (epp = n->adj.head; epp; epp = epp->next) {
+            ep = epp->this;
+            n1 = ep->ends[0];
+            if (n1 == n)
+                n1 = ep->ends[1];
+            if (n1->magiclabel != G->magicnum) {
+                n1->magiclabel = G->magicnum;
+                Xadd_nodeptr (&queue, n1);
+            }
+        }
+    }
+    return i;
+}
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xcututil.c b/contrib/blossom/concorde97/XSTUFF/Xcututil.c
new file mode 100644
index 0000000000000000000000000000000000000000..9304be520bb623df5cc1228abd6fccc1e1e35109
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xcututil.c
@@ -0,0 +1,613 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    void                                                                */
+/*        freecplanestruct (),                                            */
+/*        freeiplanestruct (),                                            */
+/*        cplane_to_iplane (),                                            */
+/*        iplane_to_cplane (),                                            */
+/*        portablecut_to_cplane (),                                       */
+/*        portablecut_to_handles_and_teeth (),                            */
+/*        portablecut_to_iplane (),                                       */
+/*        freeteeth (),                                                   */
+/*        printchvatalcomb (),                                            */
+/*        printcliquetree (),                                             */
+/*        dumpchvatalcomb (),                                             */
+/*        dumpcliquetree ();                                              */
+/*                                                                        */
+/*    int                                                                 */
+/*        slackclique (),                                                 */
+/*        induced_edges_flow ();                                          */
+/*                                                                        */
+/*    NOT CALLED:  portablecut_to_handles_and_teeth()                     */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xslackclique (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth,
+                 double *slack)
+#else
+int Xslackclique (G, handles, teeth, slack)
+Xgraph *G;
+Xnodeptrptr *handles, *teeth;
+double *slack;
+#endif
+{
+    /* ASSUMES x VALUES ON THE EDGES  */
+    int hit, H, T, TI, nteeth;
+    Xedge *e, *lastedge = (G->edgelist) + G->nedges;
+    Xnodeptr *np;
+    Xnodeptrptr *ntp, *mtp;
+    double sum, rhs;
+
+    for (e = G->edgelist; e != lastedge; e++)
+        e->flow = 0.0;
+
+    for (ntp = handles, H = 0; ntp; ntp = ntp->next) {
+        H += Xinduced_edges_flow (G, ntp->this);
+    }
+    for (ntp = teeth, nteeth = 0, T = 0; ntp; ntp = ntp->next) {
+        nteeth++;
+        T += Xinduced_edges_flow (G, ntp->this);
+    }
+
+    for (ntp = teeth, TI = 0; ntp; ntp = ntp->next) {
+        G->magicnum++;
+        for (np = ntp->this; np; np = np->next)
+            np->this->magiclabel = G->magicnum;
+        for (hit = 0, mtp = handles; mtp; mtp = mtp->next) {
+            for (np = mtp->this; np; np = np->next) {
+                if (np->this->magiclabel == G->magicnum) {
+                    TI++;
+                    hit++;
+                    break;
+                }
+            }
+        }
+        if (!hit) {
+            fprintf (stderr, "Tooth doesn't meet handles\n");
+            return 0;
+        }
+    }
+
+    rhs = H + T - TI - ((nteeth + 1) / 2);
+
+    for (e = G->edgelist, sum = 0.0; e != lastedge; e++)
+        if (e->flow >= 1.0)
+            sum += (e->flow * e->x);
+
+    *slack = rhs - sum;
+    return 1;
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xinduced_edges_flow (Xgraph *G, Xnodeptr *set)
+#else
+int Xinduced_edges_flow (G, set)
+Xgraph *G;
+Xnodeptr *set;
+#endif
+{
+    Xnodeptr *np;
+    Xedgeptr *ep;
+    int count;
+
+    G->magicnum++;
+    for (np = set, count = 0; np; count++, np = np->next)
+        np->this->magiclabel = G->magicnum;
+    for (np = set; np; np = np->next)
+        for (ep = np->this->adj.head; ep; ep = ep->next)
+            if (ep->this->ends[0]->magiclabel ==
+                ep->this->ends[1]->magiclabel)
+                ep->this->flow += 0.5;
+    return count;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xfreecplanestruct (Xcplane *c)
+#else
+void Xfreecplanestruct (c)
+Xcplane *c;
+#endif
+{
+    if (c->handle != (Xnodeptr *) NULL)
+        Xnodeptr_list_free (c->handle);
+    if (c->handles != (Xnodeptrptr *) NULL)
+        Xfreeteeth (c->handles);
+    if (c->teeth != (Xnodeptrptr *) NULL)
+        Xfreeteeth (c->teeth);
+    Xcplanefree (c);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xfreeiplanestruct (Xiplane *c)
+#else
+void Xfreeiplanestruct (c)
+Xiplane *c;
+#endif
+{
+    Xintptrptr *itp;
+
+    if (c->handle)
+        Xintptr_list_free (c->handle);
+    if (c->handles) {
+        for (itp = c->handles; itp; itp = itp->next)
+            Xintptr_list_free (itp->this);
+        Xintptrptr_list_free (c->handles);
+    }
+    if (c->teeth) {
+        for (itp = c->teeth; itp; itp = itp->next)
+            Xintptr_list_free (itp->this);
+        Xintptrptr_list_free (c->teeth);
+    }
+    Xiplanefree (c);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcplane_to_iplane (Xgraph *G, Xcplane *c, Xiplane **ipl)
+#else
+void Xcplane_to_iplane (G, c, ipl)
+Xgraph *G;
+Xcplane *c;
+Xiplane **ipl;
+#endif
+{
+    Xintptr *handle, *ip, *tooth, *h;
+    Xintptrptr *handles, *teeth;
+    Xnodeptr *np;
+    Xnodeptrptr *ntp;
+
+    if (c->handle) {
+        handle = (Xintptr *) NULL;
+        for (np = c->handle; np; np = np->next) {
+            ip = Xintptralloc ();
+            ip->this = np->this - G->nodelist;
+            ip->next = handle;
+            handle = ip;
+        }
+    } else
+        handle = (Xintptr *) NULL;
+
+    if (c->handles) {
+        handles = (Xintptrptr *) NULL;
+        for (ntp = c->handles; ntp; ntp = ntp->next) {
+            h = (Xintptr *) NULL;
+            for (np = ntp->this; np; np = np->next) {
+                ip = Xintptralloc ();
+                ip->this = np->this - G->nodelist;
+                ip->next = h;
+                h = ip;
+            }
+            Xadd_intptrptr (&handles, h);
+        }
+    } else
+        handles = (Xintptrptr *) NULL;
+
+    if (c->teeth) {
+        teeth = (Xintptrptr *) NULL;
+        for (ntp = c->teeth; ntp; ntp = ntp->next) {
+            tooth = (Xintptr *) NULL;
+            for (np = ntp->this; np; np = np->next) {
+                ip = Xintptralloc ();
+                ip->this = np->this - G->nodelist;
+                ip->next = tooth;
+                tooth = ip;
+            }
+            Xadd_intptrptr (&teeth, tooth);
+        }
+    } else
+        teeth = (Xintptrptr *) NULL;
+
+    *ipl = Xiplanealloc ();
+    (*ipl)->handle = handle;
+    (*ipl)->handles = handles;
+    (*ipl)->teeth = teeth;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xiplane_to_cplane (Xgraph *G, Xiplane *c, Xcplane **cpl)
+#else
+void Xiplane_to_cplane (G, c, cpl)
+Xgraph *G;
+Xiplane *c;
+Xcplane **cpl;
+#endif
+{
+    Xnodeptr *handle, *np, *tooth, *h;
+    Xnodeptrptr *handles, *teeth;
+    Xintptr *ip;
+    Xintptrptr *itp;
+
+    if (c->handle) {
+        handle = (Xnodeptr *) NULL;
+        for (ip = c->handle; ip; ip = ip->next) {
+            np = Xnodeptralloc ();
+            np->this = ip->this + G->nodelist;
+            np->next = handle;
+            handle = np;
+        }
+    } else
+        handle = (Xnodeptr *) NULL;
+
+    if (c->handles) {
+        handles = (Xnodeptrptr *) NULL;
+        for (itp = c->handles; itp; itp = itp->next) {
+            h = (Xnodeptr *) NULL;
+            for (ip = itp->this; ip; ip = ip->next) {
+                np = Xnodeptralloc ();
+                np->this = ip->this + G->nodelist;
+                np->next = h;
+                h = np;
+            }
+            Xadd_nodeptrptr (&handles, h);
+        }
+    } else
+        handles = (Xnodeptrptr *) NULL;
+
+    if (c->teeth) {
+        teeth = (Xnodeptrptr *) NULL;
+        for (itp = c->teeth; itp; itp = itp->next) {
+            tooth = (Xnodeptr *) NULL;
+            for (ip = itp->this; ip; ip = ip->next) {
+                np = Xnodeptralloc ();
+                np->this = ip->this + G->nodelist;
+                np->next = tooth;
+                tooth = np;
+            }
+            Xadd_nodeptrptr (&teeth, tooth);
+        }
+    } else
+        teeth = (Xnodeptrptr *) NULL;
+
+    *cpl = Xcplanealloc ();
+    (*cpl)->handle = handle;
+    (*cpl)->handles = handles;
+    (*cpl)->teeth = teeth;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xportablecut_to_cplane (Xgraph *G, Xportablecut *p, Xcplane **cpl)
+#else
+void Xportablecut_to_cplane (G, p, cpl)
+Xgraph *G;
+Xportablecut *p;
+Xcplane **cpl;
+#endif
+{
+    Xnodeptr *np, *tooth, *h;
+    Xnodeptrptr *handles, *teeth;
+    int i, k;
+
+    handles = (Xnodeptrptr *) NULL;
+    for (i = 0, k = 0; i < p->nhandles; i++) {
+        h = (Xnodeptr *) NULL;
+        while (p->handles[k] != -1) {
+            np = Xnodeptralloc ();
+            np->this = p->handles[k++] + G->nodelist;
+            np->next = h;
+            h = np;
+        }
+        Xadd_nodeptrptr (&handles, h);
+        k++;
+    }
+
+    teeth = (Xnodeptrptr *) NULL;
+    for (i = 0, k = 0; i < p->nteeth; i++) {
+        tooth = (Xnodeptr *) NULL;
+        while (p->teeth[k] != -1) {
+            np = Xnodeptralloc ();
+            np->this = p->teeth[k++] + G->nodelist;
+            np->next = tooth;
+            tooth = np;
+        }
+        Xadd_nodeptrptr (&teeth, tooth);
+        k++;
+    }
+
+    *cpl = Xcplanealloc ();
+    (*cpl)->handle = (Xnodeptr *) NULL;
+    (*cpl)->handles = handles;
+    (*cpl)->teeth = teeth;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xportablecut_to_handles_and_teeth (Xgraph *G, Xportablecut *p,
+                            Xnodeptrptr **handles, Xnodeptrptr **teeth)
+#else
+void Xportablecut_to_handles_and_teeth (G, p, handles, teeth)
+Xgraph *G;
+Xportablecut *p;
+Xnodeptrptr **handles, **teeth;
+#endif
+{
+    Xnodeptr *np, *tooth, *h;
+    int i, k;
+
+    *handles = (Xnodeptrptr *) NULL;
+    for (i = 0, k = 0; i < p->nhandles; i++) {
+        h = (Xnodeptr *) NULL;
+        while (p->handles[k] != -1) {
+            np = Xnodeptralloc ();
+            np->this = p->handles[k++] + G->nodelist;
+            np->next = h;
+            h = np;
+        }
+        Xadd_nodeptrptr (handles, h);
+        k++;
+    }
+
+    *teeth = (Xnodeptrptr *) NULL;
+    for (i = 0, k = 0; i < p->nteeth; i++) {
+        tooth = (Xnodeptr *) NULL;
+        while (p->teeth[k] != -1) {
+            np = Xnodeptralloc ();
+            np->this = p->teeth[k++] + G->nodelist;
+            np->next = tooth;
+            tooth = np;
+        }
+        Xadd_nodeptrptr (teeth, tooth);
+        k++;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xportablecut_to_iplane (Xportablecut *p, Xiplane **ipl)
+#else
+void Xportablecut_to_iplane (p, ipl)
+Xportablecut *p;
+Xiplane **ipl;
+#endif
+{
+    Xintptr *ip, *tooth, *h;
+    Xintptrptr *handles, *teeth;
+    int i, k;
+
+    handles = (Xintptrptr *) NULL;
+    for (i = 0, k = 0; i < p->nhandles; i++) {
+        h = (Xintptr *) NULL;
+        while (p->handles[k] != -1) {
+            ip = Xintptralloc ();
+            ip->this = p->handles[k++];
+            ip->next = h;
+            h = ip;
+        }
+        Xadd_intptrptr (&handles, h);
+        k++;
+    }
+
+    teeth = (Xintptrptr *) NULL;
+    for (i = 0, k = 0; i < p->nteeth; i++) {
+        tooth = (Xintptr *) NULL;
+        while (p->teeth[k] != -1) {
+            ip = Xintptralloc ();
+            ip->this = p->teeth[k++];
+            ip->next = tooth;
+            tooth = ip;
+        }
+        Xadd_intptrptr (&teeth, tooth);
+        k++;
+    }
+
+    *ipl = Xiplanealloc ();
+    (*ipl)->handle = (Xintptr *) NULL;
+    (*ipl)->handles = handles;
+    (*ipl)->teeth = teeth;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xiplane_to_portablecut (Xiplane *c, Xportablecut *p)
+#else
+void Xiplane_to_portablecut (c, p)
+Xiplane *c;
+Xportablecut *p;
+#endif
+{
+    int hands, handcount;
+    int teeth, teethcount;
+    int k;
+    Xintptr *ip;
+    Xintptrptr *ipp;
+
+    if (c->handle) {
+        p->nhandles = 1;
+        for (ip = c->handle, handcount = 0; ip; ip = ip->next)
+            handcount++;
+        handcount++;
+        p->handles = CC_SAFE_MALLOC (handcount, int);
+        if (!p->handles) {
+            fprintf (stderr, "out of memory in iplane_to_portablecut\n");
+            exit (1);
+        }
+        for (ip = c->handle, k = 0; ip; ip = ip->next)
+            p->handles[k++] = ip->this;
+        p->handles[k] = -1;
+    } else {
+        for (ipp = c->handles, hands = 0; ipp; ipp = ipp->next)
+            hands++;
+        p->nhandles = hands;
+        for (ipp = c->handles, handcount = 0; ipp; ipp = ipp->next) {
+            for (ip = ipp->this; ip; ip = ip->next)
+                handcount++;
+            handcount++;
+        }
+        p->handles = CC_SAFE_MALLOC (handcount, int);
+        if (!p->handles) {
+            fprintf (stderr, "out of memory in iplane_to_portablecut\n");
+            exit (1);
+        }
+        for (ipp = c->handles, k = 0; ipp; ipp = ipp->next) {
+            for (ip = ipp->this; ip; ip = ip->next)
+                p->handles[k++] = ip->this;
+            p->handles[k++] = -1;
+        }
+    }
+
+    for (ipp = c->teeth, teeth = 0; ipp; ipp = ipp->next)
+        teeth++;
+    p->nteeth = teeth;
+    for (ipp = c->teeth, teethcount = 0; ipp; ipp = ipp->next) {
+        for (ip = ipp->this; ip; ip = ip->next)
+            teethcount++;
+        teethcount++;
+    }
+    p->teeth = CC_SAFE_MALLOC (teethcount, int);
+    if (!p->teeth) {
+        fprintf (stderr, "out of memory in iplane_to_portablecut\n");
+        exit (1);
+    }
+
+    for (ipp = c->teeth, k = 0; ipp; ipp = ipp->next) {
+        for (ip = ipp->this; ip; ip = ip->next)
+            p->teeth[k++] = ip->this;
+        p->teeth[k++] = -1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xfreeteeth (Xnodeptrptr *teeth)
+#else
+void Xfreeteeth (teeth)
+Xnodeptrptr *teeth;
+#endif
+{
+    Xnodeptrptr *ntp;
+
+    for (ntp = teeth; ntp; ntp = ntp->next)
+        Xnodeptr_list_free (ntp->this);
+    Xnodeptrptr_list_free (teeth);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xprintchvatalcomb (Xgraph *G, Xnodeptr *h, Xnodeptrptr *t)
+#else
+void Xprintchvatalcomb (G, h, t)
+Xgraph *G;
+Xnodeptr *h;
+Xnodeptrptr *t;
+#endif
+{
+    Xnodeptr *np;
+    Xnodeptrptr *ntp;
+    int i;
+
+    printf ("HANDLE: ");
+    fflush (stdout);
+    for (np = h; np; np = np->next) {
+        printf ("%d ", (int) (np->this - G->nodelist));
+        fflush (stdout);
+    }
+    printf ("\n");
+    for (i = 0, ntp = t; ntp; ntp = ntp->next, i++) {
+        printf ("TOOTH[%d]: ", i);
+        fflush (stdout);
+        for (np = ntp->this; np; np = np->next) {
+            printf ("%d ", (int) (np->this - G->nodelist));
+            fflush (stdout);
+        }
+        printf ("\n");
+    }
+    printf ("\n");
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xprintcliquetree (Xgraph *G, Xnodeptrptr *h, Xnodeptrptr *t)
+#else
+void Xprintcliquetree (G, h, t)
+Xgraph *G;
+Xnodeptrptr *h, *t;
+#endif
+{
+    Xnodeptr *np;
+    Xnodeptrptr *ntp;
+    int i;
+
+    for (i = 0, ntp = h; ntp; ntp = ntp->next, i++) {
+        printf ("HANDLE[%d]: ", i);
+        fflush (stdout);
+        for (np = ntp->this; np; np = np->next) {
+            printf ("%d ", (int) (np->this - G->nodelist));
+            fflush (stdout);
+        }
+        printf ("\n");
+    }
+    for (i = 0, ntp = t; ntp; ntp = ntp->next, i++) {
+        printf ("TOOTH[%d]: ", i);
+        fflush (stdout);
+        for (np = ntp->this; np; np = np->next) {
+            printf ("%d ", (int) (np->this - G->nodelist));
+            fflush (stdout);
+        }
+        printf ("\n");
+    }
+    printf ("\n");
+}
+
+/* Format  #handles  #teeth  (handle) -1  (handle) -1 ... (tooth) -1 ... */
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xdumpchvatalcomb (FILE *out, Xintptr *h, Xintptrptr *t)
+#else
+void Xdumpchvatalcomb (out, h, t)
+FILE *out;
+Xintptr *h;
+Xintptrptr *t;
+#endif
+{
+    Xintptr *ip;
+    Xintptrptr *itp;
+    int nteeth;
+
+    for (nteeth = 0, itp = t; itp; itp = itp->next)
+        nteeth++;
+
+    fprintf (out, "1 %d  ", nteeth);
+    for (ip = h; ip; ip = ip->next)
+        fprintf (out, "%d ", ip->this);
+    fprintf (out, "%d ", -1);
+    for (itp = t; itp; itp = itp->next) {
+        for (ip = itp->this; ip; ip = ip->next)
+            fprintf (out, "%d ", ip->this);
+        fprintf (out, "%d ", -1);
+    }
+    fprintf (out, "\n");
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xdumpcliquetree (FILE *out, Xintptrptr *h, Xintptrptr *t)
+#else
+void Xdumpcliquetree (out, h, t)
+FILE *out;
+Xintptrptr *h;
+Xintptrptr *t;
+#endif
+{
+    Xintptr *ip;
+    Xintptrptr *itp;
+    int nteeth, nhandles;
+
+    for (nhandles = 0, itp = h; itp; itp = itp->next)
+        nhandles++;
+    for (nteeth = 0, itp = t; itp; itp = itp->next)
+        nteeth++;
+
+    fprintf (out, "%d  ", nhandles);
+    fprintf (out, "%d  ", nteeth);
+    for (itp = h; itp; itp = itp->next) {
+        for (ip = itp->this; ip; ip = ip->next)
+            fprintf (out, "%d ", ip->this);
+        fprintf (out, "%d ", -1);
+    }
+    for (itp = t; itp; itp = itp->next) {
+        for (ip = itp->this; ip; ip = ip->next)
+            fprintf (out, "%d ", ip->this);
+        fprintf (out, "%d ", -1);
+    }
+    fprintf (out, "\n");
+}
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xflow.c b/contrib/blossom/concorde97/XSTUFF/Xflow.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e563776bcac5b0013891665182929321a40c3fd
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xflow.c
@@ -0,0 +1,536 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTION:                                                     */
+/*                                                                        */
+/*    double flow ();                                                     */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    relabel (Xnode *),
+    setlabels (Xgraph *G, Xnode *, Xnode *),
+    backwards_bfs (Xnode *, int),
+    addtoq (Xnodeset *, Xnode *),
+    dfs2 (Xgraph *G, Xnode *start),
+    marknode (Xnode *n, int v);
+
+static int
+    subtourcuts (Xgraph *G, Xcplane **list),
+    connectcuts (Xgraph *G, Xcplane **list),
+    dfs (Xgraph *G, Xnode *start);
+
+static Xnode
+    *push (Xnode *, Xedge *),
+    *popfromq (Xnodeset *);
+
+#else
+
+static void
+    relabel (),
+    setlabels (),
+    backwards_bfs (),
+    addtoq (),
+    dfs2 (),
+    marknode ();
+
+static int
+    subtourcuts (),
+    connectcuts (),
+    dfs ();
+
+static Xnode
+    *push (),
+    *popfromq ();
+
+#endif
+
+#define INFINITY (1<<30)
+
+#ifdef CC_PROTOTYPE_ANSI
+double Xflow (Xgraph *G, Xnode *s, Xnode *t, double bound)
+#else
+double Xflow (G, s, t, bound)
+Xgraph *G;
+Xnode *s, *t;
+double bound;
+#endif
+{
+    Xnodeset q;
+    Xnode *n, *n1;
+    Xedge *e;
+    int savelabel;
+    Xedgeptr *ep;
+    int count, round;
+
+    q.head = q.tail = (Xnodeptr *) NULL;
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        n->excess = 0.0;
+        n->active = 0;
+        n->current = n->cadj.head;
+        n->flowlabel = 0;
+        for (ep = n->cadj.head; ep; ep = ep->next)
+            ep->this->flow = 0.0;
+    }
+    setlabels (G, s, t);
+    t->active = 1;              /* a lie, which keeps t off the active queue */
+    for (ep = s->cadj.head; ep; ep = ep->next) {
+        e = ep->this;
+        if (!e->stay)
+            continue;
+        if (e->cends[0] == s) {
+            e->flow = e->x;
+            if (e->x > 0.0) {
+                e->cends[1]->excess += e->x;
+                addtoq (&q, e->cends[1]);
+            }
+        } else {
+            e->flow = -e->x;
+            if (e->x > 0.0) {
+                e->cends[0]->excess += e->x;
+                addtoq (&q, e->cends[0]);
+            }
+        }
+    }
+    count = 0;
+    round = G->npseudonodes / 2;
+    while (q.head && t->excess < bound) {
+        if (count == round) {
+            setlabels (G, s, t);
+            count = 0;
+        } else
+            count++;
+        n = popfromq (&q);
+        n->active = 0;
+        savelabel = n->flowlabel;
+        do {
+            ep = n->current;
+            if ((n1 = push (n, ep->this)) != (Xnode *) NULL)
+                addtoq (&q, n1);
+            else {
+                n->current = ep->next;
+                if (!n->current) {
+                    n->current = n->cadj.head;
+                    relabel (n);
+                }
+            }
+        } while (n->excess > 0.0 && n->flowlabel == savelabel);
+        if (n->excess > 0.0 && n->flowlabel < G->npseudonodes)
+            addtoq (&q, n);
+    }
+
+    while (q.head) {
+        popfromq (&q);
+    }
+
+    return t->excess;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void relabel (Xnode *n)
+#else
+static void relabel (n)
+Xnode *n;
+#endif
+{
+    int m = INFINITY;
+    Xedgeptr *ep;
+    Xedge *e;
+    int t;
+
+    for (ep = n->cadj.head; ep; ep = ep->next) {
+        e = ep->this;
+        if (n == e->cends[0]) {
+            if (e->x - e->flow > 0.0 && (t = e->cends[1]->flowlabel) < m)
+                m = t;
+        } else {
+            if (e->x + e->flow > 0.0 && (t = e->cends[0]->flowlabel) < m)
+                m = t;
+        }
+    }
+    n->flowlabel = m + 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xnode *push (Xnode *n, Xedge *e)
+#else
+static Xnode *push (n, e)
+Xnode *n;
+Xedge *e;
+#endif
+{
+    Xnode *n1;
+    double rf;
+
+    if (e->cends[0] == n) {
+        n1 = e->cends[1];
+        rf = e->x - e->flow;
+        if (n->flowlabel == n1->flowlabel + 1 && rf > 0.0) {
+            if (n->excess < rf)
+                rf = n->excess;
+            n->excess -= rf;
+            e->flow += rf;
+            n1->excess += rf;
+            return n1;
+        } else
+            return 0;
+    } else {
+        n1 = e->cends[0];
+        rf = e->x + e->flow;
+        if (n->flowlabel == n1->flowlabel + 1 && rf > 0.0) {
+            if (n->excess < rf)
+                rf = n->excess;
+            n->excess -= rf;
+            e->flow -= rf;
+            n1->excess += rf;
+            return n1;
+        } else
+            return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void setlabels (Xgraph *G, Xnode *s, Xnode *t)
+#else
+static void setlabels (G, s, t)
+Xgraph *G;
+Xnode *s, *t;
+#endif
+{
+    G->magicnum++;
+    t->flowlabel = 0;
+    backwards_bfs (t, G->magicnum);
+    s->flowlabel = G->npseudonodes;
+
+    if (s->magiclabel == G->magicnum)
+        return;
+    else
+        backwards_bfs (s, G->magicnum);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void backwards_bfs (Xnode *s, int K)
+#else
+static void backwards_bfs (s, K)
+Xnode *s;
+int K;
+#endif
+{
+    Xnode *this, *next, *tail;
+    Xedge *e;
+    Xedgeptr *ep;
+    int dist;
+
+    s->magiclabel = K;
+    next = s;
+    s->tnext = (Xnode *) NULL;
+    do {
+        for (this = next, next = (Xnode *) NULL; this; this = this->tnext) {
+            dist = this->flowlabel + 1;
+            for (ep = this->cadj.head; ep; ep = ep->next) {
+                e = ep->this;
+                if (this == e->cends[0]) {
+                    tail = e->cends[1];
+                    if (tail->magiclabel != K &&
+                        e->x + e->flow > 0.0) {
+                        tail->flowlabel = dist;
+                        tail->tnext = next;
+                        next = tail;
+                        tail->magiclabel = K;
+                    }
+                } else {
+                    tail = e->cends[0];
+                    if (tail->magiclabel != K &&
+                        e->x - e->flow > 0.0) {
+                        tail->flowlabel = dist;
+                        tail->tnext = next;
+                        next = tail;
+                        tail->magiclabel = K;
+                    }
+                }
+            }
+        }
+    } while (next);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void addtoq (Xnodeset *q, Xnode *n)
+#else
+static void addtoq (q, n)
+Xnodeset *q;
+Xnode *n;
+#endif
+{
+    Xnodeptr *newn;
+
+    if (!n->active) {
+        newn = Xnodeptralloc ();
+        newn->next = (Xnodeptr *) NULL;
+        newn->this = n;
+        if (q->tail) {
+            q->tail->next = newn;
+        } else {
+            q->head = newn;
+        }
+        q->tail = newn;
+        n->active = 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xnode *popfromq (Xnodeset *q)
+#else
+static Xnode *popfromq (q)
+Xnodeset *q;
+#endif
+{
+    Xnodeptr *newn = q->head;
+    Xnode *n = newn->this;
+
+    q->head = newn->next;
+    if (!q->head)
+        q->tail = (Xnodeptr *) NULL;
+    Xnodeptrfree (newn);
+    return n;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int subtourcuts (Xgraph *G, Xcplane **list)
+#else
+static int subtourcuts (G, list)
+Xgraph *G;
+Xcplane **list;
+#endif
+{
+    Xnode *n, *nnext;
+    int returnval = 0;
+
+    for (n = G->pseudonodelist->next->next; n; n = nnext) {
+        /* printf ("o"); fflush (stdout); */
+
+        nnext = n->next;
+        if (Xflow (G, G->pseudonodelist->next, n, XCUTTWO) < XCUTTWO) {
+            G->magicnum++;
+            dfs2 (G, n);
+            returnval += Xloadcplane_cut (G, list, G->magicnum);
+            /* printf ("i"); fflush (stdout); */
+            Xsimpleshrink (G, G->pseudonodelist->next, n);
+        }
+    }
+    /* printf ("\n"); */
+    return returnval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dfs2 (Xgraph *G, Xnode *start)
+#else
+static void dfs2 (G, start)
+Xgraph *G;
+Xnode *start;
+#endif
+{
+    Xedgeptr *epp;
+    Xedge *ep;
+    Xnodeptr *next, *queue = (Xnodeptr *) NULL;
+    Xnode *n;
+
+    marknode (start, G->magicnum);
+    Xadd_nodeptr (&queue, start);
+
+    while (queue) {
+        n = queue->this;
+        next = queue->next;
+        Xnodeptrfree (queue);
+        queue = next;
+        for (epp = n->cadj.head; epp; epp = epp->next) {
+            ep = epp->this;
+            if (ep->cends[0] == n) {
+                if (ep->x + ep->flow > 0.0 &&
+                    ep->cends[1]->magiclabel != G->magicnum) {
+                    marknode (ep->cends[1], G->magicnum);
+                    Xadd_nodeptr (&queue, ep->cends[1]);
+                }
+            } else {
+                if (ep->x - ep->flow > 0.0 &&
+                    ep->cends[0]->magiclabel != G->magicnum) {
+                    marknode (ep->cends[0], G->magicnum);
+                    Xadd_nodeptr (&queue, ep->cends[0]);
+                }
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void marknode (Xnode *n, int v)
+#else
+static void marknode (n, v)
+Xnode *n;
+int v;
+#endif
+{
+    Xnodeptr *np;
+
+    n->magiclabel = v;
+    for (np = n->base.head; np; np = np->next) {
+        np->this->magiclabel = v;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xexactcutcheck (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xexactcutcheck (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    int i, hit;
+
+    Xloadx (G, x);
+    Xbuildpseudonodelist (G, 0);
+    i = Xshrinkprocess (G, list);
+/*
+    printf ("%d heavy-edge cut(s), np = %d\n", i, G->npseudonodes);
+    fflush (stdout);
+*/
+    if (i >= XCUTNUM) {
+        Xdestroypseudonodelist (G);
+        return i;
+    }
+    hit = i;
+    Xrebuildcadj (G);
+
+    i = subtourcuts (G, list);
+    /* printf ("%d flow cut(s)\n", i); fflush (stdout); */
+    Xdestroypseudonodelist (G);
+
+    return hit + i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xmincut (Xgraph *G, Xnode *s, Xnode *t, double bound, double *value,
+            int *label)
+#else
+int Xmincut (G, s, t, bound, value, label)
+Xgraph *G;
+Xnode *s, *t;
+double bound, *value;
+int *label;
+#endif
+{
+    /* Uses the x field as capacities. If min cut from s to t has */
+    /* value < bound it returns 1 and marks nodes in cut with     */
+    /* magiclabel equal to label.  value get the capacity of cut. */
+
+    *value = Xflow (G, s, t, bound);
+    if (*value >= bound)
+        return 0;
+    else {
+        G->magicnum++;
+        dfs2 (G, t);
+        *label = G->magicnum;
+        return 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xrunconnectcuts (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xrunconnectcuts (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    int i;
+
+    Xloadx (G, x);
+    Xbuildpseudonodelist (G, 0);
+    i = connectcuts (G, list);
+    Xdestroypseudonodelist (G);
+
+    fflush (stdout);
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int connectcuts (Xgraph *G, Xcplane **list)
+#else
+static int connectcuts (G, list)
+Xgraph *G;
+Xcplane **list;
+#endif
+{
+    int val, ccount = 0, count, track = 1;
+    Xnode *n;
+
+    val = ++(G->magicnum);
+    if ((count = dfs (G, G->pseudonodelist->next)) < G->npseudonodes) {
+        ccount += Xloadcplane_cut (G, list, G->magicnum);
+        n = G->pseudonodelist->next;
+        do {
+            track++;
+            n = n->next;
+            while (n->magiclabel >= val)
+                n = n->next;
+            G->magicnum++;
+            count += dfs (G, n);
+        } while (count < G->npseudonodes);
+
+        if (track > 2) {
+            for (val++; val <= G->magicnum; val++) {
+                ccount += Xloadcplane_cut (G, list, val);
+            }
+            return ccount;
+        } else {
+            return ccount;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int dfs (Xgraph *G, Xnode *start)
+#else
+static int dfs (G, start)
+Xgraph *G;
+Xnode *start;
+#endif
+{
+    int i = 0;
+    Xedgeptr *epp;
+    Xedge *ep;
+    Xnode *n, *n1;
+    Xnodeptr *next, *queue = (Xnodeptr *) NULL;
+
+    marknode (start, G->magicnum);
+    Xadd_nodeptr (&queue, start);
+
+    while (queue) {
+        i++;
+        n = queue->this;
+        next = queue->next;
+        Xnodeptrfree (queue);
+        queue = next;
+        for (epp = n->cadj.head; epp; epp = epp->next) {
+            ep = epp->this;
+            if (ep->stay) {
+                n1 = ep->cends[0];
+                if (n1 == n)
+                    n1 = ep->cends[1];
+                if (n1->magiclabel != G->magicnum) {
+                    marknode (n1, G->magicnum);
+                    Xadd_nodeptr (&queue, n1);
+                }
+            }
+        }
+    }
+    return i;
+}
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xgomhu.c b/contrib/blossom/concorde97/XSTUFF/Xgomhu.c
new file mode 100644
index 0000000000000000000000000000000000000000..af8b4f685e365d2efdc3307e68cff73094aa9794
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xgomhu.c
@@ -0,0 +1,699 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*  Xcuttree_node                                                         */
+/*      *Xgomory_hu (Xgraph *G);                                           */
+/*                                                                        */
+/*  void                                                                  */
+/*      Xcuttree_free (Xcuttree_node *n);                                  */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    addtonodeset (Xnodeset *s, Xnode *n),
+    delfromnodeset (Xnodeset *s, Xnode *n),
+    delfromedgeset (Xedgeset *s, Xedge *e),
+    freenodeset (Xnodeset *s),
+    gh_work (Xgraph *G, Xcuttree_node *n, Xnodeset *nlist, Xnodeset *special),
+    splitset (Xnodeset *s, Xnodeset *a, Xnodeset *b, int n),
+    mergeset (Xnodeset *s, Xnodeset *a),
+    shrinkdown (Xnodeset *a, Xnode *pseudo, Xedgeset *esave, int num),
+    unshrink (Xnode *pseudo, Xedgeset *esave, int num),
+    paint (Xgraph *G, Xnode *n, int v);
+
+static int
+    countdescendants (Xcuttree_node *n),
+    myrandnum (int n);
+
+#else
+
+static void
+    addtonodeset (),
+    delfromnodeset (),
+    delfromedgeset (),
+    freenodeset (),
+    gh_work (),
+    splitset (),
+    mergeset (),
+    shrinkdown (),
+    unshrink (),
+    paint ();
+
+static int
+    countdescendants (),
+    myrandnum ();
+
+#endif
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void
+    dumpcutcadj (Xgraph *G),
+#else
+static void
+    dumpcutcadj (),
+#endif
+#endif
+
+/*
+ gomory_hu returns a pointer to the root of a rooted cut tree.  The tree is
+   described by the parent, sibling, and child pointers.
+ cutval is the weight on the cut (or, edge) between a node and its parent.
+ ndescendants is the total number of nodes in the subtree rooted at that
+   node, including itself.  This is the size of the cut between that node and
+   its parent.
+ special is the special node for this node of the tree.
+ nlist is a nodeset containing all of the nodes of the graph grouped with the
+   special node.  nlist contains special.
+ pseudonode and next are work area.
+ The calling routine should call cuttree_free(root) after it is done with the
+   cuttree.
+
+ gomory_hu constructs the min-cut tree for the nodes with mark = 1.
+ pseudonodelist is the head of a linked list of the nodes in the graph
+*/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+Xcuttree_node *Xgomory_hu (Xgraph *G)
+#else
+Xcuttree_node *Xgomory_hu (G)
+Xgraph *G;
+#endif
+{
+    Xnodeset special;
+    Xnodeset nlist;
+    Xnode *p;
+    Xcuttree_node *root;
+    Xnodeptr *pp;
+
+    /* see if there's anything to do */
+    p = G->pseudonodelist->next;
+    while (p && p->mark != 1)
+        p = p->next;
+    /* BICO: WAS  for (p = pseudonodelist->next; p && p->mark==1; p=p->next);*/
+    /* WHATS THIS? IF ALL NODES ARE MARKED WE GIVE UP? */
+    if (!p) {
+        return 0;
+    }
+    /* initialize root */
+    root = Xcuttree_nodealloc ();
+    root->parent = (Xcuttree_node *) NULL;
+    root->sibling = (Xcuttree_node *) NULL;
+    root->child = (Xcuttree_node *) NULL;
+    root->cutval = 0.0;
+    root->pseudonode = (Xnode *) NULL;
+    root->nlist.head = root->nlist.tail = (Xnodeptr *) NULL;
+
+    /* set up nlist & special */
+    special.head = special.tail = (Xnodeptr *) NULL;
+    nlist.head = nlist.tail = (Xnodeptr *) NULL;
+
+    for (p = G->pseudonodelist->next; p; p = p->next) {
+        addtonodeset (&nlist, p);
+        if (p->mark == 1)
+            addtonodeset (&special, p);
+    }
+
+    if (!special.head) {
+        fprintf (stderr, "Big Whoa, calling initial gh_work\n");
+        exit (1);
+    }
+    gh_work (G, root, &nlist, &special);
+
+    /* restore pseudonodelist */
+    G->npseudonodes = 0;
+    G->pseudonodelist->next = (Xnode *) NULL;
+    G->pseudonodelist->prev = (Xnode *) NULL;
+    for (pp = nlist.head; pp; pp = pp->next) {
+        pp->this->next = G->pseudonodelist->next;
+        if (G->pseudonodelist->next)
+            G->pseudonodelist->next->prev = pp->this;
+        G->pseudonodelist->next = pp->this;
+        pp->this->prev = G->pseudonodelist;
+        G->npseudonodes++;
+    }
+
+    freenodeset (&nlist);
+    freenodeset (&special);
+
+    countdescendants (root);
+
+    root->cutval = XMAXWEIGHT;
+
+    return root;
+}
+
+#ifdef  DEBUG
+#ifdef CC_PROTOTYPE_ANSI
+static void dumpcutcadj (Xgraph *G)
+#else
+static void dumpcutcadj (G)
+Xgraph *G;
+#endif
+{
+    Xnode *p;
+    Xedgeptr *ep;
+
+    printf ("CADJ IN GOMORY_HU:\n");
+    for (p = G->pseudonodelist->next; p; p = p->next) {
+        printf ("NODE %d: ", p - G->nodelist);
+        if (p->mark)
+            printf ("(S) ");
+        for (ep = p->cadj.head; ep; ep = ep->next) {
+            printf ("%d", OTHERCURRENTEND (ep->this, p) - G->nodelist);
+            printf ("(%f) ", ep->this->x);
+        }
+        printf ("\n");
+    }
+}
+#endif /* DEBUG */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void addtonodeset (Xnodeset *s, Xnode *n)
+#else
+static void addtonodeset (s, n)
+Xnodeset *s;
+Xnode *n;
+#endif
+{
+    Xnodeptr *nnew;
+
+    nnew = Xnodeptralloc ();
+    nnew->this = n;
+    nnew->next = s->head;
+    s->head = nnew;
+    if (!s->tail)
+        s->tail = nnew;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void delfromnodeset (Xnodeset *s, Xnode *n)
+#else
+static void delfromnodeset (s, n)
+Xnodeset *s;
+Xnode *n;
+#endif
+{
+    Xnodeptr *oldn, *n1;
+
+    oldn = (Xnodeptr *) NULL;
+    n1 = s->head;
+    while (n1 && n1->this != n) {
+        oldn = n1;
+        n1 = n1->next;
+    }
+    if (!n1) {
+        fprintf (stderr, "Node vanished from sight\n");
+        exit (1);
+    }
+    if (!oldn) {                /* deleting head */
+        s->head = n1->next;
+        if (!s->head)
+            s->tail = (Xnodeptr *) NULL;
+    } else {
+        oldn->next = n1->next;
+        if (!oldn->next)
+            s->tail = oldn;
+    }
+    Xnodeptrfree (n1);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void delfromedgeset (Xedgeset *s, Xedge *e)
+#else
+static void delfromedgeset (s, e)
+Xedgeset *s;
+Xedge *e;
+#endif
+{
+    Xedgeptr *olde, *e1;
+
+    olde = (Xedgeptr *) NULL;
+    e1 = s->head;
+    while (e1 && e1->this != e) {
+        olde = e1;
+        e1 = e1->next;
+    }
+    if (!e1) {
+        fprintf (stderr, "Edge vanished from sight\n");
+        exit (1);
+    }
+    if (!olde) {                /* deleting head */
+        s->head = e1->next;
+        if (!s->head)
+            s->tail = (Xedgeptr *) NULL;
+    } else {
+        olde->next = e1->next;
+        if (!olde->next)
+            s->tail = olde;
+    }
+    Xedgeptrfree (e1);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void freenodeset (Xnodeset *s)
+#else
+static void freenodeset (s)
+Xnodeset *s;
+#endif
+{
+    Xnodeptr *p, *pnext;
+
+    for (p = s->head; p; p = pnext) {
+        pnext = p->next;
+        Xnodeptrfree (p);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcuttree_free (Xcuttree_node *n)
+#else
+void Xcuttree_free (n)
+Xcuttree_node *n;
+#endif
+{
+    Xcuttree_node *p, *pnext;
+
+    for (p = n->child; p; p = pnext) {
+        pnext = p->sibling;
+        Xcuttree_free (p);
+    }
+    freenodeset (&n->nlist);
+    Xcuttree_nodefree (n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int countdescendants (Xcuttree_node *n)
+#else
+static int countdescendants (n)
+Xcuttree_node *n;
+#endif
+{
+    Xcuttree_node *p;
+    int i;
+
+    i = 1;
+    for (p = n->child; p; p = p->sibling)
+        i += countdescendants (p);
+    n->ndescendants = i;
+    return i;
+}
+
+/* gh_work(n) expands the Xcuttree_node n. */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void gh_work (Xgraph *G, Xcuttree_node *n, Xnodeset *nlist,
+             Xnodeset *special)
+#else
+static void gh_work (G, n, nlist, special)
+Xgraph *G;
+Xcuttree_node *n;
+Xnodeset *nlist, *special;
+#endif
+{
+    Xnodeset a_nlist, b_nlist;
+    Xnodeset a_special, b_special;
+    Xcuttree_node *a_cut, *b_cut;
+    Xcuttree_node *cp, *nextcp;
+    Xnodeptr *p;
+    double fv;
+    Xedgeset esave;
+    Xcuttree_node *newcut;
+    Xnode newnode;
+    Xnode *anode = (Xnode *) NULL;
+    Xnode *bnode = (Xnode *) NULL;
+    int i;
+    Xnode *v;
+
+    /* termination cases for the recursion */
+    if (!special->head) {
+        fprintf (stderr, "Whoa, gh_work called with a null special list\n");
+        exit (1);
+    }
+    if (!special->head->next) {
+        ++(G->magicnum);
+        if (n->parent)
+            n->parent->pseudonode->magiclabel = G->magicnum;
+        for (cp = n->child; cp; cp = cp->sibling)
+            cp->pseudonode->magiclabel = G->magicnum;
+        n->special = special->head->this;
+        n->nlist.head = n->nlist.tail = (Xnodeptr *) NULL;
+        for (p = nlist->head; p; p = p->next)
+            if (p->this->magiclabel != G->magicnum)
+                addtonodeset (&n->nlist, p->this);
+        return;
+    }
+    /* find the split */
+
+    /* set up G->pseudonodelist so flow is happy */
+    G->npseudonodes = 0;
+    G->pseudonodelist->next = (Xnode *) NULL;
+    for (p = nlist->head; p; p = p->next) {
+        p->this->next = G->pseudonodelist->next;
+        G->pseudonodelist->next = p->this;
+        G->npseudonodes++;
+    }
+
+    for (p = special->head, i = 0; p; p = p->next) {
+        i++;
+        if (myrandnum (i) == 0)
+            anode = p->this;
+    }
+
+    for (p = special->head, i = 0; p; p = p->next) {
+        if (p->this != anode) {
+            i++;
+            if (myrandnum (i) == 0)
+                bnode = p->this;
+        }
+    }
+
+    fv = Xflow (G, anode, bnode, 1.0e10);
+
+    paint (G, bnode, ++(G->magicnum));
+
+    /* make the two new cuttree_nodes */
+
+    /* divide them up */
+    splitset (nlist, &a_nlist, &b_nlist, G->magicnum);
+    splitset (special, &a_special, &b_special, G->magicnum);
+
+    if (!a_special.head) {
+        fprintf (stderr, "Yipes! a_special is null\n");
+        if (!b_special.head)
+            fprintf (stderr, "And so is b_special\n");
+        exit (1);
+    } else if (!b_special.head) {
+        fprintf (stderr, "Yipes! b_special is null\n");
+        printf ("SPECIAL: ");
+        for (p = a_special.head; p; p = p->next)
+            printf ("%d ", (int) (p->this - G->nodelist));
+        printf ("\n");
+        printf ("anode = %d  bnode = %d\n", (int) (anode - G->nodelist),
+                (int) (bnode - G->nodelist));
+        printf ("flow value = %f\n", fv);
+        printf ("npseudonodes = %d\n", G->npseudonodes);
+        Xdumppseudograph (G);
+        fv = Xflow (G, anode, bnode, 10.0);
+        printf ("new flow value = %f\n", fv);
+        fflush (stdout);
+        paint (G, bnode, ++(G->magicnum));
+        printf ("MIN CUT: ");
+        fflush (stdout);
+        for (v = G->pseudonodelist->next; v; v = v->next)
+            if (v->magiclabel == G->magicnum) {
+                printf ("%d ", (int) (v - G->nodelist));
+                fflush (stdout);
+            }
+        printf ("\n");
+        Xdumppseudograph_edgelist (G);
+        exit (1);
+    }
+    newcut = Xcuttree_nodealloc ();
+    newcut->parent = n;
+    newcut->sibling = (Xcuttree_node *) NULL;
+    newcut->child = (Xcuttree_node *) NULL;
+    newcut->cutval = fv;
+    newcut->nlist.head = newcut->nlist.tail = (Xnodeptr *) NULL;
+
+    if (n->parent && n->parent->pseudonode->magiclabel == G->magicnum) {
+        a_cut = n;
+        b_cut = newcut;
+    } else {
+        a_cut = newcut;
+        b_cut = n;
+    }
+
+    /* divide the children up between the two sides */
+    for (cp = n->child, n->child = (Xcuttree_node *) NULL,
+                   newcut->child = (Xcuttree_node *) NULL; cp; cp = nextcp) {
+        nextcp = cp->sibling;
+        if (cp->pseudonode->magiclabel == G->magicnum) {
+            cp->sibling = a_cut->child;
+            a_cut->child = cp;
+        } else {
+            cp->sibling = b_cut->child;
+            b_cut->child = cp;
+        }
+    }
+    newcut->sibling = n->child;
+    n->child = newcut;
+
+    newnode.magiclabel = 0;
+    newnode.stacklabel = 0;
+    shrinkdown (&a_nlist, &newnode, &esave, G->magicnum);
+
+    a_cut->pseudonode = (Xnode *) NULL;
+    b_cut->pseudonode = &newnode;
+
+    addtonodeset (&a_nlist, &newnode);
+
+    gh_work (G, a_cut, &a_nlist, &a_special);
+
+    delfromnodeset (&a_nlist, &newnode);
+
+    ++(G->magicnum);
+    for (p = b_nlist.head; p; p = p->next)
+        p->this->magiclabel = G->magicnum;
+
+    unshrink (&newnode, &esave, G->magicnum);
+
+    shrinkdown (&b_nlist, &newnode, &esave, G->magicnum);
+
+    a_cut->pseudonode = &newnode;
+    b_cut->pseudonode = (Xnode *) NULL;
+
+    addtonodeset (&b_nlist, &newnode);
+
+    gh_work (G, b_cut, &b_nlist, &b_special);
+
+    delfromnodeset (&b_nlist, &newnode);
+
+    ++(G->magicnum);
+    for (p = a_nlist.head; p; p = p->next)
+        p->this->magiclabel = G->magicnum;
+
+    unshrink (&newnode, &esave, G->magicnum);
+
+    nlist->head = a_nlist.head;
+    nlist->tail = a_nlist.tail;
+    mergeset (nlist, &b_nlist);
+
+    special->head = a_special.head;
+    special->tail = a_special.tail;
+    mergeset (special, &b_special);
+
+    return;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void splitset (Xnodeset *s, Xnodeset *a, Xnodeset *b, int n)
+#else
+static void splitset (s, a, b, n)
+Xnodeset *s, *a, *b;
+int n;
+#endif
+{
+    Xnodeptr *p;
+    Xnodeptr *pnext;
+
+    a->head = a->tail = (Xnodeptr *) NULL;
+    b->head = b->tail = (Xnodeptr *) NULL;
+    for (p = s->head; p; p = pnext) {
+        pnext = p->next;
+        if (p->this->magiclabel == n) {
+            p->next = a->head;
+            a->head = p;
+            if (!a->tail)
+                a->tail = p;
+        } else {
+            p->next = b->head;
+            b->head = p;
+            if (!b->tail)
+                b->tail = p;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void mergeset (Xnodeset *s, Xnodeset *a)
+#else
+static void mergeset (s, a)
+Xnodeset *s, *a;
+#endif
+{
+    Xnodeptr *p;
+    Xnodeptr *pnext;
+
+    for (p = a->head; p; p = pnext) {
+        pnext = p->next;
+        p->next = s->head;
+        s->head = p;
+        if (!s->tail)
+            s->tail = p;
+    }
+}
+
+/* shrink everything with G->magicnum != num to pseudo. a is a list of
+ * everything with G->magicnum == num. */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void shrinkdown (Xnodeset *a, Xnode *pseudo, Xedgeset *esave, int num)
+#else
+static void shrinkdown (a, pseudo, esave, num)
+Xnodeset *a;
+Xnode *pseudo;
+Xedgeset *esave;
+int num;
+#endif
+{
+    Xedgeset enew;
+    Xnodeptr *p;
+    Xedgeptr *e, *enext;
+    Xnode *x;
+    double cumx;
+
+    pseudo->cadj.head = pseudo->cadj.tail = (Xedgeptr *) NULL;
+    esave->head = esave->tail = (Xedgeptr *) NULL;
+    for (p = a->head; p; p = p->next) {
+        cumx = 0.0;
+        enew.head = enew.tail = (Xedgeptr *) NULL;
+        for (e = p->this->cadj.head; e; e = enext) {
+            enext = e->next;
+            x = OTHERCURRENTEND (e->this, p->this);
+            if (x->magiclabel != num) {
+                cumx += e->this->x;
+                e->next = esave->head;
+                esave->head = e;
+                if (!esave->tail)
+                    esave->tail = e;
+            } else {
+                e->next = enew.head;
+                enew.head = e;
+                if (!enew.tail)
+                    enew.tail = e;
+            }
+        }
+        if (cumx > 0.0) {
+            e = Xedgeptralloc ();
+            e->this = Xedgealloc ();
+            e->next = enew.head;
+            enew.head = e;
+            if (!enew.tail)
+                enew.tail = e;
+            e->this->cends[0] = p->this;
+            e->this->cends[1] = pseudo;
+            e->this->x = cumx;
+            e->this->stay = 1;
+            e = Xedgeptralloc ();
+            e->this = enew.head->this;
+            e->next = pseudo->cadj.head;
+            pseudo->cadj.head = e;
+            if (!pseudo->cadj.tail)
+                pseudo->cadj.tail = e;
+        }
+        p->this->cadj.head = enew.head;
+        p->this->cadj.tail = enew.tail;
+    }
+}
+
+/* unshrink pseudo.  everything inside pseudo has been marked with num */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void unshrink (Xnode *pseudo, Xedgeset *esave, int num)
+#else
+static void unshrink (pseudo, esave, num)
+Xnode *pseudo;
+Xedgeset *esave;
+int num;
+#endif
+{
+    Xedgeptr *e, *enext;
+    Xnode *x;
+
+    /* take out the new edges we added */
+    for (e = pseudo->cadj.head; e; e = enext) {
+        enext = e->next;
+        x = OTHERCURRENTEND (e->this, pseudo);
+        delfromedgeset (&x->cadj, e->this);
+        Xedgefree (e->this);
+        Xedgeptrfree (e);
+    }
+
+    /* put back the edges we deleted */
+    for (e = esave->head; e; e = enext) {
+        enext = e->next;
+        x = e->this->cends[0];
+        if (x->magiclabel == num)
+            x = e->this->cends[1];
+        e->next = x->cadj.head;
+        x->cadj.head = e;
+        if (!x->cadj.tail)
+            x->cadj.tail = e;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void paint (Xgraph *G, Xnode *n, int v)
+#else
+static void paint (G, n, v)
+Xgraph *G;
+Xnode *n;
+int v;
+#endif
+{
+    Xedgeptr *epp;
+    Xedge *ep;
+
+    n->magiclabel = v;
+    for (epp = n->cadj.head; epp; epp = epp->next) {
+        ep = epp->this;
+        if (ep->cends[0] == n) {
+            if (ep->x + ep->flow > 0.0 &&
+                    ep->cends[1]->magiclabel != G->magicnum)
+                paint (G, ep->cends[1], v);
+        } else {
+            if (ep->x - ep->flow > 0.0 &&
+                    ep->cends[0]->magiclabel != G->magicnum)
+                paint (G, ep->cends[0], v);
+        }
+    }
+}
+
+/*
+#define RAND_M 1771875
+#define RAND_A 2416
+#define RAND_C 374441
+
+#ifdef CC_PROTOTYPE_ANSI
+int myrandnum (int n)
+#else
+int myrandnum (n)
+int n;
+#endif
+{
+    static unsigned int seed = 473;
+
+    seed = (seed * RAND_A + RAND_C) % RAND_M;
+    return (n * seed) / RAND_M;
+}
+*/
+
+#ifdef CC_PROTOTYPE_ANSI
+static int myrandnum (int n)
+#else
+static int myrandnum (n)
+int n;
+#endif
+{
+    return (CCutil_lprand () % n);
+}
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xgraph.c b/contrib/blossom/concorde97/XSTUFF/Xgraph.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d5ac7e41d0e4e05546ab794f6e785fa80419b6a
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xgraph.c
@@ -0,0 +1,132 @@
+/**************************************************************************/
+/*                                                                        */
+/*     OLD GRAPH STUFF - Routines for building the old style graphs to    */
+/*                       run the separation routines from concorde.       */
+/*                       The separation routines will not be threadsafe.  */
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    void                                                                */
+/*        Xfreegraph (Xgraph *G)                                          */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xbuildgraph (Xgraph *G, int ncount, int ecount, int *elist, int *elen)
+#else
+int Xbuildgraph (G, ncount, ecount, elist, elen)
+Xgraph *G;
+int ncount;
+int ecount;
+int *elist;
+int *elen;
+#endif
+{
+    Xedge *e;
+    Xedgeptr *e1;
+    int i, k, n1, n2;
+
+    G->edgelist = (Xedge *) NULL;
+    G->nodelist = (Xnode *) NULL;
+    G->pseudonodelist = (Xnode *) NULL;
+    G->pseudoedgelist = (Xedge *) NULL;
+    G->npseudonodes = 0;
+    G->magicnum = 0;
+    G->stacknum = 0;
+    G->magicedgenum = 0;
+
+    G->nnodes = ncount;
+    G->nedges = ecount;
+    G->nodelist = CC_SAFE_MALLOC (ncount, Xnode);
+    if (!G->nodelist)
+        return 1;
+    G->edgelist = CC_SAFE_MALLOC (ecount, Xedge);
+    if (!G->edgelist) {
+        CC_FREE (G->nodelist, Xnode);
+        return 1;
+    }
+
+    for (i = 0; i < ncount; i++) {
+        G->nodelist[i].adj.head = G->nodelist[i].adj.tail = (Xedgeptr *) NULL;
+        G->nodelist[i].magiclabel = 0;
+        G->nodelist[i].stacklabel = 0;
+    }
+    for (i = 0, e = G->edgelist, k = 0; i < ecount; i++, e++) {
+        n1 = elist[k++];
+        n2 = elist[k++];
+        e->weight = elen[i];
+        e->ends[0] = G->nodelist + n1;
+        e->ends[1] = G->nodelist + n2;
+        e->elim = 0;
+        e->weak = 0;
+        e->fixed = 0;
+        e->hold = 0;            /* use 1 to hold original edges in weak
+                                 * remove */
+        e->x = 0.0;
+        e->rc = 0.0;
+        e->magiclabel = 0;
+    }
+
+    for (i = ecount, e = G->edgelist; i; i--, e++) {
+        e1 = Xedgeptralloc ();
+        e1->next = e->ends[0]->adj.head;
+        e1->this = e;
+        e->ends[0]->adj.head = e1;
+        if (e->ends[0]->adj.tail == (Xedgeptr *) NULL)
+            e->ends[0]->adj.tail = e1;
+        e1 = Xedgeptralloc ();
+        e1->next = e->ends[1]->adj.head;
+        e1->this = e;
+        e->ends[1]->adj.head = e1;
+        if (e->ends[1]->adj.tail == (Xedgeptr *) NULL)
+            e->ends[1]->adj.tail = e1;
+    }
+    Xinit_hash_values (G);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xfreegraph (Xgraph *G)
+#else
+void Xfreegraph (G)
+Xgraph *G;
+#endif
+{
+    int i;
+    Xnode *n;
+    Xedgeptr *e, *enext;
+
+    if (G->nodelist) {
+        for (i = G->nnodes, n = G->nodelist; i; i--, n++) {
+            for (e = n->adj.head; e; e = enext) {
+                enext = e->next;
+                Xedgeptrfree (e);
+            }
+            n->adj.head = n->adj.tail = (Xedgeptr *) NULL;
+        }
+        CC_FREE (G->nodelist, Xnode);
+    }
+    if (G->edgelist)
+        CC_FREE (G->edgelist, Xedge);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xloadx (Xgraph *G, double *x)
+#else
+void Xloadx (G, x)
+Xgraph *G;
+double *x;
+#endif
+{
+    double *dp;
+    Xedge *pe;
+    int i;
+
+    for (i = G->nedges, pe = G->edgelist, dp = x; i; i--)
+        pe++->x = *dp++;
+
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xnecklac.c b/contrib/blossom/concorde97/XSTUFF/Xnecklac.c
new file mode 100644
index 0000000000000000000000000000000000000000..caa4da5ebccb9007d8e9e194b5535d7c240c9ee4
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xnecklac.c
@@ -0,0 +1,1930 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTION:                                                     */
+/*        int necklaces(Xcplane **, double *)                              */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+#include "Xpq.h"
+#include "Xnecklac.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    cliquelist_free (Xclique *),
+    necklace_build_neckedges (double *),
+    necklace_build_necklaces (PQ_node *),
+    necklace_build_neckadj (void),
+    necklace_destroy_neckadj (void),
+    label_necklaces (PQ_node *),
+    label_necklaces_work (PQ_node *),
+    label_necklace (PQ_node *),
+    label_edges (PQ_node *, PQ_node *, int),
+    lift_ends (PQ_node *, PQ_node *),
+    lift_edges (PQ_node *, PQ_node *),
+    dump_necklaces (void),
+    dump_necklace_work (PQ_node *),
+    free_equation (Xeqn *),
+    compute_toroots (PQ_node *),
+    free_toroots (PQ_node *),
+    eqn_addto (Xeqn *, Xeqn *),
+    dump_intptr_list (Xintptr *),
+    collect_neck_tooth_leaf (PQ_node *, int, int, Xnodeptr **),
+    collect_neck_tooth_work (PQ_node *, int, int, Xnodeptr **, PQ_node *),
+    binsys_init (bin_system *, int),
+    binsys_elim (bin_system *, Xeqn *),
+    binsys_random_solution (bin_system *),
+    binsys_eval_pivot (bin_system *, Xeqn *),
+    binsys_pop_sparse (bin_system *),
+    binsys_free_system (bin_system *),
+    ds_makeset (PQ_node *);
+
+static int
+    necklace_cuts (double *, Xcplane **, PQ_node *),
+    neckedge_compare (const void *, const void *),
+    count_necklaces (PQ_node *),
+    find_node_label (PQ_node *),
+    necklace_crunch_cuts (PQ_node *, Xcplane **),
+    necklace_add_edge_to_sys (Xneckedge *, bin_system *),
+    necklace_try_solutions (bin_system *, PQ_node *, Xcplane **, Xintptrptr **),
+    find_label (Xintptr *, int),
+    intptr_list_size (Xintptr *),
+    intptrlist_equal (Xintptr *, Xintptr *),
+    find_solution (Xintptr *, Xintptrptr *),
+    necklace_checkout_solution (Xintptr *, PQ_node *, Xcplane **),
+    count_labeled_children (PQ_node *),
+    check_realization (PQ_node *, int, PQ_node **, PQ_node **),
+    collect_necklace_label (PQ_node *),
+    binsys_add_dense (bin_system *, Xeqn *),
+    binsys_add_sparse (bin_system *, Xeqn *),
+    binsys_force_zero (bin_system *, int);
+
+static PQ_node
+    *init_elems (PQ_node *elems),
+    *necklace_build_cuttree (double *),
+    *necklace_build_spantree (void),
+    *ds_find (PQ_node *),
+    *ds_link (PQ_node *, PQ_node *);
+
+static Xeqn
+    *necklace_edge_to_eqn (Xneckedge *);
+
+static Xintptr
+    *intptr_add (Xintptr *, Xintptr *),
+    *intptr_add_destruc (Xintptr *, Xintptr *),
+    *intptr_addto (Xintptr *, Xintptr *),
+    *intptr_copy (Xintptr *),
+    *binsys_random_minimal_solution (bin_system *),
+    *binsys_list_solution (bin_system *);
+
+static Xnodeptr
+    *collect_necklace_tooth (PQ_node *, PQ_node *, PQ_node *, PQ_node *),
+    *collect_necklace_handle (void);
+
+static int
+     add_clique_to_PQtree (Xclique *c, PQ_node *elems);
+static PQ_node
+     *clique_to_PQlist (Xclique *c, PQ_node *elems);
+static int
+     find_intptr_list (Xintptr *p, int n);
+
+#else
+
+static void
+    cliquelist_free (),
+    necklace_build_neckedges (),
+    necklace_build_necklaces (),
+    necklace_build_neckadj (),
+    necklace_destroy_neckadj (),
+    label_necklaces (),
+    label_necklaces_work (),
+    label_necklace (),
+    label_edges (),
+    lift_ends (),
+    lift_edges (),
+    dump_necklaces (),
+    dump_necklace_work (),
+    free_equation (),
+    compute_toroots (),
+    free_toroots (),
+    eqn_addto (),
+    dump_intptr_list (),
+    collect_neck_tooth_leaf (),
+    collect_neck_tooth_work (),
+    binsys_init (),
+    binsys_elim (),
+    binsys_random_solution (),
+    binsys_eval_pivot (),
+    binsys_pop_sparse (),
+    binsys_free_system (),
+    ds_makeset ();
+
+static int
+    necklace_cuts (),
+    neckedge_compare (),
+    count_necklaces (),
+    find_node_label (),
+    necklace_crunch_cuts (),
+    necklace_add_edge_to_sys (),
+    necklace_try_solutions (),
+    find_label (),
+    intptr_list_size (),
+    intptrlist_equal (),
+    find_solution (),
+    necklace_checkout_solution (),
+    count_labeled_children (),
+    check_realization (),
+    collect_necklace_label (),
+    binsys_add_dense (),
+    binsys_add_sparse (),
+    binsys_force_zero ();
+
+static PQ_node
+    *init_elems (),
+    *necklace_build_cuttree (),
+    *necklace_build_spantree (),
+    *ds_find (),
+    *ds_link ();
+
+static Xeqn
+    *necklace_edge_to_eqn ();
+
+static Xintptr
+    *intptr_add (),
+    *intptr_add_destruc (),
+    *intptr_addto (),
+    *intptr_copy (),
+    *binsys_random_minimal_solution (),
+    *binsys_list_solution ();
+
+static Xnodeptr
+    *collect_necklace_tooth (),
+    *collect_necklace_handle ();
+
+static int
+     add_clique_to_PQtree ();
+static PQ_node
+     *clique_to_PQlist ();
+static int
+     find_intptr_list ();
+
+
+#endif
+
+#define NECK_ENUM_CUTOFF 5
+#define NECK_ENUM_NTRIES 50
+#define NECK_NEXTTRY(x) (((x)*2)/3)
+
+static int verbose = 0;
+static int nnecklaces;
+static PQ_node **necklist;
+static Xneckedge *neckedgelist;
+static int nneckedges;
+static PQ_node *necknodelist;
+static int magicneckedgenum = 0;
+static Xgraph *G;
+
+static Xclique *cliquelist = (Xclique *) NULL;
+static int ncliques = 0;
+
+#ifdef CC_PROTOTYPE_ANSI
+int  Xnecklaces (Xgraph *Gin, Xcplane **list, double *x)
+#else
+int  Xnecklaces (Gin, list, x)
+Xgraph *Gin;
+Xcplane **list;
+double *x;
+#endif
+{
+    double szeit;
+    PQ_node *pqroot;
+    int k;
+
+    G = Gin;
+
+    szeit = CCutil_zeit ();
+
+    printf ("CALLED NECKLACE ... (%d, %d)\n", G->nnodes, G->nedges);
+    fflush (stdout);
+
+    pqroot = necklace_build_cuttree (x);
+
+    if (!pqroot) {
+        return 0;
+    }
+
+    k = necklace_cuts (x, list, pqroot);
+
+/*
+    for (c = *list; c; c = c->next)
+        if (c->handles)
+            printcliquetree (c->handles, c->teeth);
+        else
+            printchvatalcomb (c->handle, c->teeth);
+*/
+
+
+    XPQ_free_all (pqroot, 1);
+    CC_FREE (necknodelist, PQ_node);
+
+    printf ("Time in Necklace: %2f\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+    return k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int  necklace_cuts (double *x, Xcplane **list, PQ_node *pqroot)
+#else
+static int  necklace_cuts (x, list, pqroot)
+double *x;
+Xcplane **list;
+PQ_node *pqroot;
+#endif
+{
+    PQ_node *spanroot;
+    int k;
+
+    necklace_build_neckedges (x);
+
+    necklace_build_necklaces (pqroot);
+
+    necklace_build_neckadj ();
+
+    spanroot = necklace_build_spantree ();
+
+    if (!spanroot) {
+        necklace_destroy_neckadj ();
+        CC_FREE (necklist, PQ_node *);
+        CC_FREE (neckedgelist, Xneckedge);
+        return 0;
+    }
+
+    spanroot->toroot = (Xintptr *) NULL;
+    compute_toroots (spanroot);
+
+    k = necklace_crunch_cuts (pqroot, list);
+
+    free_toroots (spanroot);
+    necklace_destroy_neckadj ();
+    CC_FREE (necklist, PQ_node *);
+    CC_FREE (neckedgelist, Xneckedge);
+
+    return k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *necklace_build_cuttree (double *x)
+#else
+static PQ_node *necklace_build_cuttree (x)
+double *x;
+#endif
+{
+    int i;
+    Xclique *cnext;
+    PQ_node *token_elem;
+    double szeit;
+
+    for (i=0; i<G->nedges; i++) {
+        G->edgelist[i].x = x[i];
+    }
+    cliquelist = (Xclique *) NULL;
+    ncliques = 0;
+    szeit = CCutil_zeit ();
+    Xall_tightcuts (G, &cliquelist, &ncliques);
+    printf ("Found %d tight cliques in %.2f seconds\n", ncliques,
+                      CCutil_zeit () - szeit);
+
+    necknodelist = CC_SAFE_MALLOC (G->nnodes, PQ_node);
+    if (!necknodelist) {
+        fprintf (stderr, "out of memory in necklace\n");
+        exit (1);
+    }
+
+    token_elem = init_elems (necknodelist);
+
+    while (cliquelist) {
+        cnext = cliquelist->next;
+        if (!add_clique_to_PQtree (cliquelist, necknodelist)) {
+            XPQ_free_all (token_elem, 1);
+            CC_FREE (necknodelist, PQ_node);
+            cliquelist_free (cliquelist);
+            printf ("ZZZ Necklace bailout\n");
+            fflush (stdout);
+            return (PQ_node *) NULL;
+        }
+        Xintptr_list_free (cliquelist->nodes);
+        Xcliquefree (cliquelist);
+        cliquelist = cnext;
+    }
+    return XPQ_find_root (token_elem);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void cliquelist_free (Xclique *c)
+#else
+static void cliquelist_free (c)
+Xclique *c;
+#endif
+{
+    Xclique *cnext;
+
+    while (c) {
+        cnext = c->next;
+        Xintptr_list_free (c->nodes);
+        Xcliquefree (c);
+        c = cnext;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int neckedge_compare (const void *a, const void *b)
+#else
+static int neckedge_compare (a, b)
+const void *a;
+const void *b;
+#endif
+{
+    if (((const Xneckedge *) a)->x < ((const Xneckedge *) b)->x) {
+        return 1;
+    } else if (((const Xneckedge *) a)->x > ((const Xneckedge *) b)->x) {
+        return -1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void necklace_build_neckedges (double *x)
+#else
+static void necklace_build_neckedges (x)
+double *x;
+#endif
+{
+    int i;
+
+    for (i=0; i<G->nnodes; i++) {
+        necknodelist[i].adj = (Xneckedgeptr *) NULL;
+        necknodelist[i].magiclabel = 0;
+    }
+
+    neckedgelist = CC_SAFE_MALLOC (G->nedges, Xneckedge);
+    if (!neckedgelist) {
+        fprintf (stderr, "out of memory in necklace\n");
+        exit (1);
+    }
+    for (i=0, nneckedges = 0; i<G->nedges; i++) {
+        if (x[i] > 0.0) {
+            neckedgelist[nneckedges].x = x[i];
+            neckedgelist[nneckedges].ends[0] = necknodelist + (G->edgelist[i].ends[0] - G->nodelist);
+            neckedgelist[nneckedges].ends[1] = necknodelist + (G->edgelist[i].ends[1] - G->nodelist);
+            neckedgelist[nneckedges].magiclabel = 0;
+            nneckedges++;
+        }
+    }
+    qsort ((char *) neckedgelist, nneckedges, sizeof (Xneckedge), neckedge_compare);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void necklace_build_necklaces (PQ_node *pqroot)
+#else
+static void necklace_build_necklaces (pqroot)
+PQ_node *pqroot;
+#endif
+{
+    int neckspace;
+
+    neckspace = count_necklaces (pqroot);
+
+    necklist = CC_SAFE_MALLOC (neckspace, PQ_node *);
+    if (!necklist) {
+        fprintf (stderr, "out of memory in necklace\n");
+        exit (1);
+    }
+    nnecklaces = 0;
+
+    label_necklaces (pqroot);
+
+    if (nnecklaces != neckspace) {
+        fprintf (stderr, "ZZZ NECKLACE COUNTS WRONG (%d != %d)\n",neckspace, nnecklaces);
+    }
+
+    printf ("%d necklaces found, ",nnecklaces);
+    fflush (stdout);
+
+    if (verbose) {
+        printf ("Necklaces:\n");
+        dump_necklaces ();
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void necklace_build_neckadj (void)
+#else
+static void necklace_build_neckadj ()
+#endif
+{
+    int i;
+
+    for (i=0; i<nneckedges; i++) {
+        Xadd_neckedgeptr (&neckedgelist[i].ends[0]->adj, &neckedgelist[i]);
+        Xadd_neckedgeptr (&neckedgelist[i].ends[1]->adj, &neckedgelist[i]);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void necklace_destroy_neckadj (void)
+#else
+static void necklace_destroy_neckadj ()
+#endif
+{
+    int i;
+
+    for (i=0; i<G->nnodes; i++) {
+        Xneckedgeptr_list_free (necknodelist[i].adj);
+        necknodelist[i].adj = (Xneckedgeptr *) NULL;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int count_necklaces (PQ_node *x)
+#else
+static int count_necklaces (x)
+PQ_node *x;
+#endif
+{
+    int cnt = 0;
+    PQ_node *z, *zprev, *znext;
+    int childcount = 0;
+
+    PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+        cnt += count_necklaces (z);
+        childcount++;
+    }
+    if (x->type == Q_NODE || (x->type == P_NODE && childcount == 2)) {
+        cnt++;
+    }
+    return cnt;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void label_necklaces (PQ_node *pqroot)
+#else
+static void label_necklaces (pqroot)
+PQ_node *pqroot;
+#endif
+{
+    int i;
+
+    for (i=0; i<nneckedges; i++) {
+        neckedgelist[i].cends[0] = neckedgelist[i].ends[0];
+        neckedgelist[i].cends[1] = neckedgelist[i].ends[1];
+        neckedgelist[i].necklabel = -1;
+    }
+
+    necklace_build_neckadj ();
+
+    label_necklaces_work (pqroot);
+/* label_necklaces_work destroys neckadj except for pqroot and magicnode */
+    Xneckedgeptr_list_free (pqroot->adj);
+    pqroot->adj = (Xneckedgeptr *) NULL;
+    Xneckedgeptr_list_free (necknodelist[MAGICNODE].adj);
+    necknodelist[MAGICNODE].adj = (Xneckedgeptr *) NULL;
+
+    assert (nnecklaces < G->nnodes);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void label_necklaces_work (PQ_node *n)
+#else
+static void label_necklaces_work (n)
+PQ_node *n;
+#endif
+{
+    PQ_node *z;
+    PQ_node *zprev;
+    PQ_node *znext;
+    int cnt;
+
+    cnt = 0;
+    PQ_set_FOREACH (n->children_set, z, children_elem, zprev, znext) {
+        cnt++;
+        label_necklaces_work (z);
+    }
+    n->children_set.size = cnt;
+
+    label_necklace (n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void label_necklace (PQ_node *n)
+#else
+static void label_necklace (n)
+PQ_node *n;
+#endif
+{
+    PQ_node *a, *b, *c;
+
+    if (n->type == Q_NODE || (n->type == P_NODE && PQ_set_SIZE (n->children_set) == 2)) {
+        a = PQ_set_LEFT_ELEM (n->children_set);
+        assert (a);
+        b = a->children_elem.ptr1;
+        if (!b) {
+            b = a->children_elem.ptr2;
+        }
+        assert (b);
+
+        necklist[nnecklaces] = n;
+        label_edges (a, b, nnecklaces);
+        nnecklaces++;
+    }
+
+    if (n->type != LEAF_NODE) {
+        PQ_set_FOREACH (n->children_set, a, children_elem, b, c) {
+            lift_ends (a, n);
+        }
+
+        n->adj = (Xneckedgeptr *) NULL;
+        PQ_set_FOREACH (n->children_set, a, children_elem, b, c) {
+            lift_edges (a, n);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void label_edges (PQ_node *a, PQ_node *b, int n)
+#else
+static void label_edges (a, b, n)
+PQ_node *a;
+PQ_node *b;
+int n;
+#endif
+{
+    Xneckedgeptr *p;
+
+    for (p = a->adj; p; p = p->next) {
+        assert (p->this->cends[0] == a || p->this->cends[1] == a);
+        if (p->this->cends[0] == b || p->this->cends[1] == b) {
+            p->this->necklabel = n;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void lift_ends (PQ_node *a, PQ_node *n)
+#else
+static void lift_ends (a, n)
+PQ_node *a;
+PQ_node *n;
+#endif
+{
+    Xneckedgeptr *p;
+
+    for (p = a->adj; p; p = p->next) {
+        if (p->this->cends[0] == a) {
+            p->this->cends[0] = n;
+        } else {
+            assert (p->this->cends[1] == a);
+            p->this->cends[1] = n;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void lift_edges (PQ_node *a, PQ_node *n)
+#else
+static void lift_edges (a, n)
+PQ_node *a;
+PQ_node *n;
+#endif
+{
+    Xneckedgeptr *p, *pnext;
+
+    for (p = a->adj; p; p = pnext) {
+        pnext = p->next;
+        if (p->this->cends[0] != n || p->this->cends[1] != n) {
+            assert (p->this->cends[0] == n || p->this->cends[1] == n);
+            p->next = n->adj;
+            n->adj = p;
+        } else {
+            Xneckedgeptrfree (p);
+        }
+    }
+    a->adj = (Xneckedgeptr *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_necklaces (void)
+#else
+static void dump_necklaces ()
+#endif
+{
+    int i;
+    PQ_node *z, *znext, *zprev;
+    int j;
+
+    for (i=0; i<nnecklaces; i++) {
+        printf ("%d:",i);
+        PQ_set_FOREACH (necklist[i]->children_set, z, children_elem, zprev, znext) {
+            if (z->type == Q_NODE || (z->type == P_NODE && PQ_set_SIZE (z->children_set) == 2)) {
+                j = find_node_label (z);
+                printf (" %d",j);
+            } else if (z->type == LEAF_NODE) {
+                printf (" n%d",z->number);
+            } else {
+                printf (" (");
+                dump_necklace_work (z);
+                printf (")");
+            }
+        }
+        printf ("\n");
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_necklace_work (PQ_node *x)
+#else
+static void dump_necklace_work (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+    if (x->type == Q_NODE || (x->type == P_NODE && PQ_set_SIZE (x->children_set) == 2)) {
+        printf ("%d ",find_node_label (x));
+    } else if (x->type == LEAF_NODE) {
+        printf ("n%d ",x->number);
+    } else {
+        PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+            dump_necklace_work (z);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_node_label (PQ_node *z)
+#else
+static int find_node_label (z)
+PQ_node *z;
+#endif
+{
+    int i;
+
+    for (i=0; i<nnecklaces; i++) {
+        if (necklist[i] == z) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *necklace_build_spantree (void)
+#else
+static PQ_node *necklace_build_spantree ()
+#endif
+{
+    int i;
+    int k;
+    PQ_node *front, *back, *new;
+    Xneckedge *e;
+    Xneckedgeptr *it;
+    PQ_node *root;
+    int cnt;
+
+    for (i=0; i<G->nnodes; i++) {
+        ds_makeset (&necknodelist[i]);
+    }
+    for (i=0; i<nneckedges; i++) {
+        neckedgelist[i].inspanning = 0;
+    }
+
+    for (i=0, k=G->nnodes-1; k && i < nneckedges; i++) {
+        if (ds_find (neckedgelist[i].ends[0]) != ds_find (neckedgelist[i].ends[1])) {
+            ds_link (ds_find (neckedgelist[i].ends[0]), ds_find (neckedgelist[i].ends[1]));
+            neckedgelist[i].inspanning = 1;
+            k--;
+        }
+    }
+    if (k) {
+        return (PQ_node *) NULL;
+    }
+
+    /* this is a bit clumsy; first we build the spanning tree, then we do
+       a breadth-first search through it to root it */
+
+    G->magicnum++;
+    root = &necknodelist[0];
+    cnt = 0;
+
+    front = root;
+    front->magiclabel = G->magicnum;
+    cnt++;
+    front->entered = (Xneckedge *) NULL;
+    front->next = (PQ_node *) NULL;
+    back = front;
+
+    while (front) {
+        for (it = front->adj; it; it = it->next) {
+            e = it->this;
+            if (e->inspanning) {
+                new = (e->ends[0] == front) ? e->ends[1] : e->ends[0];
+                if (new->magiclabel != G->magicnum) {
+                    new->magiclabel = G->magicnum;
+                    cnt++;
+                    new->entered = e;
+                    back->next = new;
+                    back = new;
+                    back->next = (PQ_node *) NULL;
+                }
+            }
+        }
+        front = front->next;
+    }
+    if (cnt < G->nnodes) {
+        printf ("ZZZ !!!!LOST THE SPANNING TREE!!!!\n");
+        fflush (stdout);
+        return (PQ_node *) NULL;
+    }
+    return root;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int necklace_crunch_cuts (PQ_node *pqroot, Xcplane **list)
+#else
+static int necklace_crunch_cuts (pqroot, list)
+PQ_node *pqroot;
+Xcplane **list;
+#endif
+{
+    bin_system necksys;
+    Xeqn *oneseqn;
+    int i;
+    Xintptr *tmp;
+    int tried;
+    Xintptrptr *found;
+    int k;
+    int trynext;
+    int v;
+
+    binsys_init (&necksys, nnecklaces);
+
+    for (i=0; i<nneckedges; i++) {
+        neckedgelist[i].insystem = neckedgelist[i].inspanning;
+    }
+
+    oneseqn = Xeqnalloc ();
+    oneseqn->lhs = (Xintptr *) NULL;
+    for (i = nnecklaces-1; i>=0; i--) {
+        tmp = Xintptralloc ();
+        tmp->this = i;
+        tmp->next = oneseqn->lhs;
+        oneseqn->lhs = tmp;
+    }
+    oneseqn->rhs = 1;
+
+    if (binsys_add_dense (&necksys, oneseqn) != 1) {
+        fprintf (stderr, "ZZZ ODDNESS CONSTRAINT FAILED\n");
+    }
+    printf ("1"); fflush (stdout);
+
+    found = (Xintptrptr *) NULL;
+    k = 0;
+    trynext = NECK_NEXTTRY (nnecklaces);
+
+    tried = 0;
+    for (i=0; i<nneckedges && necksys.nfreevars > NECK_ENUM_CUTOFF; i++) {
+        if (!neckedgelist[i].inspanning) {
+            v = necklace_add_edge_to_sys (&neckedgelist[i], &necksys);
+            if (v == 1) {
+                neckedgelist[i].insystem = 1;
+                printf ("+"); fflush (stdout);
+                tried = 0;
+                if (necksys.nfreevars <= trynext) {
+                    printf (" (%.2f:%d)",neckedgelist[i].x,necksys.nfreevars);
+                    fflush (stdout);
+                    k += necklace_try_solutions (&necksys, pqroot, list, &found);
+                    printf ("\n"); fflush (stdout);
+                    tried = 1;
+                    trynext = NECK_NEXTTRY (trynext);
+                }
+            } else if (v == 0) {
+                neckedgelist[i].insystem = 1;
+                printf ("."); fflush (stdout);
+            } else {
+                printf ("-"); fflush (stdout);
+            }
+        }
+    }
+    if (!tried) {
+        printf (" (%.2f:%d)",neckedgelist[i-1].x,necksys.nfreevars);
+        fflush (stdout);
+        k += necklace_try_solutions (&necksys, pqroot, list, &found);
+        printf ("\n"); fflush (stdout);
+    }
+
+    Xintptrptr_list_freeall (found);
+    binsys_free_system (&necksys);
+    return k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xeqn *necklace_edge_to_eqn (Xneckedge *e)
+#else
+static Xeqn *necklace_edge_to_eqn (e)
+Xneckedge *e;
+#endif
+{
+    Xeqn *neweqn;
+    Xintptr *tmp;
+
+    neweqn = Xeqnalloc ();
+    neweqn->lhs = intptr_add (e->ends[0]->toroot, e->ends[1]->toroot);
+    if (e->necklabel != -1) {
+        tmp = Xintptralloc ();
+        tmp->this = e->necklabel;
+        tmp->next = (Xintptr *) NULL;
+        neweqn->lhs = intptr_add_destruc (neweqn->lhs, tmp);
+    }
+    neweqn->rhs = 0;
+    return neweqn;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int necklace_add_edge_to_sys (Xneckedge *e, bin_system *s)
+#else
+static int necklace_add_edge_to_sys (e, s)
+Xneckedge *e;
+bin_system *s;
+#endif
+{
+    Xeqn *neweqn;
+
+    neweqn = necklace_edge_to_eqn (e);
+    return binsys_add_sparse (s, neweqn);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int necklace_try_solutions (bin_system *necksys, PQ_node *pqroot, Xcplane **list, Xintptrptr **found)
+#else
+static int necklace_try_solutions (necksys, pqroot, list, found)
+bin_system *necksys;
+PQ_node *pqroot;
+Xcplane **list;
+Xintptrptr **found;
+#endif
+{
+    int i;
+    int k = 0;
+    Xintptr *sollst;
+    Xintptrptr *new;
+
+    for (i=0; i<NECK_ENUM_NTRIES; i++) {
+        sollst = binsys_random_minimal_solution (necksys);
+        if (intptr_list_size (sollst) >= 3 &&
+            !find_solution (sollst, *found)) {
+            new = Xintptrptralloc ();
+            new->this = sollst;
+            new->next = *found;
+            *found = new;
+            k += necklace_checkout_solution (sollst, pqroot, list);
+        } else {
+            Xintptr_list_free (sollst);
+        }
+    }
+    return k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_equation (Xeqn *sys)
+#else
+static void free_equation (sys)
+Xeqn *sys;
+#endif
+{
+    Xintptr_list_free (sys->lhs);
+    Xeqnfree (sys);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void compute_toroots (PQ_node *n)
+#else
+static void compute_toroots (n)
+PQ_node *n;
+#endif
+{
+    Xneckedgeptr *ep;
+    Xneckedge *e;
+    PQ_node *m;
+    Xintptr tmp;
+
+    for (ep = n->adj; ep; ep=ep->next) {
+        if (ep->this->inspanning) {
+            e = ep->this;
+            m = (e->ends[0] == n) ? e->ends[1] : e->ends[0];
+            if (m->entered == e) {
+                if (e->necklabel != -1) {
+                    tmp.this = e->necklabel;
+                    tmp.next = (Xintptr *) NULL;
+                    m->toroot = intptr_add (n->toroot, &tmp);
+                } else {
+                    m->toroot = intptr_copy (n->toroot);
+                }
+                compute_toroots (m);
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_toroots (PQ_node *n)
+#else
+static void free_toroots (n)
+PQ_node *n;
+#endif
+{
+    Xneckedgeptr *ep;
+    Xneckedge *e;
+    PQ_node *m;
+
+    for (ep = n->adj; ep; ep=ep->next) {
+        if (ep->this->inspanning) {
+            e = ep->this;
+            m = (e->ends[0] == n) ? e->ends[1] : e->ends[0];
+            if (m->entered == e) {
+                free_toroots (m);
+            }
+        }
+    }
+    Xintptr_list_free (n->toroot);
+    n->toroot = (Xintptr *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xintptr *intptr_add (Xintptr *a, Xintptr *b)
+#else
+static Xintptr *intptr_add (a, b)
+Xintptr *a;
+Xintptr *b;
+#endif
+{
+    Xintptr *sum;
+    Xintptr **sumend;
+
+    sum = (Xintptr *) NULL;
+    sumend = &sum;
+
+    while (a && b) {
+        if (a->this == b->this) {
+            a = a->next;
+            b = b->next;
+        } else if (a->this < b->this) {
+            *sumend = Xintptralloc ();
+            (*sumend)->this = a->this;
+            sumend = & (*sumend)->next;
+            a = a->next;
+        } else {
+            assert (a->this > b->this);
+            *sumend = Xintptralloc ();
+            (*sumend)->this = b->this;
+            sumend = & (*sumend)->next;
+            b = b->next;
+        }
+    }
+    if (a) {
+        *sumend = intptr_copy (a);
+    } else if (b) {
+        *sumend = intptr_copy (b);
+    } else {
+        *sumend = (Xintptr *) NULL;
+    }
+    return sum;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xintptr *intptr_add_destruc (Xintptr *a, Xintptr *b)
+#else
+static Xintptr *intptr_add_destruc (a, b)
+Xintptr *a;
+Xintptr *b;
+#endif
+{
+    Xintptr *sum;
+    Xintptr **sumend;
+    Xintptr *tnext;
+
+    sum = (Xintptr *) NULL;
+    sumend = &sum;
+
+    while (a && b) {
+        if (a->this == b->this) {
+            tnext = a->next;
+            Xintptrfree (a);
+            a = tnext;
+            tnext = b->next;
+            Xintptrfree (b);
+            b = tnext;
+        } else if (a->this < b->this) {
+            *sumend = a;
+            sumend = &a->next;
+            a = a->next;
+        } else {
+            assert (a->this > b->this);
+            *sumend = b;
+            sumend = &b->next;
+            b = b->next;
+        }
+    }
+    if (a) {
+        *sumend = a;
+    } else if (b) {
+        *sumend = b;
+    } else {
+        *sumend = (Xintptr *) NULL;
+    }
+    return sum;
+}
+
+/* destroys a, but leaves b alone */
+#ifdef CC_PROTOTYPE_ANSI
+static Xintptr *intptr_addto (Xintptr *a, Xintptr *b)
+#else
+static Xintptr *intptr_addto (a, b)
+Xintptr *a;
+Xintptr *b;
+#endif
+{
+    Xintptr *sum;
+    Xintptr **sumend;
+    Xintptr *tnext;
+
+    sum = (Xintptr *) NULL;
+    sumend = &sum;
+
+    while (a && b) {
+        if (a->this == b->this) {
+            tnext = a->next;
+            Xintptrfree (a);
+            a = tnext;
+            b = b->next;
+        } else if (a->this < b->this) {
+            *sumend = a;
+            sumend = &a->next;
+            a = a->next;
+        } else {
+            assert (a->this > b->this);
+            *sumend = Xintptralloc ();
+            (*sumend)->this = b->this;
+            sumend = & (*sumend)->next;
+            b = b->next;
+        }
+    }
+    if (a) {
+        *sumend = a;
+    } else if (b) {
+        *sumend = intptr_copy (b);
+    } else {
+        *sumend = (Xintptr *) NULL;
+    }
+    return sum;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xintptr *intptr_copy (Xintptr *a)
+#else
+static Xintptr *intptr_copy (a)
+Xintptr *a;
+#endif
+{
+    Xintptr *sum;
+    Xintptr **sumend;
+
+    sum = (Xintptr *) NULL;
+    sumend = &sum;
+
+    while (a) {
+        *sumend = Xintptralloc ();
+         (*sumend)->this = a->this;
+        sumend = & (*sumend)->next;
+        a = a->next;
+    }
+    *sumend = (Xintptr *) NULL;
+    return sum;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void eqn_addto (Xeqn *a, Xeqn *b)
+#else
+static void eqn_addto (a, b)
+Xeqn *a;
+Xeqn *b;
+#endif
+{
+    a->lhs = intptr_addto (a->lhs, b->lhs);
+    a->rhs ^= b->rhs;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_intptr_list (Xintptr *p)
+#else
+static void dump_intptr_list (p)
+Xintptr *p;
+#endif
+{
+    if (p) {
+        printf ("%d",p->this);
+        p = p->next;
+    }
+    while (p) {
+        printf (" %d",p->this);
+        p = p->next;
+    }
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_label (Xintptr *e, int label)
+#else
+static int find_label (e, label)
+Xintptr *e;
+int label;
+#endif
+{
+    while (e) {
+        if (e->this == label) return 1;
+        if (e->this > label) return 0;
+        e = e->next;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int intptr_list_size (Xintptr *p)
+#else
+static int intptr_list_size (p)
+Xintptr *p;
+#endif
+{
+    int i;
+
+    for (i=0; p; p = p->next) {
+        i++;
+    }
+    return i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int intptrlist_equal (Xintptr *a, Xintptr *b)
+#else
+static int intptrlist_equal (a, b)
+Xintptr *a;
+Xintptr *b;
+#endif
+{
+    while (a && b) {
+        if (a->this != b->this) {
+            return 0;
+        }
+        a = a->next;
+        b = b->next;
+    }
+    return (a == b);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_solution (Xintptr *sollst, Xintptrptr *found)
+#else
+static int find_solution (sollst, found)
+Xintptr *sollst;
+Xintptrptr *found;
+#endif
+{
+    while (found) {
+        if (intptrlist_equal (sollst, found->this)) {
+            return 1;
+        }
+        found = found->next;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int necklace_checkout_solution (Xintptr *sollst, PQ_node *pqroot, Xcplane **list)
+#else
+static int necklace_checkout_solution (sollst, pqroot, list)
+Xintptr *sollst;
+PQ_node *pqroot;
+Xcplane **list;
+#endif
+{
+    int cnt;
+    Xintptr *p;
+    PQ_node *lefthalf, *righthalf;
+    Xnodeptrptr *teeth;
+    Xnodeptrptr *handles;
+    Xnodeptrptr *npp;
+    int test;
+
+    if (verbose) {
+        printf ("New minimal solution: ");
+        dump_intptr_list (sollst);
+        printf ("\n");
+        fflush (stdout);
+    } else {
+        printf (".");
+        fflush (stdout);
+    }
+
+    G->magicnum++;
+    for (p = sollst, cnt = 0; p; p = p->next) {
+        cnt++;
+        necklist[p->this]->magiclabel = G->magicnum;
+    }
+
+    if (count_labeled_children (pqroot) != cnt) {
+        fprintf (stderr, "Lost some labels\n");
+        exit (1);
+    }
+
+    for (p = sollst; p; p = p->next) {
+        if (!check_realization (necklist[p->this], cnt, &lefthalf, &righthalf)) {
+            if (verbose) {
+                printf ("Unrealizable!!\n");
+            }
+            return 0;
+        }
+    }
+    if (verbose) {
+        printf ("Realizable\n");
+    } else {
+        printf ("+");
+        fflush (stdout);
+    }
+
+    magicneckedgenum++;
+
+    teeth = (Xnodeptrptr *) NULL;
+    for (p = sollst; p; p = p->next) {
+        if (!check_realization (necklist[p->this], cnt, &lefthalf, &righthalf)) {
+            fprintf (stderr, "ZZZ Whoops, necklace broke\n");
+            exit (1);
+        }
+        npp = Xnodeptrptralloc ();
+        npp->this = collect_necklace_tooth (lefthalf, righthalf, necklist[p->this], pqroot);
+        npp->next = teeth;
+        teeth = npp;
+    }
+    handles = Xnodeptrptralloc ();
+    handles->next = (Xnodeptrptr *) NULL;
+    handles->this = collect_necklace_handle ();
+
+    if (!Xcliquefluff (G, &handles, &teeth)) {
+        printf ("ZZZ NECKLACE DE FLUFFED TO 0\n");
+        fflush (stdout);
+        return 0;
+    }
+
+    test = Xloadcplane (list, (Xnodeptr *) NULL, handles, teeth, 0);
+    if (!test) {
+        Xfreeteeth (handles);
+        Xfreeteeth (teeth);
+        printf ("-");
+        fflush (stdout);
+    } else {
+        printf ("YES ");
+        fflush (stdout);
+    }
+
+    return test;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int count_labeled_children (PQ_node *x)
+#else
+static int count_labeled_children (x)
+PQ_node *x;
+#endif
+{
+    int cnt = 0;
+    PQ_node *z, *zprev, *znext;
+
+    PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+        cnt += count_labeled_children (z);
+    }
+    if (x->magiclabel == G->magicnum) {
+        cnt++;
+    }
+    x->labeled_children_count = cnt;
+    return cnt;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_realization (PQ_node *x, int fullcnt, PQ_node **lefthalf, PQ_node **righthalf)
+#else
+static int check_realization (x, fullcnt, lefthalf, righthalf)
+PQ_node *x;
+int fullcnt;
+PQ_node **lefthalf;
+PQ_node **righthalf;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+
+    PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+        if (zprev && z->labeled_children_count == 0 && zprev->labeled_children_count == 0) {
+            *lefthalf = zprev;
+            *righthalf = z;
+            return 1;
+        }
+    }
+    if (x->labeled_children_count == fullcnt) {
+        if (PQ_set_RIGHT_ELEM (x->children_set)->labeled_children_count == 0) {
+            *lefthalf = PQ_set_RIGHT_ELEM (x->children_set);
+            *righthalf = (PQ_node *) NULL;
+            return 1;
+        }
+        if (PQ_set_LEFT_ELEM  (x->children_set)->labeled_children_count == 0) {
+            *lefthalf = PQ_set_LEFT_ELEM (x->children_set);
+            *righthalf = (PQ_node *) NULL;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xnodeptr *collect_necklace_tooth (PQ_node *lefthalf, PQ_node *righthalf, PQ_node *x, PQ_node *pqroot)
+#else
+static Xnodeptr *collect_necklace_tooth (lefthalf, righthalf, x, pqroot)
+PQ_node *lefthalf;
+PQ_node *righthalf;
+PQ_node *x;
+PQ_node *pqroot;
+#endif
+{
+    Xnodeptr *tooth;
+
+    tooth = (Xnodeptr *) NULL;
+
+    if (!lefthalf) {
+        lefthalf = righthalf;
+        righthalf = (PQ_node *) NULL;
+    }
+    G->magicnum++;
+    collect_neck_tooth_work (lefthalf, 0, G->magicnum, &tooth, (PQ_node *) NULL);
+    if (righthalf) {
+        collect_neck_tooth_work (righthalf, 1, G->magicnum, &tooth, (PQ_node *) NULL);
+    } else {
+        collect_neck_tooth_work (pqroot, 1, G->magicnum, &tooth, x);
+        collect_neck_tooth_leaf (&necknodelist[MAGICNODE], 1, G->magicnum, &tooth);
+    }
+    return tooth;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void collect_neck_tooth_leaf (PQ_node *x, int mode, int label, Xnodeptr **list)
+#else
+static void collect_neck_tooth_leaf (x, mode, label, list)
+PQ_node *x;
+int mode;
+int label;
+Xnodeptr **list;
+#endif
+{
+    Xnodeptr *np;
+    Xneckedgeptr *ep;
+    PQ_node *y;
+
+    np = Xnodeptralloc ();
+    np->this = G->nodelist + x->number;
+    np->next = *list;
+    *list = np;
+    if (mode == 0) {
+        x->magiclabel = label;
+    } else {
+        for (ep = x->adj; ep; ep = ep->next) {
+            y = ep->this->ends[0];
+            if (y == x) y = ep->this->ends[1];
+            if (y->magiclabel == label) {
+                ep->this->magiclabel = magicneckedgenum;
+            }
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void collect_neck_tooth_work (PQ_node *x, int mode, int label, Xnodeptr **list, PQ_node *avoid)
+#else
+static void collect_neck_tooth_work (x, mode, label, list, avoid)
+PQ_node *x;
+int mode;
+int label;
+Xnodeptr **list;
+PQ_node *avoid;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+
+    if (x == avoid) return;
+    if (x->type == LEAF_NODE) {
+        collect_neck_tooth_leaf (x, mode, label, list);
+    } else {
+        PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+            collect_neck_tooth_work (z, mode, label, list, avoid);
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xnodeptr *collect_necklace_handle (void)
+#else
+static Xnodeptr *collect_necklace_handle ()
+#endif
+{
+    Xnodeptr *handle;
+    int cnt;
+    Xnodeptr *np;
+    int i;
+
+    G->magicnum++;
+    cnt = collect_necklace_label (necknodelist);
+    handle = (Xnodeptr *) NULL;
+    if (cnt*2 < G->nnodes) {
+        for (i=0; i<G->nnodes; i++) {
+            if (necknodelist[i].magiclabel == G->magicnum) {
+                np = Xnodeptralloc ();
+                np->this = &(G->nodelist[i]);
+                np->next = handle;
+                handle = np;
+            }
+        }
+    } else {
+        for (i=0; i<G->nnodes; i++) {
+            if (necknodelist[i].magiclabel != G->magicnum) {
+                np = Xnodeptralloc ();
+                np->this = &(G->nodelist[i]);
+                np->next = handle;
+                handle = np;
+            }
+        }
+    }
+    return handle;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int collect_necklace_label (PQ_node *x)
+#else
+static int collect_necklace_label (x)
+PQ_node *x;
+#endif
+{
+    int cnt;
+    Xneckedgeptr *ep;
+    PQ_node *y;
+
+    x->magiclabel = G->magicnum;
+    cnt = 1;
+
+    for (ep = x->adj; ep; ep = ep->next) {
+        if (ep->this->magiclabel != magicneckedgenum && ep->this->insystem) {
+            y = ep->this->ends[0];
+            if (y == x) y = ep->this->ends[1];
+            if (y->magiclabel != G->magicnum) {
+                cnt += collect_necklace_label (y);
+            }
+        }
+    }
+    return cnt;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void binsys_init (bin_system *s, int nvars)
+#else
+static void binsys_init (s, nvars)
+bin_system *s;
+int nvars;
+#endif
+{
+    int i;
+
+    s->vars = CC_SAFE_MALLOC (nvars, bin_var);
+    if (!s->vars) {
+        fprintf (stderr, "out of memory in necklace\n");
+        exit (1);
+    }
+
+    for (i=0; i<nnecklaces; i++) {
+        s->vars[i].elim = (Xeqn *) NULL;
+        s->vars[i].value = VALUE_UNKNOWN;
+        s->vars[i].fixed = 0;
+    }
+
+    s->sparselist = (Xeqn *) NULL;
+    s->denseeqn = (Xeqn *) NULL;
+    s->nvars = nvars;
+    s->nfreevars = nvars;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int binsys_add_dense (bin_system *s, Xeqn *e)
+#else
+static int binsys_add_dense (s, e)
+bin_system *s;
+Xeqn *e;
+#endif
+{
+    assert (s->denseeqn == (Xeqn *) NULL);
+    binsys_elim (s, e);
+    if (e->lhs == (Xintptr *) NULL) {
+        if (e->rhs == 0) {
+            Xeqnfree (e);
+            return 0;
+        } else {
+            Xeqnfree (e);
+            return -1;
+        }
+    }
+    s->denseeqn = e;
+    e->next = (Xeqn *) NULL;
+    s->nfreevars--;
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int binsys_add_sparse (bin_system *s, Xeqn *e)
+#else
+static int binsys_add_sparse (s, e)
+bin_system *s;
+Xeqn *e;
+#endif
+{
+    binsys_elim (s, e);
+
+    if (!e->lhs) {
+        if (e->rhs == 0) {
+            free_equation (e);
+            return 0;
+        } else {
+            free_equation (e);
+            return -1;
+        }
+    }
+    if (s->denseeqn && intptrlist_equal (e->lhs, s->denseeqn->lhs)) {
+        if (e->rhs == s->denseeqn->rhs) {
+            free_equation (e);
+            return 0;
+        } else {
+            free_equation (e);
+            return -1;
+        }
+    }
+    e->pivot = e->lhs->this;
+    s->vars[e->pivot].elim = e;
+    if (s->denseeqn && find_label (s->denseeqn->lhs, e->pivot)) {
+        eqn_addto (s->denseeqn, e);
+        assert (s->denseeqn->lhs);
+        e->hitdense = 1;
+    } else {
+        e->hitdense = 0;
+    }
+    e->next = s->sparselist;
+    s->sparselist = e;
+    s->nfreevars--;
+
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void binsys_elim (bin_system *s, Xeqn *e)
+#else
+static void binsys_elim (s, e)
+bin_system *s;
+Xeqn *e;
+#endif
+{
+    Xintptr **p;
+    Xintptr *q;
+    Xeqn *f;
+
+    p = &e->lhs;
+    while ((q = *p) != (Xintptr *) NULL) {
+        if ((f = s->vars[q->this].elim) != (Xeqn *) NULL) {
+            if (f->lhs && f->lhs->this == q->this) {
+                eqn_addto (e, f);
+            } else {
+                eqn_addto (e, f);
+                p = &e->lhs;
+            }
+        } else {
+            p = & (*p)->next;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xintptr *binsys_random_minimal_solution (bin_system *s)
+#else
+static Xintptr *binsys_random_minimal_solution (s)
+bin_system *s;
+#endif
+{
+    Xintptr *sollst;
+    int nadded;
+    int i;
+
+    for (i=0; i<s->nvars; i++) {
+        s->vars[i].fixed = 0;
+    }
+
+    nadded = 0;
+    while (s->nfreevars) {
+        binsys_random_solution (s);
+        for (i=0; i<s->nvars; i++) {
+            if (s->vars[i].value == 0 && !s->vars[i].fixed) {
+                s->vars[i].fixed = 1;
+                if (binsys_force_zero (s, i) == 1) {
+                    nadded++;
+                }
+            }
+        }
+    }
+    binsys_random_solution (s);
+    sollst = binsys_list_solution (s);
+    for (i=0; i<nadded; i++) {
+        binsys_pop_sparse (s);
+    }
+    return sollst;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void binsys_random_solution (bin_system *s)
+#else
+static void binsys_random_solution (s)
+bin_system *s;
+#endif
+{
+    Xeqn *e;
+    int i;
+
+    for (i=0; i<s->nvars; i++) {
+        if (s->vars[i].elim) {
+            s->vars[i].value = VALUE_UNKNOWN;
+        } else {
+            s->vars[i].value = (CCutil_lprand () & 1);
+        }
+    }
+    if (s->denseeqn && s->denseeqn->lhs) {
+        s->denseeqn->pivot = s->denseeqn->lhs->this;
+        binsys_eval_pivot (s, s->denseeqn);
+    }
+    for (e = s->sparselist; e; e = e->next) {
+        binsys_eval_pivot (s, e);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void binsys_eval_pivot (bin_system *s, Xeqn *e)
+#else
+static void binsys_eval_pivot (s, e)
+bin_system *s;
+Xeqn *e;
+#endif
+{
+    int val;
+    Xintptr *p;
+
+    val = e->rhs;
+    for (p = e->lhs; p; p = p->next) {
+        if (p->this != e->pivot) {
+            assert (s->vars[p->this].value != VALUE_UNKNOWN);
+            val ^= s->vars[p->this].value;
+        }
+    }
+    s->vars[e->pivot].value = val;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int binsys_force_zero (bin_system *s, int v)
+#else
+static int binsys_force_zero (s, v)
+bin_system *s;
+int v;
+#endif
+{
+    Xeqn *e = Xeqnalloc ();
+    Xintptr *p;
+
+    e->rhs = 0;
+    p = Xintptralloc ();
+    p->this = v;
+    p->next = (Xintptr *) NULL;
+    e->lhs = p;
+
+    return binsys_add_sparse (s, e);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void binsys_pop_sparse (bin_system *s)
+#else
+static void binsys_pop_sparse (s)
+bin_system *s;
+#endif
+{
+    Xeqn *e;
+
+    e = s->sparselist;
+    s->sparselist = e->next;
+    s->vars[e->pivot].elim = (Xeqn *) NULL;
+    if (e->hitdense && s->denseeqn) {
+        eqn_addto (s->denseeqn, e);
+    }
+    s->nfreevars++;
+    free_equation (e);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xintptr *binsys_list_solution (bin_system *s)
+#else
+static Xintptr *binsys_list_solution (s)
+bin_system *s;
+#endif
+{
+    Xintptr *lst;
+    Xintptr **lstend;
+    Xintptr *new;
+    int i;
+
+    lst = (Xintptr *) NULL;
+    lstend = &lst;
+    for (i=0; i<s->nvars; i++) {
+        if (s->vars[i].value == 1) {
+            new = Xintptralloc ();
+            new->this = i;
+            *lstend = new;
+            lstend = &new->next;
+        }
+    }
+    *lstend = (Xintptr *) NULL;
+    return lst;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void binsys_free_system (bin_system *s)
+#else
+static void binsys_free_system (s)
+bin_system *s;
+#endif
+{
+    Xeqn *e, *enext;
+
+    CC_FREE (s->vars, bin_var);
+
+    for (e = s->sparselist; e; e = enext) {
+        enext = e->next;
+        free_equation (e);
+    }
+    if (s->denseeqn) {
+        free_equation (s->denseeqn);
+    }
+
+    s->vars = (bin_var *) NULL;
+    s->sparselist = (Xeqn *) NULL;
+    s->denseeqn = (Xeqn *) NULL;
+    s->nvars = 0;
+    s->nfreevars = 0;
+}
+
+/* disjoint sets ala Tarjan (from Data Structures and Network Algorithms
+   by Robert Tarjan) */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void ds_makeset (PQ_node *v)
+#else
+static void ds_makeset (v)
+PQ_node *v;
+#endif
+{
+    v->setinfo.parent = v;
+    v->setinfo.rank = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *ds_find (PQ_node *v)
+#else
+static PQ_node *ds_find (v)
+PQ_node *v;
+#endif
+{
+    PQ_node *p = v->setinfo.parent;
+
+    return v == p ? v : (v->setinfo.parent = ds_find (p));
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *ds_link (PQ_node *x, PQ_node *y)
+#else
+static PQ_node *ds_link (x, y)
+PQ_node *x;
+PQ_node *y;
+#endif
+{
+    PQ_node *t;
+    if (x->setinfo.rank > y->setinfo.rank) {
+        SWAP (x,y,t);
+    } else if (x->setinfo.rank == y->setinfo.rank) {
+        y->setinfo.rank++;
+    }
+    x->setinfo.parent = y;
+    return y;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *init_elems (PQ_node *elems)
+#else
+static PQ_node *init_elems (elems)
+PQ_node *elems;
+#endif
+{
+    int i;
+    PQ_node *token;
+
+    for (i = 0, token = (PQ_node *) NULL; i < G->nnodes; i++) {
+        if (i != MAGICNODE) {
+            elems[i].next = token;
+            token = &elems[i];
+        }
+        elems[i].number = i;
+    }
+
+    XPQ_init_tree (token);
+    return token;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_clique_to_PQtree (Xclique *c, PQ_node *elems)
+#else
+static int add_clique_to_PQtree (c, elems)
+Xclique *c;
+PQ_node *elems;
+#endif
+{
+    PQ_node *cut;
+
+    cut = clique_to_PQlist (c, elems);
+    return (XPQ_process (cut) != (PQ_node *) NULL);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *clique_to_PQlist (Xclique *c, PQ_node *elems)
+#else
+static PQ_node *clique_to_PQlist (c, elems)
+Xclique *c;
+PQ_node *elems;
+#endif
+{
+    Xintptr *p;
+    PQ_node *cut;
+    int n;
+
+    if (find_intptr_list (c->nodes, MAGICNODE)) {
+        G->magicnum++;
+        for (p = c->nodes; p; p = p->next) {
+            G->nodelist[p->this].magiclabel = G->magicnum;
+        }
+        for (n = 1, cut = (PQ_node *) NULL; n < G->nnodes; n++) {
+            if (G->nodelist[n].magiclabel != G->magicnum) {
+                elems[n].next = cut;
+                cut = &elems[n];
+            }
+        }
+    } else {
+        for (cut = (PQ_node *) NULL, p = c->nodes; p; p = p->next) {
+            n = p->this;
+            elems[n].next = cut;
+            cut = &elems[n];
+        }
+    }
+    return cut;
+}
+
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_intptr_list (Xintptr *p, int n)
+#else
+static int find_intptr_list (p, n)
+Xintptr *p;
+int n;
+#endif
+{
+    while (p) {
+        if (p->this == n)
+            return 1;
+        p = p->next;
+    }
+    return 0;
+}
+
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xnecklac.h b/contrib/blossom/concorde97/XSTUFF/Xnecklac.h
new file mode 100644
index 0000000000000000000000000000000000000000..e63fd543caab979fc79fe16a435d557e99862479
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xnecklac.h
@@ -0,0 +1,65 @@
+#ifndef __XNECKLAC_H
+#define __XNECKLAC_H
+typedef struct Xneckedge {
+    struct PQ_node *ends[2];
+    struct PQ_node *cends[2];
+    double x;
+    int magiclabel;
+    int insystem;
+    int inspanning;
+    int necklabel;
+    struct Xneckedge *next;
+} Xneckedge;
+
+typedef struct Xneckedgeptr {
+    struct Xneckedge *this;
+    struct Xneckedgeptr *next;
+} Xneckedgeptr;
+
+typedef struct Xeqn {
+    struct Xintptr *lhs;
+    int rhs;
+    struct Xeqn *next;
+    int pivot;
+    int hitdense;
+} Xeqn;
+
+typedef struct bin_var {
+#define VALUE_UNKNOWN (-1)
+    int value;
+    int fixed;
+    struct Xeqn *elim;
+} bin_var;
+
+typedef struct bin_system {
+    int nvars;
+    int nfreevars;
+    struct bin_var *vars;
+    struct Xeqn *sparselist;
+    struct Xeqn *denseeqn;
+} bin_system;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+/* ouralloc.c */
+
+Xeqn *Xeqnalloc (void);
+Xneckedgeptr *Xneckedgeptralloc (void);
+void Xadd_neckedgeptr (Xneckedgeptr **, Xneckedge *);
+void Xeqnfree (Xeqn *);
+void Xneckedgeptrfree (Xneckedgeptr *);
+void Xneckedgeptr_list_free (Xneckedgeptr *);
+
+#else
+
+/* ouralloc.c */
+
+Xeqn *Xeqnalloc ();
+Xneckedgeptr *Xneckedgeptralloc ();
+void Xadd_neckedgeptr ();
+void Xeqnfree ();
+void Xneckedgeptrfree ();
+void Xneckedgeptr_list_free ();
+
+#endif
+#endif /*  __XNECKLAC_H */
diff --git a/contrib/blossom/concorde97/XSTUFF/Xnewkids.c b/contrib/blossom/concorde97/XSTUFF/Xnewkids.c
new file mode 100644
index 0000000000000000000000000000000000000000..863210ca3ed1d997615f1e43bb9a3809426c172c
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xnewkids.c
@@ -0,0 +1,660 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*  int       Xnewkids ()                                                  */
+/*                                                                        */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+#include "Xcutpool.h"
+#include "Xpq.h"
+
+Xgraph *G;
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xsearch_cutpool_for_slack_cliques (Xgraph *H, double maxslack,
+         int request, int *kcount, Xportableclique **klist, int ecount,
+         int *elist, double *x);
+#else
+int Xsearch_cutpool_for_slack_cliques ();
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    free_portableclique (Xportableclique *q),
+    build_weakcliques (double *),
+    gethist (unsigned int *),
+    sortcliquelist (void),
+    mark_clique (Xclique *, int);
+
+static int
+    add_clique_to_PQtree (Xclique *c, PQ_node *elems),
+    add_comblist_to_cutlist (Xclique *[4], Xcplane **),
+    checkout_cliquelist (Xcplane **),
+    find_intptr_list (Xintptr *, int),
+    found_clique_contradiction (Xclique *, Xclique *, Xclique *, Xcplane **),
+    found_comb_contradiction (Xclique *[4], Xcplane **),
+    clique_comp (const void *, const void *);
+
+static PQ_node
+    *init_elems (PQ_node *elems),
+    *clique_to_PQlist (Xclique *, PQ_node *);
+
+static Xclique
+    *add_cliques_to_PQtree (Xclique *, Xclique *, PQ_node *);
+
+#else
+
+static void
+    free_portableclique (),
+    build_weakcliques (),
+    gethist (),
+    sortcliquelist (),
+    mark_clique ();
+
+static int
+    add_clique_to_PQtree (),
+    add_comblist_to_cutlist (),
+    checkout_cliquelist (),
+    find_intptr_list (),
+    found_clique_contradiction (),
+    found_comb_contradiction (),
+    clique_comp ();
+
+static PQ_node
+    *init_elems (),
+    *clique_to_PQlist ();
+
+static Xclique
+    *add_cliques_to_PQtree ();
+
+#endif
+
+static int ncliques = 0;
+static Xclique *cliquelist = (Xclique *) NULL;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xnewkids (Xgraph *Gin, double *x, Xcplane **list)
+#else
+int Xnewkids (Gin, x, list)
+Xgraph *Gin;
+double *x;
+Xcplane **list;
+#endif
+{
+    int ntight, nweak;
+    int i, k;
+    Xclique *c, *cnext;
+
+    G = Gin;
+
+    printf ("CALLED PQ CUTS ... (%d, %d)\n", G->nnodes, G->nedges);
+    fflush (stdout);
+
+    for (i = 0; i < G->nedges; i++) {
+        G->edgelist[i].x = x[i];
+    }
+
+    cliquelist = (Xclique *) NULL;
+    ncliques = 0;
+
+    Xall_tightcuts (G, &cliquelist, &ncliques);
+    ntight = ncliques;
+    printf ("Found %d tight cliques\n", ntight);
+    fflush (stdout);
+
+    for (i = 0; i < G->nedges; i++) {
+        G->edgelist[i].x = x[i];
+    }
+    build_weakcliques (x);
+    nweak = ncliques - ntight;
+    printf ("Found %d weak cliques\n", nweak);
+    fflush (stdout);
+
+    sortcliquelist ();
+    printf ("Sorted cliques\n");
+
+    k = checkout_cliquelist (list);
+    printf ("Checked out cliques\n"); fflush (stdout);
+
+    c = cliquelist;
+    do {
+        cnext = c->next;
+        Xintptr_list_free (c->nodes);
+        Xcliquefree (c);
+        c = cnext;
+    } while (c != cliquelist);
+
+    return k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void build_weakcliques (double *x)
+#else
+static void build_weakcliques (x)
+double *x;
+#endif
+{
+    int ecount;
+    int *elist = (int *) NULL;
+    int etemp = G->nedges;
+    int kcount;
+    Xportableclique *klist = (Xportableclique *) NULL;
+    Xclique *c;
+    Xintptr *ip;
+    int i, j, k;
+
+    ecount = G->nedges;
+    elist = CC_SAFE_MALLOC (2 * G->nedges, int);
+    if (!elist) {
+        fprintf (stderr, "out of memory in build_weakcliques\n");
+        exit (1);
+    }
+    for (i = 0, k = 0; i < etemp; i++) {
+        elist[k++] = G->edgelist[i].ends[0] - G->nodelist;
+        elist[k++] = G->edgelist[i].ends[1] - G->nodelist;
+    }
+    if (Xsearch_cutpool_for_slack_cliques (G, 1.0, 1000000, &kcount, &klist,
+                                           ecount, elist, x)) {
+        fprintf (stderr, "Xsearch_cutpool failed\n");
+        exit (1);
+    }
+
+    for (i = 0; i < kcount; i++) {
+        ncliques++;
+        c = Xcliquealloc ();
+        c->slack = klist[i].cutval;
+        c->nodes = (Xintptr *) NULL;
+        for (j = 0; j < klist[i].size; j++) {
+            ip = Xintptralloc ();
+            ip->this = klist[i].nodes[j];
+            ip->next = c->nodes;
+            c->nodes = ip;
+        }
+        c->next = cliquelist;
+        cliquelist = c;
+        free_portableclique (&(klist[i]));
+    }
+    if (elist)
+        CC_FREE (elist, int);
+    if (klist)
+        CC_FREE (klist, Xportableclique);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *init_elems (PQ_node *elems)
+#else
+static PQ_node *init_elems (elems)
+PQ_node *elems;
+#endif
+{
+    int i;
+    PQ_node *token;
+
+    for (i = 0, token = (PQ_node *) NULL; i < G->nnodes; i++) {
+        if (i != MAGICNODE) {
+            elems[i].next = token;
+            token = &elems[i];
+        }
+        elems[i].number = i;
+    }
+
+    XPQ_init_tree (token);
+    return token;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkout_cliquelist (Xcplane **list)
+#else
+static int checkout_cliquelist (list)
+Xcplane **list;
+#endif
+{
+    PQ_node *elems;
+    PQ_node *token_elem;
+    PQ_node *save_root;
+    Xclique *bot, *top, *botnext, *topnext;
+    Xclique *save_bot;
+    Xclique *chk;
+    int isbot;
+    int k = 0;
+    int botcount;
+    int topcount;
+
+    elems = CC_SAFE_MALLOC (G->nnodes, PQ_node);
+    if (!elems) {
+        fprintf (stderr, "out of memory in checkout_cliquelist\n");
+        exit (1);
+    }
+
+    token_elem = init_elems (elems);
+
+    bot = cliquelist;
+    top = cliquelist;
+    /* [cliquelist,bot) is base, [top,cliquelist) is tested */
+    /* [cliquelist,save_bot) is in save_root */
+
+    save_root = XPQ_save_tree (token_elem);
+    save_bot = bot;
+    botcount = 0;
+    topcount = 0;
+
+    do {
+        if (3 * bot->slack + top->prev->slack < 1.0) {
+            /* putchar ('v'); fflush (stdout); */
+            chk = bot;
+            isbot = 1;
+            botnext = bot->next;
+            topnext = top;
+        } else {
+            /* putchar ('^'); fflush (stdout); */
+            chk = top->prev;
+            botnext = bot;
+            topnext = top->prev;
+            isbot = 0;
+            if (botcount > 20 && topcount == 0) {
+                XPQ_save_tree_free (save_root);
+                save_root = XPQ_save_tree (token_elem);
+                save_bot = bot;
+                botcount = 0;
+            }
+        }
+        if (!add_clique_to_PQtree (chk, elems)) {
+            /* putchar ('!'); fflush (stdout); */
+            XPQ_free_all (token_elem, 1);
+            XPQ_restore_tree (save_root, 1);
+            topcount = 0;
+            if (save_bot != bot) {
+                if (add_cliques_to_PQtree (save_bot, bot, elems)) {
+                    fprintf (stderr, "add_clique error\n");
+                    exit (1);
+                }
+                XPQ_save_tree_free (save_root);
+                save_root = XPQ_save_tree (token_elem);
+                save_bot = bot;
+                botcount = 0;
+            }
+            if (!add_clique_to_PQtree (chk, elems)) {
+                k += found_clique_contradiction (chk, cliquelist, bot, list);
+                XPQ_free_all (token_elem, 1);
+                XPQ_restore_tree (save_root, 1);
+
+                if (isbot) {
+                    chk->next->prev = chk->prev;
+                    chk->prev->next = chk->next;
+                    if (save_bot == chk) {
+                        save_bot = bot->next;
+                    }
+                    Xintptr_list_free (chk->nodes);
+                    Xcliquefree (chk);
+                }
+            } else {
+                if (isbot) {
+                    botcount++;
+                } else {
+                    topcount++;
+                }
+            }
+        } else {
+            if (isbot)
+                botcount++;
+            else
+                topcount++;
+        }
+        top = topnext;
+        bot = botnext;
+    } while (bot != top);
+    /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+    XPQ_free_all (token_elem, 1);
+    XPQ_save_tree_free (save_root);
+    /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+    CC_FREE (elems, PQ_node);
+
+    return k;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int clique_comp (const void *a, const void *b)
+#else
+static int clique_comp (a, b)
+const void *a, *b;
+#endif
+{
+    if ((*(Xclique * const *) a)->slack <
+        (*(Xclique * const *) b)->slack) {
+        return -1;
+    } else if ((*(Xclique * const *) a)->slack >
+               (*(Xclique * const *) b)->slack) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void sortcliquelist (void)
+#else
+static void sortcliquelist ()
+#endif
+{
+    Xclique **svec;
+    Xclique *p;
+    int i;
+
+    svec = CC_SAFE_MALLOC (ncliques, Xclique *);
+    if (!svec) {
+        fprintf (stderr, "out of memory in sortcliquelist\n");
+        exit (1);
+    }
+    for (i = 0, p = cliquelist; p; p = p->next, i++) {
+        svec[i] = p;
+    }
+    if (i != ncliques) {
+        fprintf (stderr, "Found %d cliques, expected %d\n", i, ncliques);
+    }
+    qsort ((char *) svec, ncliques, sizeof (Xclique *), clique_comp);
+
+    for (i = 0; i < ncliques; i++) {
+        svec[i]->next = svec[i + 1];
+        svec[i]->prev = svec[i - 1];
+    }
+    svec[0]->prev = svec[ncliques - 1];
+    svec[ncliques - 1]->next = svec[0];
+    cliquelist = svec[0];
+
+    CC_FREE (svec, Xclique *);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_clique_to_PQtree (Xclique *c, PQ_node *elems)
+#else
+static int add_clique_to_PQtree (c, elems)
+Xclique *c;
+PQ_node *elems;
+#endif
+{
+    PQ_node *cut;
+
+    cut = clique_to_PQlist (c, elems);
+    return (XPQ_process (cut) != (PQ_node *) NULL);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xclique *add_cliques_to_PQtree (Xclique *c, Xclique *cend, PQ_node *elems)
+#else
+static Xclique *add_cliques_to_PQtree (c, cend, elems)
+Xclique *c;
+Xclique *cend;
+PQ_node *elems;
+#endif
+{
+    while (c != cend) {
+        if (!add_clique_to_PQtree (c, elems)) {
+            return c;
+        }
+        c = c->next;
+    }
+    return (Xclique *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *clique_to_PQlist (Xclique *c, PQ_node *elems)
+#else
+static PQ_node *clique_to_PQlist (c, elems)
+Xclique *c;
+PQ_node *elems;
+#endif
+{
+    Xintptr *p;
+    PQ_node *cut;
+    int n;
+
+    if (find_intptr_list (c->nodes, MAGICNODE)) {
+        G->magicnum++;
+        for (p = c->nodes; p; p = p->next) {
+            G->nodelist[p->this].magiclabel = G->magicnum;
+        }
+        for (n = 1, cut = (PQ_node *) NULL; n < G->nnodes; n++) {
+            if (G->nodelist[n].magiclabel != G->magicnum) {
+                elems[n].next = cut;
+                cut = &elems[n];
+            }
+        }
+    } else {
+        for (cut = (PQ_node *) NULL, p = c->nodes; p; p = p->next) {
+            n = p->this;
+            elems[n].next = cut;
+            cut = &elems[n];
+        }
+    }
+    return cut;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int find_intptr_list (Xintptr *p, int n)
+#else
+static int find_intptr_list (p, n)
+Xintptr *p;
+int n;
+#endif
+{
+    while (p) {
+        if (p->this == n)
+            return 1;
+        p = p->next;
+    }
+    return 0;
+}
+
+/* viol added to [base,bend) results in violation.  Convert to comb. */
+
+#ifdef CC_PROTOTYPE_ANSI
+static int found_clique_contradiction (Xclique *viol, Xclique *base, Xclique *bend, Xcplane **list)
+#else
+static int found_clique_contradiction (viol, base, bend, list)
+Xclique *viol;
+Xclique *base;
+Xclique *bend;
+Xcplane **list;
+#endif
+{
+    Xclique *comblist[4];
+    PQ_node *elems;
+    PQ_node *token_elem;
+    int i, j;
+    Xclique *b = (Xclique *) NULL;
+
+    comblist[0] = viol;
+    elems = CC_SAFE_MALLOC (G->nnodes, PQ_node);
+    if (!elems) {
+        fprintf (stderr, "out of memory in found_clique_contradiction\n");
+        exit (1);
+    }
+
+    for (i = 1;; i++) {
+        token_elem = init_elems (elems);
+        for (j = 0; j < i; j++) {
+            if (!add_clique_to_PQtree (comblist[j], elems)) {
+                if (j != i - 1) {
+                    fprintf (stderr, "Whoa, unexpected violation\n");
+                }
+                XPQ_free_all (token_elem, 1);
+                CC_FREE (elems, PQ_node);
+                if (i == 4) {
+                    return found_comb_contradiction (comblist, list);
+                } else {
+                    return 0;
+                }
+            }
+        }
+        if (i < 4) {
+            b = add_cliques_to_PQtree (base, bend, elems);
+        }
+        XPQ_free_all (token_elem, 1);
+        if (i >= 4 || !b) {
+            CC_FREE (elems, PQ_node);
+            return 0;
+        }
+        comblist[i] = b;
+        bend = b;
+    }
+}
+
+#define HANDLE 1
+#define TOOTH1 2
+#define TOOTH2 4
+#define TOOTH3 8
+#define NREGIONS 16
+
+int flipseq[NREGIONS] = {0, TOOTH1, TOOTH2, TOOTH3, TOOTH1 | TOOTH2,
+    TOOTH1 | TOOTH3, TOOTH2 | TOOTH3, TOOTH1 | TOOTH2 | TOOTH3,
+    HANDLE | TOOTH1, HANDLE | TOOTH2, HANDLE | TOOTH3,
+    HANDLE | TOOTH1 | TOOTH2, HANDLE | TOOTH1 | TOOTH3,
+HANDLE | TOOTH2 | TOOTH3};
+
+#ifdef CC_PROTOTYPE_ANSI
+static int found_comb_contradiction (Xclique *comblist[4], Xcplane **list)
+
+#else
+static int found_comb_contradiction (comblist, list)
+Xclique  *comblist[4];
+Xcplane  **list;
+#endif
+{
+    int i, i2;
+    int flip;
+    int handle;
+    int hbit;
+    unsigned int hist[NREGIONS];
+    unsigned int hist2[NREGIONS];
+    Xclique *tmp;
+    int test;
+
+    for (i = 0; i < G->nnodes; i++) {
+        G->nodelist[i].Tmark = 0;
+    }
+    for (i = 0; i < 4; i++) {
+        mark_clique (comblist[i], (1 << i));
+    }
+    gethist (hist);
+
+    for (flip = 0; flip < NREGIONS; flip++) {
+        for (handle = 0; handle < 4; handle++) {
+            hbit = (1 << handle);
+            for (i = 0; i < NREGIONS; i++) {
+                i2 = i & ~(1 | hbit);
+                if (i & 1)
+                    i2 |= hbit;
+                if (i & hbit)
+                    i2 |= 1;
+                i2 ^= flipseq[flip];
+                hist2[i] = hist[i2];
+            }
+            if (Xhistok (hist2)) {
+                SWAP (comblist[0], comblist[handle], tmp);
+                test = add_comblist_to_cutlist (comblist, list);
+                return test;
+            }
+        }
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void mark_clique (Xclique *c, int m)
+#else
+static void mark_clique (c, m)
+Xclique *c;
+int m;
+#endif
+{
+    Xintptr *p;
+
+    for (p = c->nodes; p; p = p->next) {
+        G->nodelist[p->this].Tmark |= m;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void gethist (unsigned int *hist)
+#else
+static void gethist (hist)
+unsigned int *hist;
+#endif
+{
+    int i;
+
+    for (i = 0; i < NREGIONS; i++) {
+        hist[i] = 0;
+    }
+    for (i = 0; i < G->nnodes; i++) {
+        hist[G->nodelist[i].Tmark]++;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int add_comblist_to_cutlist (Xclique *comblist[4], Xcplane **list)
+#else
+static int add_comblist_to_cutlist (comblist, list)
+Xclique *comblist[4];
+Xcplane **list;
+#endif
+{
+    Xintptr *ip;
+    Xnodeptr *np;
+    Xnodeptrptr *npp;
+    Xnodeptrptr *handles, *teeth;
+    int i;
+    int test;
+
+    handles = Xnodeptrptralloc ();
+    handles->next = (Xnodeptrptr *) NULL;
+    handles->this = (Xnodeptr *) NULL;
+    for (ip = comblist[0]->nodes; ip; ip = ip->next) {
+        np = Xnodeptralloc ();
+        np->this = &G->nodelist[ip->this];
+        np->next = handles->this;
+        handles->this = np;
+    }
+    teeth = (Xnodeptrptr *) NULL;
+    for (i = 1; i < 4; i++) {
+        npp = Xnodeptrptralloc ();
+        npp->next = teeth;
+        teeth = npp;
+        npp->this = (Xnodeptr *) NULL;
+        for (ip = comblist[i]->nodes; ip; ip = ip->next) {
+            np = Xnodeptralloc ();
+            np->this = &G->nodelist[ip->this];
+            np->next = npp->this;
+            npp->this = np;
+        }
+    }
+    if (!Xcliquefluff (G, &handles, &teeth)) {
+        printf ("DE FLUFFED TO 0\n");
+        fflush (stdout);
+        return 0;
+    }
+    test = Xloadcplane (list, (Xnodeptr *) NULL, handles, teeth, 0);
+    if (!test) {
+        Xfreeteeth (handles);
+        Xfreeteeth (teeth);
+    }
+    return test;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void free_portableclique (Xportableclique *q)
+#else
+static void free_portableclique (q)
+Xportableclique *q;
+#endif
+{
+    if (q->nodes)
+        CC_FREE (q->nodes, int);
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xourallo.c b/contrib/blossom/concorde97/XSTUFF/Xourallo.c
new file mode 100644
index 0000000000000000000000000000000000000000..6409ff98f3ae07f70f49aef5e75895d58323d4f8
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xourallo.c
@@ -0,0 +1,1209 @@
+/**************************************************************************/
+/*                                                                        */
+/*    OLD SUBTOUR STUFF - all functions and types now start with X        */
+/*                      - this stuff is only for testing concorde         */
+/*                                                                        */
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*  blockptr *blockptralloc ()                                            */
+/*  clique *cliquealloc ()                                                */
+/*  combhash *combhashalloc ()                                            */
+/*  cplane *cplanealloc ()                                                */
+/*  cutnodeptr *cutnodeptralloc ()                                        */
+/*  cuttree_node *cuttree_nodealloc ()                                    */
+/*  edge *edgealloc ()                                                    */
+/*  edgeptr *edgeptralloc ()                                              */
+/*  intptr *intptralloc ()                                                */
+/*  intptrptr *intptrptralloc ()                                          */
+/*  void add_intptrptr ()                                                 */
+/*  iplane *iplanealloc ()                                                */
+/*  node *nodealloc ()                                                    */
+/*  nodeptr *nodeptralloc ()                                              */
+/*  nodeptrptr *nodeptrptralloc ()                                        */
+/*  void add_edgeptr ()                                                   */
+/*  void add_extralink ()                                                 */
+/*  void add_nodeptr ()                                                   */
+/*  void add_nodeptrptr ()                                                */
+/*  void blinkfree ()                                                     */
+/*  void blockptrfree ()                                                  */
+/*  void clinkfree ()                                                     */
+/*  void cliquefree ()                                                    */
+/*  void combhashfree ()                                                  */
+/*  void cplane_list_free ()                                              */
+/*  void cplanefree ()                                                    */
+/*  void cutnodeptrfree ()                                                */
+/*  void cuttree_nodefree ()                                              */
+/*  void edgefree ()                                                      */
+/*  void edge_list_free ()                                                */
+/*  void edgeptr_list_free ()                                             */
+/*  void edgeptrfree ()                                                   */
+/*  void initialize_ouralloc ()                                           */
+/*  void intptr_list_free ()                                              */
+/*  void intptrfree ()                                                    */
+/*  void intptrptr_list_free ()                                           */
+/*  void intptrptr_list_freeall()                                         */
+/*  void intptrptrfree ()                                                 */
+/*  void iplane_list_free ()                                              */
+/*  void iplanefree ()                                                    */
+/*  void nodefree ()                                                      */
+/*  void nodeptr_list_free ()                                             */
+/*  void nodeptrfree ()                                                   */
+/*  void nodeptrptr_list_free ()                                          */
+/*  void nodeptrptrfree ()                                                */
+/*  void union_nodeptr ()                                                 */
+/*  void ouralloc_reset ()                                                */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+#include "Xnecklac.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static Xextralink *Xextralinkalloc (void);
+static union size_104 *size_104_alloc (void);
+static union size_16 *size_16_alloc (void);
+static union size_24 *size_24_alloc (void);
+static union size_48 *size_48_alloc (void);
+static union size_8 *size_8_alloc (void);
+static union size_80 *size_80_alloc (void);
+static void Xextralinkfree (Xextralink *);
+static void fetch_size_104 (int);
+static void fetch_size_16 (int);
+static void fetch_size_24 (int);
+static void fetch_size_48 (int);
+static void fetch_size_8 (int);
+static void fetch_size_80 (int);
+static void size_104_free (union size_104 *);
+static void size_16_free (union size_16 *);
+static void size_24_free (union size_24 *);
+static void size_48_free (union size_48 *);
+static void size_80_free (union size_80 *);
+static void size_8_free (union size_8 *);
+static void initialize_ouralloc (void);
+
+#else
+
+static Xextralink *Xextralinkalloc ();
+static union size_104 *size_104_alloc ();
+static union size_16 *size_16_alloc ();
+static union size_24 *size_24_alloc ();
+static union size_48 *size_48_alloc ();
+static union size_8 *size_8_alloc ();
+static union size_80 *size_80_alloc ();
+static void Xextralinkfree ();
+static void fetch_size_104 ();
+static void fetch_size_16 ();
+static void fetch_size_24 ();
+static void fetch_size_48 ();
+static void fetch_size_8 ();
+static void fetch_size_80 ();
+static void size_104_free ();
+static void size_16_free ();
+static void size_24_free ();
+static void size_48_free ();
+static void size_80_free ();
+static void size_8_free ();
+static void initialize_ouralloc ();
+
+#endif
+
+/* fooALLOCCHUNK * sizeof foo + 16 should be <= a power of 2 */
+
+#define CHUNKBASE ((1<<13)-16)
+
+#define INIT_8_ALLOC    (CHUNKBASE / sizeof (union size_8))
+#define SIZE_8_CHUNK    (CHUNKBASE / sizeof (union size_8))
+
+#define INIT_16_ALLOC   (CHUNKBASE / sizeof (union size_16))
+#define SIZE_16_CHUNK   (CHUNKBASE / sizeof (union size_16))
+
+#define INIT_24_ALLOC   (50)
+#define SIZE_24_CHUNK   (CHUNKBASE / sizeof (union size_24))
+
+#define INIT_48_ALLOC   (CHUNKBASE / sizeof (union size_48))
+#define SIZE_48_CHUNK   (CHUNKBASE / sizeof (union size_48))
+
+#define INIT_80_ALLOC   (CHUNKBASE / sizeof (union size_80))
+#define SIZE_80_CHUNK   (CHUNKBASE / sizeof (union size_80))
+
+#define INIT_104_ALLOC  (CHUNKBASE / sizeof (union size_104))
+#define SIZE_104_CHUNK  (CHUNKBASE / sizeof (union size_104))
+
+static int init_ouralloc = 1;
+
+union size_8 {
+    Xnodeptr obj_nodeptr;
+    Xnodeptrptr obj_nodeptrptr;
+    Xedgeptr obj_edgeptr;
+    Xneckedgeptr obj_neckedgeptr;
+    Xclink obj_clink;
+    Xintptr obj_intptr;
+    Xintptrptr obj_intptrptr;
+    Xcutnodeptr obj_cutnodeptr;
+    Xcombhash obj_combhash;
+    union size_8 *next;
+} *size_8_freelist = (union size_8 *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fetch_size_8 (int n)
+#else
+static void fetch_size_8 (n)
+int n;
+#endif
+{
+    union size_8 *x;
+
+    x = CC_SAFE_MALLOC (n, union size_8);
+    if (!x) {
+        fprintf (stderr, "Out of memory in old fetch\n");
+        exit (1);
+    }
+    x[n - 1].next = size_8_freelist;
+    size_8_freelist = x;
+    for (n -= 2; n >= 0; n--, x++) {
+        x->next = x + 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static union size_8 *size_8_alloc (void)
+#else
+static union size_8 *size_8_alloc ()
+#endif
+{
+    union size_8 *x;
+
+    if (init_ouralloc) {
+        initialize_ouralloc ();
+    }
+    if (!size_8_freelist) {
+        fetch_size_8 (SIZE_8_CHUNK);
+    }
+    x = size_8_freelist;
+    size_8_freelist = x->next;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void size_8_free (union size_8 *x)
+#else
+static void size_8_free (x)
+union size_8 *x;
+#endif
+{
+    x->next = size_8_freelist;
+    size_8_freelist = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xnodeptr *Xnodeptralloc (void)
+#else
+Xnodeptr *Xnodeptralloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_nodeptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xnodeptrfree (Xnodeptr *n)
+#else
+void Xnodeptrfree (n)
+Xnodeptr *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xnodeptr_list_free (Xnodeptr *np)
+#else
+void Xnodeptr_list_free (np)
+Xnodeptr *np;
+#endif
+{
+    Xnodeptr *next;
+
+    while (np) {
+        next = np->next;
+        Xnodeptrfree (np);
+        np = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xadd_nodeptr (Xnodeptr **list, Xnode *n)
+#else
+void Xadd_nodeptr (list, n)
+Xnodeptr **list;
+Xnode *n;
+#endif
+{
+    Xnodeptr *temp;
+
+    temp = Xnodeptralloc ();
+    temp->this = n;
+    temp->next = *list;
+    *list = temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xunion_nodeptr (Xgraph *G, Xnodeptr *a, Xnodeptr *b, Xnodeptr **u)
+#else
+void Xunion_nodeptr (G, a, b, u)
+Xgraph *G;
+Xnodeptr *a, *b, **u;
+#endif
+{
+    Xnode *n;
+    Xnodeptr *np;
+
+    *u = (Xnodeptr *) NULL;
+    G->magicnum++;
+    for (np = a; np; np = np->next) {
+        n = np->this;
+        if (n->magiclabel != G->magicnum) {
+            Xadd_nodeptr (u, n);
+            n->magiclabel = G->magicnum;
+        }
+    }
+    for (np = b; np; np = np->next) {
+        n = np->this;
+        if (n->magiclabel != G->magicnum) {
+            Xadd_nodeptr (u, n);
+            n->magiclabel = G->magicnum;
+        }
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xnodeptrptr *Xnodeptrptralloc (void)
+#else
+Xnodeptrptr *Xnodeptrptralloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_nodeptrptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xnodeptrptrfree (Xnodeptrptr *n)
+#else
+void Xnodeptrptrfree (n)
+Xnodeptrptr *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xnodeptrptr_list_free (Xnodeptrptr *np)
+#else
+void Xnodeptrptr_list_free (np)
+Xnodeptrptr *np;
+#endif
+{
+    Xnodeptrptr *next;
+
+    while (np) {
+        next = np->next;
+        Xnodeptrptrfree (np);
+        np = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xadd_nodeptrptr (Xnodeptrptr **list, Xnodeptr *n)
+#else
+void Xadd_nodeptrptr (list, n)
+Xnodeptrptr **list;
+Xnodeptr *n;
+#endif
+{
+    Xnodeptrptr *temp;
+
+    temp = Xnodeptrptralloc ();
+    temp->this = n;
+    temp->next = *list;
+    *list = temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xedgeptr *Xedgeptralloc (void)
+#else
+Xedgeptr *Xedgeptralloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_edgeptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xedgeptrfree (Xedgeptr *n)
+#else
+void Xedgeptrfree (n)
+Xedgeptr *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xedgeptr_list_free (Xedgeptr *ep)
+#else
+void Xedgeptr_list_free (ep)
+Xedgeptr *ep;
+#endif
+{
+    Xedgeptr *next;
+
+    while (ep) {
+        next = ep->next;
+        Xedgeptrfree (ep);
+        ep = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xadd_edgeptr (Xedgeptr **list, Xedge *e)
+#else
+void Xadd_edgeptr (list, e)
+Xedgeptr **list;
+Xedge *e;
+#endif
+{
+    Xedgeptr *temp;
+
+    temp = Xedgeptralloc ();
+    temp->this = e;
+    temp->next = *list;
+    *list = temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xneckedgeptr *Xneckedgeptralloc (void)
+#else
+Xneckedgeptr *Xneckedgeptralloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_neckedgeptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xneckedgeptrfree (Xneckedgeptr *n)
+#else
+void Xneckedgeptrfree (n)
+Xneckedgeptr *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xneckedgeptr_list_free (Xneckedgeptr *ep)
+#else
+void Xneckedgeptr_list_free (ep)
+Xneckedgeptr *ep;
+#endif
+{
+    Xneckedgeptr *next;
+
+    while (ep) {
+        next = ep->next;
+        Xneckedgeptrfree (ep);
+        ep = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xadd_neckedgeptr (Xneckedgeptr **list, Xneckedge *e)
+#else
+void Xadd_neckedgeptr (list, e)
+Xneckedgeptr **list;
+Xneckedge *e;
+#endif
+{
+    Xneckedgeptr *temp;
+
+    temp = Xneckedgeptralloc ();
+    temp->this = e;
+    temp->next = *list;
+    *list = temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xclink *Xclinkalloc (void)
+#else
+Xclink *Xclinkalloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_clink);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xclinkfree (Xclink *n)
+#else
+void Xclinkfree (n)
+Xclink *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xintptr *Xintptralloc (void)
+#else
+Xintptr *Xintptralloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_intptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xintptrfree (Xintptr *n)
+#else
+void Xintptrfree (n)
+Xintptr *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xintptr_list_free (Xintptr *ip)
+#else
+void Xintptr_list_free (ip)
+Xintptr *ip;
+#endif
+{
+    Xintptr *next;
+
+    while (ip) {
+        next = ip->next;
+        Xintptrfree (ip);
+        ip = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xintptrptr *Xintptrptralloc (void)
+#else
+Xintptrptr *Xintptrptralloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_intptrptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xintptrptrfree (Xintptrptr *n)
+#else
+void Xintptrptrfree (n)
+Xintptrptr *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xintptrptr_list_free (Xintptrptr *ip)
+#else
+void Xintptrptr_list_free (ip)
+Xintptrptr *ip;
+#endif
+{
+    Xintptrptr *next;
+
+    while (ip) {
+        next = ip->next;
+        Xintptrptrfree (ip);
+        ip = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xintptrptr_list_freeall(Xintptrptr *ip)
+#else
+void Xintptrptr_list_freeall(ip)
+Xintptrptr *ip;
+#endif
+{
+    Xintptrptr *next;
+
+    while (ip) {
+        next = ip->next;
+        Xintptr_list_free (ip->this);
+        Xintptrptrfree (ip);
+        ip = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xadd_intptrptr (Xintptrptr **list, Xintptr *n)
+#else
+void Xadd_intptrptr (list, n)
+Xintptrptr **list;
+Xintptr *n;
+#endif
+{
+    Xintptrptr *temp;
+
+    temp = Xintptrptralloc ();
+    temp->this = n;
+    temp->next = *list;
+    *list = temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xcutnodeptr *Xcutnodeptralloc (void)
+#else
+Xcutnodeptr *Xcutnodeptralloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_cutnodeptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcutnodeptrfree (Xcutnodeptr *n)
+#else
+void Xcutnodeptrfree (n)
+Xcutnodeptr *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xcombhash *Xcombhashalloc (void)
+#else
+Xcombhash *Xcombhashalloc ()
+#endif
+{
+    return &(size_8_alloc ()->obj_combhash);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcombhashfree (Xcombhash *n)
+#else
+void Xcombhashfree (n)
+Xcombhash *n;
+#endif
+{
+    size_8_free ((union size_8 *) n);
+}
+
+union size_16 {
+    Xblink obj_blink;
+    Xextralink obj_extralink;
+    Xblockptr obj_blockptr;
+    union size_16 *next;
+} *size_16_freelist = (union size_16 *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fetch_size_16 (int n)
+#else
+static void fetch_size_16 (n)
+int n;
+#endif
+{
+    union size_16 *x;
+
+    x = CC_SAFE_MALLOC (n, union size_16);
+    if (!x) {
+        fprintf (stderr, "Out of memory in old fetch\n");
+        exit (1);
+    }
+    x[n - 1].next = size_16_freelist;
+    size_16_freelist = x;
+    for (n -= 2; n >= 0; n--, x++) {
+        x->next = x + 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static union size_16 *size_16_alloc (void)
+#else
+static union size_16 *size_16_alloc ()
+#endif
+{
+    union size_16 *x;
+
+    if (init_ouralloc) {
+        initialize_ouralloc ();
+    }
+    if (!size_16_freelist) {
+        fetch_size_16 (SIZE_16_CHUNK);
+    }
+    x = size_16_freelist;
+    size_16_freelist = x->next;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void size_16_free (union size_16 *x)
+#else
+static void size_16_free (x)
+union size_16 *x;
+#endif
+{
+    x->next = size_16_freelist;
+    size_16_freelist = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static Xextralink *Xextralinkalloc (void)
+#else
+static Xextralink *Xextralinkalloc ()
+#endif
+{
+    return &(size_16_alloc ()->obj_extralink);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void Xextralinkfree (Xextralink *n)
+#else
+static void Xextralinkfree (n)
+Xextralink *n;
+#endif
+{
+    size_16_free ((union size_16 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xextralink_list_free (Xextralink *ep)
+#else
+void Xextralink_list_free (ep)
+Xextralink *ep;
+#endif
+{
+    Xextralink *next;
+
+    while (ep) {
+        next = ep->next;
+        Xextralinkfree (ep);
+        ep = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xadd_extralink (Xextralink **list, int end0, int end1, int weight)
+#else
+void Xadd_extralink (list, end0, end1, weight)
+Xextralink **list;
+int end0, end1, weight;
+#endif
+{
+    Xextralink *temp;
+
+    temp = Xextralinkalloc ();
+    temp->ends[0] = end0;
+    temp->ends[1] = end1;
+    temp->weight = weight;
+    temp->next = *list;
+    *list = temp;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xblink *Xblinkalloc (void)
+#else
+Xblink *Xblinkalloc ()
+#endif
+{
+    return &(size_16_alloc ()->obj_blink);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xblinkfree (Xblink *n)
+#else
+void Xblinkfree (n)
+Xblink *n;
+#endif
+{
+    size_16_free ((union size_16 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xblockptr *Xblockptralloc (void)
+#else
+Xblockptr *Xblockptralloc ()
+#endif
+{
+    return &(size_16_alloc ()->obj_blockptr);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xblockptrfree (Xblockptr *n)
+#else
+void Xblockptrfree (n)
+Xblockptr *n;
+#endif
+{
+    size_16_free ((union size_16 *) n);
+}
+
+union size_24 {
+    Xcplane obj_cplane;          /* size really 20 */
+    Xiplane obj_iplane;
+    Xclique obj_clique;
+    Xeqn obj_eqn;
+    union size_24 *next;
+} *size_24_freelist = (union size_24 *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fetch_size_24 (int n)
+#else
+static void fetch_size_24 (n)
+int n;
+#endif
+{
+    union size_24 *x;
+
+    x = CC_SAFE_MALLOC (n, union size_24);
+    if (!x) {
+        fprintf (stderr, "Out of memory in old fetch\n");
+        exit (1);
+    }
+    x[n - 1].next = size_24_freelist;
+    size_24_freelist = x;
+    for (n -= 2; n >= 0; n--, x++) {
+        x->next = x + 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static union size_24 *size_24_alloc (void)
+#else
+static union size_24 *size_24_alloc ()
+#endif
+{
+    union size_24 *x;
+
+    if (init_ouralloc) {
+        initialize_ouralloc ();
+    }
+    if (!size_24_freelist) {
+        fetch_size_24 (SIZE_24_CHUNK);
+    }
+    x = size_24_freelist;
+    size_24_freelist = x->next;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void size_24_free (union size_24 *x)
+#else
+static void size_24_free (x)
+union size_24 *x;
+#endif
+{
+    x->next = size_24_freelist;
+    size_24_freelist = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xcplane *Xcplanealloc (void)
+#else
+Xcplane *Xcplanealloc ()
+#endif
+{
+    return &(size_24_alloc ()->obj_cplane);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcplanefree (Xcplane *n)
+#else
+void Xcplanefree (n)
+Xcplane *n;
+#endif
+{
+    size_24_free ((union size_24 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcplane_list_free (Xcplane *ip)
+#else
+void Xcplane_list_free (ip)
+Xcplane *ip;
+#endif
+{
+    Xcplane *next;
+
+    while (ip) {
+        next = ip->next;
+        Xcplanefree (ip);
+        ip = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xiplane *Xiplanealloc (void)
+#else
+Xiplane *Xiplanealloc ()
+#endif
+{
+    return &(size_24_alloc ()->obj_iplane);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xiplanefree (Xiplane *n)
+#else
+void Xiplanefree (n)
+Xiplane *n;
+#endif
+{
+    size_24_free ((union size_24 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xiplane_list_free (Xiplane *ip)
+#else
+void Xiplane_list_free (ip)
+Xiplane *ip;
+#endif
+{
+    Xiplane *next;
+
+    while (ip) {
+        next = ip->next;
+        Xiplanefree (ip);
+        ip = next;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xclique *Xcliquealloc (void)
+#else
+Xclique *Xcliquealloc ()
+#endif
+{
+    return &(size_24_alloc ()->obj_clique);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcliquefree (Xclique *n)
+#else
+void Xcliquefree (n)
+Xclique *n;
+#endif
+{
+    size_24_free ((union size_24 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xeqn *Xeqnalloc (void)
+#else
+Xeqn *Xeqnalloc ()
+#endif
+{
+    return &(size_24_alloc ()->obj_eqn);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xeqnfree (Xeqn *n)
+#else
+void Xeqnfree (n)
+Xeqn *n;
+#endif
+{
+    size_24_free ((union size_24 *) n);
+}
+
+union size_48 {
+    Xcuttree_node obj_cuttree_node;
+    union size_48 *next;
+} *size_48_freelist = (union size_48 *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fetch_size_48 (int n)
+#else
+static void fetch_size_48 (n)
+int n;
+#endif
+{
+    union size_48 *x = (union size_48 *) NULL;
+
+    x = CC_SAFE_MALLOC (n, union size_48);
+    if (!x) {
+        fprintf (stderr, "Out of memory in old fetch\n");
+        exit (1);
+    }
+    x[n - 1].next = size_48_freelist;
+    size_48_freelist = x;
+    for (n -= 2; n >= 0; n--, x++) {
+        x->next = x + 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static union size_48 *size_48_alloc (void)
+#else
+static union size_48 *size_48_alloc ()
+#endif
+{
+    union size_48 *x;
+
+    if (init_ouralloc) {
+        initialize_ouralloc ();
+    }
+    if (!size_48_freelist) {
+        fetch_size_48 (SIZE_48_CHUNK);
+    }
+    x = size_48_freelist;
+    size_48_freelist = x->next;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void size_48_free (union size_48 *x)
+#else
+static void size_48_free (x)
+union size_48 *x;
+#endif
+{
+    x->next = size_48_freelist;
+    size_48_freelist = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xcuttree_node *Xcuttree_nodealloc (void)
+#else
+Xcuttree_node *Xcuttree_nodealloc ()
+#endif
+{
+    return &(size_48_alloc ()->obj_cuttree_node);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xcuttree_nodefree (Xcuttree_node *n)
+#else
+void Xcuttree_nodefree (n)
+Xcuttree_node *n;
+#endif
+{
+    size_48_free ((union size_48 *) n);
+}
+
+union size_80 {
+    Xedge obj_edge;
+    union size_80 *next;
+} *size_80_freelist = (union size_80 *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fetch_size_80 (int n)
+#else
+static void fetch_size_80 (n)
+int n;
+#endif
+{
+    union size_80 *x;
+
+    x = CC_SAFE_MALLOC (n, union size_80);
+    if (!x) {
+        fprintf (stderr, "Out of memory in old fetch\n");
+        exit (1);
+    }
+    x[n - 1].next = size_80_freelist;
+    size_80_freelist = x;
+    for (n -= 2; n >= 0; n--, x++) {
+        x->next = x + 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static union size_80 *size_80_alloc (void)
+#else
+static union size_80 *size_80_alloc ()
+#endif
+{
+    union size_80 *x;
+
+    if (init_ouralloc) {
+        initialize_ouralloc ();
+    }
+    if (!size_80_freelist) {
+        fetch_size_80 (SIZE_80_CHUNK);
+    }
+    x = size_80_freelist;
+    size_80_freelist = x->next;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void size_80_free (union size_80 *x)
+#else
+static void size_80_free (x)
+union size_80 *x;
+#endif
+{
+    x->next = size_80_freelist;
+    size_80_freelist = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xedge *Xedgealloc (void)
+#else
+Xedge *Xedgealloc ()
+#endif
+{
+    return &(size_80_alloc ()->obj_edge);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xedgefree (Xedge *n)
+#else
+void Xedgefree (n)
+Xedge *n;
+#endif
+{
+    size_80_free ((union size_80 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xedge_list_free (Xedge *e)
+#else
+void Xedge_list_free (e)
+Xedge *e;
+#endif
+{
+    Xedge *next;
+
+    while (e) {
+        next = e->next;
+        Xedgefree (e);
+        e = next;
+    }
+}
+
+union size_104 {
+    Xnode obj_node;
+    union size_104 *next;
+} *size_104_freelist = (union size_104 *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+static void fetch_size_104 (int n)
+#else
+static void fetch_size_104 (n)
+int n;
+#endif
+{
+    union size_104 *x;
+
+    x = CC_SAFE_MALLOC (n, union size_104);
+    if (!x) {
+        fprintf (stderr, "Out of memory in old fetch\n");
+        exit (1);
+    }
+    x[n - 1].next = size_104_freelist;
+    size_104_freelist = x;
+    for (n -= 2; n >= 0; n--, x++) {
+        x->next = x + 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static union size_104 *size_104_alloc (void)
+#else
+static union size_104 *size_104_alloc ()
+#endif
+{
+    union size_104 *x;
+
+    if (init_ouralloc) {
+        initialize_ouralloc ();
+    }
+    if (!size_104_freelist) {
+        fetch_size_104 (SIZE_104_CHUNK);
+    }
+    x = size_104_freelist;
+    size_104_freelist = x->next;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void size_104_free (union size_104 *x)
+#else
+static void size_104_free (x)
+union size_104 *x;
+#endif
+{
+    x->next = size_104_freelist;
+    size_104_freelist = x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+Xnode *Xnodealloc (void)
+#else
+Xnode *Xnodealloc ()
+#endif
+{
+    return &(size_104_alloc ()->obj_node);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xnodefree (Xnode *n)
+#else
+void Xnodefree (n)
+Xnode *n;
+#endif
+{
+    size_104_free ((union size_104 *) n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void initialize_ouralloc (void)
+#else
+static void initialize_ouralloc ()
+#endif
+{
+    if (init_ouralloc) {
+        if (sizeof (union size_8) != 8) {
+            fprintf (stderr, "Warning, sizeof (union size_8) == %d\n",
+                     (int) sizeof (union size_8));
+        }
+        if (sizeof (union size_16) != 16) {
+            fprintf (stderr, "Warning, sizeof (union size_16) == %d\n",
+                     (int) sizeof (union size_16));
+        }
+        if (sizeof (union size_24) != 24) {
+            fprintf (stderr, "Warning, sizeof (union size_24) == %d\n",
+                     (int) sizeof (union size_24));
+        }
+        if (sizeof (union size_48) != 48) {
+            fprintf (stderr, "Warning, sizeof (union size_48) == %d\n",
+                     (int) sizeof (union size_48));
+        }
+        if (sizeof (union size_80) != 80) {
+            fprintf (stderr, "Warning, sizeof (union size_80) == %d\n",
+                     (int) sizeof (union size_80));
+        }
+        if (sizeof (union size_104) != 104) {
+            fprintf (stderr, "Warning, sizeof (union size_104) == %d\n",
+                     (int) sizeof (union size_104));
+        }
+        if (INIT_8_ALLOC) {
+            fetch_size_8 (INIT_8_ALLOC);
+        }
+        if (INIT_16_ALLOC) {
+            fetch_size_16 (INIT_16_ALLOC);
+        }
+        if (INIT_24_ALLOC) {
+            fetch_size_24 (INIT_24_ALLOC);
+        }
+        if (INIT_48_ALLOC) {
+            fetch_size_48 (INIT_48_ALLOC);
+        }
+        if (INIT_80_ALLOC) {
+            fetch_size_80 (INIT_80_ALLOC);
+        }
+        if (INIT_104_ALLOC) {
+            fetch_size_104 (INIT_104_ALLOC);
+        }
+        init_ouralloc = 0;
+    }
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xpq.h b/contrib/blossom/concorde97/XSTUFF/Xpq.h
new file mode 100644
index 0000000000000000000000000000000000000000..d730c467afbe49af3d41be29fde82bcc40d20b15
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xpq.h
@@ -0,0 +1,104 @@
+#ifndef __XPQ_H
+#define __XPQ_H
+
+#include "Xpqsets.h"
+
+#define MAGICNODE 0
+
+typedef struct PQ_node {
+    int number;
+    struct PQ_node *next;
+    struct Xedge *base_edge;
+    int dir_nodenum;
+    int labeled_children_count;
+    int magiclabel;
+    struct  Xintptr *toroot;
+    struct Xneckedgeptr *adj;
+    struct Xneckedge *entered;
+    struct {
+        struct PQ_node *parent;
+        int rank;
+    } setinfo;
+
+    PQ_elem queue_elem;
+
+/* the size of the children_set will not necessarily be correct for Q nodes */
+    PQ_set children_set;
+    PQ_elem children_elem;
+
+    PQ_set full_children_set;
+    PQ_elem full_children_elem;
+
+    PQ_set partial_children_set;
+    PQ_elem partial_children_elem;
+
+    PQ_elem blocked_elem;
+
+    PQ_elem leaves_elem;
+
+    struct PQ_node *parent;
+
+    int pertinent_child_count;
+    int pertinent_leaf_count;
+
+    int mark;
+#define IS_UNINITIALIZED(x) ((x)->mark < markbase)
+#define UNMARKED (markbase+0)
+#define QUEUED (markbase+1)
+#define BLOCKED (markbase+2)
+#define UNBLOCKED (markbase+3)
+
+    int type;
+    int parenttype;
+#define LEAF_NODE 0
+#define P_NODE 1
+#define Q_NODE 2
+#define DIR_NODE 3
+
+    int label;
+#define IS_EMPTY(x) ((x)->label <= markbase)
+#define EMPTY (markbase + 0)
+#define PARTIAL (markbase + 1)
+#define FULL (markbase + 2)
+
+} PQ_node;
+
+
+#define BUBBLE_SUCCESS 0
+#define REDUCE_SUCCESS 0
+#define BUBBLE_NO_SOL 1
+#define REDUCE_NO_SOL 2
+
+#ifdef CC_PROTOTYPE_ANSI
+
+/* pq.c */
+
+void
+    XPQ_free_all (PQ_node *, int),
+    XPQ_save_tree_free (PQ_node *);
+
+PQ_node
+    *XPQ_process (PQ_node *),
+    *XPQ_init_tree (PQ_node *),
+    *XPQ_find_root (PQ_node *),
+    *XPQ_save_tree (PQ_node *),
+    *XPQ_restore_tree (PQ_node *, int);
+
+#else
+
+/* pq.c */
+
+void
+    XPQ_free_all (),
+    XPQ_save_tree_free ();
+
+PQ_node
+    *XPQ_process (),
+    *XPQ_init_tree (),
+    *XPQ_find_root (),
+    *XPQ_save_tree (),
+    *XPQ_restore_tree ();
+
+#endif
+
+#endif  /* __XPQ_H */
diff --git a/contrib/blossom/concorde97/XSTUFF/Xpqnew.c b/contrib/blossom/concorde97/XSTUFF/Xpqnew.c
new file mode 100644
index 0000000000000000000000000000000000000000..1527f9ee7124bcb7fae85bf0c5a77a71dd77b60d
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xpqnew.c
@@ -0,0 +1,1743 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*  void                                                                  */
+/*      XPQ_free_all (),                                                  */
+/*      XPQ_save_tree_free ();                                            */
+/*                                                                        */
+/*  PQ_node                                                               */
+/*      *XPQ_process (),                                                  */
+/*      *XPQ_init_tree (),                                                */
+/*      *XPQ_find_root (),                                                */
+/*      *XPQ_save_tree (),                                                */
+/*      *XPQ_restore_tree ();                                             */
+/*                                                                        */
+/**************************************************************************/
+
+
+#include "machdefs.h"
+#include "util.h"
+#include "Xsubtour.h"
+#include "Xpq.h"
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    PQ_tree_grab (PQ_node *, PQ_set *, PQ_node *),
+    PQ_label_full (PQ_node *),
+    PQ_label_partial (PQ_node *),
+    PQ_collect_full_children (PQ_node *, int),
+    PQ_neighbor_replace (PQ_node *, PQ_set *, PQ_node *, PQ_node *),
+    PQ_merge_qnode (PQ_node *),
+    PQ_replace_node (PQ_node *, PQ_node *),
+    PQ_node_free (PQ_node *),
+    PQ_tree_free (PQ_node *, int),
+#ifndef NDEBUG
+    dump_solution (PQ_node *),
+    dump_subtree (PQ_node *),
+#endif
+    print_solution (PQ_node *, PQ_node *);
+
+static int
+    PQ_bubble (PQ_node *),
+    PQ_left_end_is_full (PQ_node *);
+
+#ifndef NDEBUG
+static int
+    checkout_before (PQ_node *, int),
+    checkout_after (PQ_node *, int),
+    check_tree (PQ_node *),
+    check_node_pert (PQ_node *),
+    check_node_pert_work (PQ_node *),
+    check_subtree (PQ_node *),
+    check_node (PQ_node *);
+#endif
+
+static PQ_node
+    *PQ_reduce (PQ_node *),
+    *PQ_template_l1 (PQ_node *),
+    *PQ_template_p1 (PQ_node *),
+    *PQ_template_p3_notroot (PQ_node *),
+    *PQ_template_p5_notroot (PQ_node *),
+    *PQ_template_q1 (PQ_node *),
+    *PQ_template_q2 (PQ_node *),
+    *PQ_template_p2_root (PQ_node *),
+    *PQ_template_p4_root (PQ_node *),
+    *PQ_template_p6_root (PQ_node *),
+    *PQ_template_q3_root (PQ_node *),
+    *PQ_collect_empty_children (PQ_node *, int),
+    *PQ_next_nondir (PQ_node *, PQ_node *),
+    *PQ_node_alloc_work (void),
+    *PQ_node_alloc (void),
+    *PQ_save_work (PQ_node *),
+    *PQ_restore_work (PQ_node *, int);
+
+#else
+
+static void
+    PQ_tree_grab (),
+    PQ_label_full (),
+    PQ_label_partial (),
+    PQ_collect_full_children (),
+    PQ_neighbor_replace (),
+    PQ_merge_qnode (),
+    PQ_replace_node (),
+    PQ_node_free (),
+    PQ_tree_free (),
+#ifndef NDEBUG
+    dump_solution (),
+    dump_subtree (),
+#endif
+    print_solution ();
+
+static int
+    PQ_bubble (),
+    PQ_left_end_is_full ();
+
+#ifndef NDEBUG
+static int
+    checkout_before (),
+    checkout_after (),
+    check_tree (),
+    check_node_pert (),
+    check_node_pert_work (),
+    check_subtree (),
+    check_node ();
+#endif
+
+static PQ_node
+    *PQ_reduce (),
+    *PQ_template_l1 (),
+    *PQ_template_p1 (),
+    *PQ_template_p3_notroot (),
+    *PQ_template_p5_notroot (),
+    *PQ_template_q1 (),
+    *PQ_template_q2 (),
+    *PQ_template_p2_root (),
+    *PQ_template_p4_root (),
+    *PQ_template_p6_root (),
+    *PQ_template_q3_root (),
+    *PQ_collect_empty_children (),
+    *PQ_next_nondir (),
+    *PQ_node_alloc_work (),
+    *PQ_node_alloc (),
+    *PQ_save_work (),
+    *PQ_restore_work ();
+
+#endif
+
+/* This is an implementation of the PQ-tree algorithms described in "Testing
+ * for the Consecutive Ones Property, Interval Graphs, and Graph Planarity
+ * Using PQ-Tree Algorithms" by Kellogg Booth and George Leuker, Journal of
+ * Computer and Systems Sciences 13 (1976) pp 335-379.  For details, proofs
+ * of correctness, etc. see the paper */
+
+#ifdef CC_PROTOTYPE_ANSI
+PQ_node *XPQ_process (PQ_node *S)
+#else
+PQ_node *XPQ_process (S)
+PQ_node *S;
+#endif
+{
+    if (!PQ_bubble (S)) {
+        return (PQ_node *) NULL;
+    }
+    return PQ_reduce (S);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_tree_grab (PQ_node *x, PQ_set *leaves, PQ_node *xprev)
+#else
+static void PQ_tree_grab (x, leaves, xprev)
+PQ_node *x;
+PQ_set *leaves;
+PQ_node *xprev;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+
+    if (x->type == LEAF_NODE || x->type == DIR_NODE) {
+        PQ_set_ADD_RIGHT (x, *leaves, leaves_elem);
+        if ((x->leaves_elem.ptr1 == (PQ_node *) NULL &&
+             x->children_elem.ptr1 == xprev) ||
+            (x->leaves_elem.ptr2 == (PQ_node *) NULL &&
+             x->children_elem.ptr2 == xprev)) {
+            /* We want the leaves ptr usage to match the children ptr usage,
+             * so we can preserve the direction the DIR_NODEs point */
+            SWAP (x->leaves_elem.ptr1, x->leaves_elem.ptr2, z);
+        }
+    } else {
+        PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+            PQ_tree_grab (z, leaves, zprev);
+        }
+    }
+}
+
+int markbase = 0;
+PQ_set blocked_set;
+PQ_node pseudo_root;
+int off_the_top;
+
+#ifdef CC_PROTOTYPE_ANSI
+PQ_node *XPQ_init_tree (PQ_node *S)
+#else
+PQ_node *XPQ_init_tree (S)
+PQ_node *S;
+#endif
+{
+    PQ_node *root;
+    PQ_node *x;
+
+    if (!S->next) {
+        S->type = LEAF_NODE;
+        S->parent = (PQ_node *) NULL;
+        S->parenttype = P_NODE;
+        PQ_set_INIT (S->children_set);
+        PQ_set_INIT (S->full_children_set);
+        PQ_set_INIT (S->partial_children_set);
+        S->label = 0;
+        S->mark = 0;
+        S->pertinent_child_count = 0;
+        S->pertinent_leaf_count = 0;
+        return S;
+    }
+    root = PQ_node_alloc ();
+
+    PQ_set_INIT (root->children_set);
+    PQ_set_INIT (root->full_children_set);
+    PQ_set_INIT (root->partial_children_set);
+    root->type = P_NODE;
+    root->parent = (PQ_node *) NULL;
+    root->parenttype = P_NODE;
+
+    for (x = S; x; x = x->next) {
+        x->parent = root;
+        x->parenttype = P_NODE;
+        PQ_set_ADD (x, root->children_set, children_elem);
+        x->label = 0;
+        x->mark = 0;
+        x->type = LEAF_NODE;
+        PQ_set_INIT (x->children_set);
+        PQ_set_INIT (x->full_children_set);
+        PQ_set_INIT (x->partial_children_set);
+        x->pertinent_child_count = 0;
+        x->pertinent_leaf_count = 0;
+    }
+    return root;
+}
+
+/* PQ_bubble forms the first half of the PQ-tree implementation.
+ *
+ * It takes as input a list of PQ_node(s) linked by (next).
+ *
+ * It fills in the parent field of all the nodes in the PQ-tree, notices certain
+ * unsatisfiable requests, fills in the pertinent_child_counts, ...
+ *
+ * It returns either BUBBLE_NO_SOL or BUBBLE_SUCCESS. */
+
+#ifdef CC_PROTOTYPE_ANSI
+static int PQ_bubble (PQ_node *S)
+#else
+static int PQ_bubble (S)
+PQ_node *S;
+#endif
+{
+    PQ_set q;
+    int block_count;
+    PQ_node *x;
+    PQ_node *zprev, *z, *znext;
+    PQ_node *leftsib, *rightsib;
+    int i;
+    int nbs;
+
+    assert (check_tree (S));
+
+    markbase += 4;
+    PQ_set_INIT (q);
+    block_count = 0;
+    PQ_set_INIT (blocked_set);
+    off_the_top = 0;
+
+    for (x = S; x; x = x->next) {
+        PQ_set_ADD_LEFT (x, q, queue_elem);
+    }
+
+    while (PQ_set_SIZE (q) + block_count + off_the_top > 1) {
+        if (PQ_set_ISEMPTY (q)) {
+            return 0;
+        }
+        x = PQ_set_RIGHT_ELEM (q);
+        PQ_set_DELETE (x, q, queue_elem);
+        x->mark = BLOCKED;
+
+        x->pertinent_leaf_count = 0;
+        PQ_set_INIT (x->full_children_set);
+        PQ_set_INIT (x->partial_children_set);
+
+        nbs = 0;
+
+        leftsib = PQ_next_nondir (x->children_elem.ptr1, x);
+        rightsib = PQ_next_nondir (x->children_elem.ptr2, x);
+
+        if (leftsib && leftsib->mark == BLOCKED) {
+            nbs++;
+        }
+        if (rightsib && rightsib->mark == BLOCKED) {
+            nbs++;
+        }
+        if (x->parenttype == P_NODE || leftsib == (PQ_node *) NULL
+            || rightsib == (PQ_node *) NULL) {
+            x->mark = UNBLOCKED;
+        } else if (leftsib->mark == UNBLOCKED) {
+            z = x;
+            zprev = x->children_elem.ptr2;
+            PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+                if (z == leftsib) {
+                    break;
+                }
+                z->parent = leftsib->parent;
+                z->mark = UNBLOCKED;
+            }
+            assert (z == leftsib);
+        } else if (rightsib->mark == UNBLOCKED) {
+            z = x;
+            zprev = x->children_elem.ptr1;
+            PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+                if (z == rightsib) {
+                    break;
+                }
+                z->parent = rightsib->parent;
+                z->mark = UNBLOCKED;
+            }
+            assert (z == rightsib);
+        }
+        if (x->mark == UNBLOCKED) {
+            if (x->parent && IS_UNINITIALIZED (x->parent)) {
+                x->parent->mark = UNMARKED;
+                x->parent->pertinent_child_count = 0;
+            }
+            PQ_set_FOREACH_ADJ (x, children_elem, z, i) {
+                zprev = x;
+                PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+                    if (z->type == DIR_NODE) {
+                        z->parent = x->parent;
+                    } else if (z->mark == BLOCKED) {
+                        z->parent = x->parent;
+                        z->mark = UNBLOCKED;
+                        if (x->parent) {
+                            x->parent->pertinent_child_count++;
+                        }
+                        PQ_set_DELETE (z, blocked_set, blocked_elem);
+                    } else {
+                        break;
+                    }
+                }
+            }
+
+            if (x->parent) {
+                x->parent->pertinent_child_count++;
+                if (x->parent->mark == UNMARKED) {
+                    PQ_set_ADD_LEFT (x->parent, q, queue_elem);
+                    x->parent->mark = QUEUED;
+                }
+            } else {
+                off_the_top = 1;
+            }
+            block_count -= nbs;
+        } else {
+            block_count = block_count + 1 - nbs;
+            PQ_set_ADD (x, blocked_set, blocked_elem);
+        }
+    }
+    if (!PQ_set_ISEMPTY (q)) {
+        x = PQ_set_LEFT_ELEM (q);
+        x->pertinent_leaf_count = 0;
+        if (x->pertinent_child_count == 1) {
+            x->pertinent_child_count = 0;
+        }
+        PQ_set_INIT (x->full_children_set);
+        PQ_set_INIT (x->partial_children_set);
+    }
+    if (block_count) {
+        pseudo_root.type = Q_NODE;
+        pseudo_root.parent = (PQ_node *) NULL;
+        pseudo_root.pertinent_child_count = 0;
+        PQ_set_FOREACH (blocked_set, x, blocked_elem, zprev, znext) {
+            x->parent = &pseudo_root;
+            pseudo_root.pertinent_child_count++;
+        }
+        pseudo_root.pertinent_leaf_count = 0;
+        PQ_set_INIT (pseudo_root.full_children_set);
+        PQ_set_INIT (pseudo_root.partial_children_set);
+        pseudo_root.label = 0;
+    }
+    assert (check_tree (S));
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_reduce (PQ_node *S)
+#else
+static PQ_node *PQ_reduce (S)
+PQ_node *S;
+#endif
+{
+    PQ_set q;
+    PQ_node *x;
+    int ssize;
+    PQ_node *y;
+
+    assert (check_tree (S));
+
+    PQ_set_INIT (q);
+
+    for (x = S, ssize = 0; x; x = x->next, ssize++) {
+        PQ_set_ADD_LEFT (x, q, queue_elem);
+        x->pertinent_leaf_count = 1;
+    }
+    while (!PQ_set_ISEMPTY (q)) {
+        x = PQ_set_RIGHT_ELEM (q);
+        PQ_set_DELETE (x, q, queue_elem);
+
+        assert (check_node_pert (x));
+
+        if (x->pertinent_leaf_count < ssize) {
+            /* x is not the root of the pertinent subtree */
+            assert (checkout_before (x, 0));
+            y = x->parent;
+            y->pertinent_leaf_count += x->pertinent_leaf_count;
+            y->pertinent_child_count--;
+            if (y->pertinent_child_count == 0) {
+                PQ_set_ADD_LEFT (y, q, queue_elem);
+            }
+            /* now, the templates */
+            if (!PQ_template_l1 (x) &&
+                !PQ_template_p1 (x) &&
+                !PQ_template_p3_notroot (x) &&
+                !PQ_template_p5_notroot (x) &&
+                !PQ_template_q1 (x) &&
+                !PQ_template_q2 (x)) {
+                return (PQ_node *) NULL;
+            }
+            assert (checkout_after (x, 0));
+        } else {
+            /* x is the root of the pertinent subtree */
+            assert (checkout_before (x, 1));
+            assert (PQ_set_ISEMPTY (q));
+            if ((y = PQ_template_l1 (x)) ||
+                (y = PQ_template_p1 (x)) ||
+                (y = PQ_template_p2_root (x)) ||
+                (y = PQ_template_p4_root (x)) ||
+                (y = PQ_template_p6_root (x)) ||
+                (y = PQ_template_q1 (x)) ||
+                (y = PQ_template_q2 (x)) ||
+                (y = PQ_template_q3_root (x))) {
+                assert (check_tree (S));
+                return y;
+            } else {
+                return (PQ_node *) NULL;
+            }
+        }
+    }
+    return (PQ_node *) NULL;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_l1 (PQ_node *x)
+#else
+static PQ_node *PQ_template_l1 (x)
+PQ_node *x;
+#endif
+{
+    if (x->type != LEAF_NODE) {
+        return (PQ_node *) NULL;
+    }
+    PQ_label_full (x);
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_p1 (PQ_node *x)
+#else
+static PQ_node *PQ_template_p1 (x)
+PQ_node *x;
+#endif
+{
+    if (x->type != P_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (PQ_set_SIZE (x->full_children_set) != PQ_set_SIZE (x->children_set)) {
+        return (PQ_node *) NULL;
+    }
+    PQ_label_full (x);
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_p3_notroot (PQ_node *x)
+#else
+static PQ_node *PQ_template_p3_notroot (x)
+PQ_node *x;
+#endif
+{
+    if (x->type != P_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (!PQ_set_ISEMPTY (x->partial_children_set)) {
+        return (PQ_node *) NULL;
+    }
+    assert (!PQ_set_ISEMPTY (x->full_children_set));
+    assert (PQ_set_SIZE (x->full_children_set) != PQ_set_SIZE (x->children_set));
+
+    PQ_collect_full_children (x, Q_NODE);
+    x = PQ_collect_empty_children (x, Q_NODE);
+
+    PQ_label_partial (x);
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_p5_notroot (PQ_node *x)
+#else
+static PQ_node *PQ_template_p5_notroot (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *partial_child;
+    PQ_node *full_child;
+    PQ_node *z;
+
+    if (x->type != P_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (PQ_set_SIZE (x->partial_children_set) != 1) {
+        return (PQ_node *) NULL;
+    }
+    partial_child = PQ_set_LEFT_ELEM (x->partial_children_set);
+    PQ_set_DELETE (partial_child, x->children_set, children_elem);
+    PQ_set_DELETE (partial_child, x->partial_children_set, partial_children_elem);
+
+    PQ_collect_full_children (x, Q_NODE);
+    if (!PQ_set_ISEMPTY (x->full_children_set)) {
+        full_child = PQ_set_LEFT_ELEM (x->full_children_set);
+        PQ_set_DELETE (full_child, x->children_set, children_elem);
+        PQ_set_DELETE (full_child, x->full_children_set, full_children_elem);
+        full_child->parent = partial_child;
+        full_child->parenttype = Q_NODE;
+        if (PQ_left_end_is_full (partial_child)) {
+            PQ_set_ADD_LEFT (full_child, partial_child->children_set, children_elem);
+            PQ_set_ADD_LEFT (full_child, partial_child->full_children_set, full_children_elem);
+        } else {
+            PQ_set_ADD_RIGHT (full_child, partial_child->children_set, children_elem);
+            PQ_set_ADD_RIGHT (full_child, partial_child->full_children_set, full_children_elem);
+        }
+    }
+    PQ_replace_node (x, partial_child);
+
+    if (PQ_set_ISEMPTY (x->children_set)) {
+        PQ_node_free (x);
+    } else {
+        if (PQ_set_SIZE (x->children_set) == 1) {
+            z = PQ_set_LEFT_ELEM (x->children_set);
+            PQ_node_free (x);
+            x = z;
+        }
+        x->parent = partial_child;
+        x->parenttype = Q_NODE;
+        if (PQ_left_end_is_full (partial_child)) {
+            PQ_set_ADD_RIGHT (x, partial_child->children_set, children_elem);
+        } else {
+            PQ_set_ADD_LEFT (x, partial_child->children_set, children_elem);
+        }
+    }
+    PQ_label_partial (partial_child);
+    return partial_child;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_q1 (PQ_node *x)
+#else
+static PQ_node *PQ_template_q1 (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+
+    if (x->type != Q_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (x == &pseudo_root) {
+        return (PQ_node *) NULL;
+    }
+    PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+        if (z->label != FULL && z->type != DIR_NODE) {
+            return (PQ_node *) NULL;
+        }
+    }
+    PQ_label_full (x);
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_q2 (PQ_node *x)
+#else
+static PQ_node *PQ_template_q2 (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *partial_child;
+    int full_count;
+    PQ_node *z, *zprev, *znext;
+    PQ_node *full_end, *empty_end;
+
+    if (x->type != Q_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (x == &pseudo_root) {
+        return (PQ_node *) NULL;
+    }
+    if (PQ_set_SIZE (x->partial_children_set) > 1) {
+        return (PQ_node *) NULL;
+    }
+    if (PQ_left_end_is_full (x)) {
+        full_end = PQ_set_LEFT_ELEM (x->children_set);
+        empty_end = PQ_set_RIGHT_ELEM (x->children_set);
+    } else {
+        full_end = PQ_set_RIGHT_ELEM (x->children_set);
+        empty_end = PQ_set_LEFT_ELEM (x->children_set);
+    }
+
+    full_count = 0;
+    z = full_end;
+    zprev = (PQ_node *) NULL;
+
+    PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+        if (z->label == FULL) {
+            full_count++;
+        } else if (z->type != DIR_NODE) {
+            break;
+        }
+    }
+
+    if (full_count != PQ_set_SIZE (x->full_children_set)) {
+        return (PQ_node *) NULL;
+    }
+    if (!PQ_set_ISEMPTY (x->partial_children_set) &&
+        z != PQ_set_LEFT_ELEM (x->partial_children_set)) {
+        return (PQ_node *) NULL;
+    }
+    assert (!PQ_set_ISEMPTY (x->full_children_set) || !PQ_set_ISEMPTY (x->partial_children_set));
+
+    if (!PQ_set_ISEMPTY (x->partial_children_set)) {
+        partial_child = PQ_set_LEFT_ELEM (x->partial_children_set);
+        PQ_set_DELETE (partial_child, x->partial_children_set, partial_children_elem);
+        PQ_merge_qnode (partial_child);
+    }
+    PQ_label_partial (x);
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_p2_root (PQ_node *x)
+#else
+static PQ_node *PQ_template_p2_root (x)
+PQ_node *x;
+#endif
+{
+    if (x->type != P_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (!PQ_set_ISEMPTY (x->partial_children_set)) {
+        return (PQ_node *) NULL;
+    }
+    assert (!PQ_set_ISEMPTY (x->full_children_set));
+    assert (PQ_set_SIZE (x->full_children_set) != PQ_set_SIZE (x->children_set));
+
+    PQ_collect_full_children (x, P_NODE);
+
+    return PQ_set_LEFT_ELEM (x->full_children_set);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_p4_root (PQ_node *x)
+#else
+static PQ_node *PQ_template_p4_root (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *partial_child;
+    PQ_node *full_child;
+
+    if (x->type != P_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (PQ_set_SIZE (x->partial_children_set) != 1) {
+        return (PQ_node *) NULL;
+    }
+    partial_child = PQ_set_LEFT_ELEM (x->partial_children_set);
+
+    PQ_collect_full_children (x, Q_NODE);
+
+    if (!PQ_set_ISEMPTY (x->full_children_set)) {
+        full_child = PQ_set_LEFT_ELEM (x->full_children_set);
+        PQ_set_DELETE (full_child, x->children_set, children_elem);
+        PQ_set_DELETE (full_child, x->full_children_set, full_children_elem);
+        full_child->parent = partial_child;
+        full_child->parenttype = Q_NODE;
+        if (PQ_left_end_is_full (partial_child)) {
+            PQ_set_ADD_LEFT (full_child, partial_child->children_set, children_elem);
+            PQ_set_ADD_LEFT (full_child, partial_child->full_children_set, full_children_elem);
+        } else {
+            PQ_set_ADD_RIGHT (full_child, partial_child->children_set, children_elem);
+            PQ_set_ADD_RIGHT (full_child, partial_child->full_children_set, full_children_elem);
+        }
+    }
+    if (PQ_set_SIZE (x->children_set) == 1) {
+        full_child = PQ_set_LEFT_ELEM (x->children_set);
+        PQ_replace_node (x, full_child);
+        PQ_node_free (x);
+    }
+    return partial_child;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_p6_root (PQ_node *x)
+#else
+static PQ_node *PQ_template_p6_root (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *partial_child1, *partial_child2;
+    PQ_node *full_end1, *empty_end1, *full_end2, *empty_end2;
+    PQ_node *z, *zprev, *znext;
+    PQ_node *full_child;
+
+    if (x->type != P_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (PQ_set_SIZE (x->partial_children_set) > 2) {
+        return (PQ_node *) NULL;
+    }
+    assert (PQ_set_SIZE (x->partial_children_set) == 2);
+
+    partial_child1 = PQ_set_LEFT_ELEM (x->partial_children_set);
+    partial_child2 = PQ_set_RIGHT_ELEM (x->partial_children_set);
+
+    PQ_collect_full_children (x, Q_NODE);
+
+    if (!PQ_set_ISEMPTY (x->full_children_set)) {
+        full_child = PQ_set_LEFT_ELEM (x->full_children_set);
+        PQ_set_DELETE (full_child, x->children_set, children_elem);
+        PQ_set_DELETE (full_child, x->full_children_set, full_children_elem);
+
+        full_child->parent = partial_child1;
+        full_child->parenttype = Q_NODE;
+        if (PQ_left_end_is_full (partial_child1)) {
+            PQ_set_ADD_LEFT (full_child, partial_child1->children_set, children_elem);
+            PQ_set_ADD_LEFT (full_child, partial_child1->full_children_set, full_children_elem);
+        } else {
+            PQ_set_ADD_RIGHT (full_child, partial_child1->children_set, children_elem);
+            PQ_set_ADD_RIGHT (full_child, partial_child1->full_children_set, full_children_elem);
+        }
+    }
+    if (PQ_left_end_is_full (partial_child1)) {
+        full_end1 = PQ_set_LEFT_ELEM (partial_child1->children_set);
+        empty_end1 = PQ_set_RIGHT_ELEM (partial_child1->children_set);
+    } else {
+        full_end1 = PQ_set_RIGHT_ELEM (partial_child1->children_set);
+        empty_end1 = PQ_set_LEFT_ELEM (partial_child1->children_set);
+    }
+    if (PQ_left_end_is_full (partial_child2)) {
+        full_end2 = PQ_set_LEFT_ELEM (partial_child2->children_set);
+        empty_end2 = PQ_set_RIGHT_ELEM (partial_child2->children_set);
+    } else {
+        full_end2 = PQ_set_RIGHT_ELEM (partial_child2->children_set);
+        empty_end2 = PQ_set_LEFT_ELEM (partial_child2->children_set);
+    }
+
+    PQ_set_PTR_REPLACE (full_end1->children_elem, 0, full_end2);
+    PQ_set_PTR_REPLACE (full_end2->children_elem, 0, full_end1);
+
+    if (partial_child1->children_set.left == full_end1) {
+        partial_child1->children_set.left = empty_end2;
+    } else {
+        partial_child1->children_set.right = empty_end2;
+    }
+    partial_child1->children_set.size += partial_child2->children_set.size;
+    empty_end2->parent = partial_child1;
+
+    PQ_set_FOREACH_DEL (partial_child2->full_children_set, z, full_children_elem, zprev, znext) {
+        PQ_set_DELETE (z, partial_child2->full_children_set, full_children_elem);
+        PQ_set_ADD (z, partial_child1->full_children_set, full_children_elem);
+        z->parent = partial_child1;
+    }
+
+    PQ_set_DELETE (partial_child2, x->children_set, children_elem);
+    PQ_set_DELETE (partial_child2, x->partial_children_set, partial_children_elem);
+
+    PQ_node_free (partial_child2);
+
+    if (PQ_set_SIZE (x->children_set) == 1) {
+        full_child = PQ_set_LEFT_ELEM (x->children_set);
+        PQ_replace_node (x, full_child);
+        PQ_node_free (x);
+    }
+    return partial_child1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_template_q3_root (PQ_node *x)
+#else
+static PQ_node *PQ_template_q3_root (x)
+PQ_node *x;
+#endif
+{
+    int full_count;
+    PQ_node *z, *zprev, *znext, *zstart;
+
+    /* note that we cannot talk about x->children_set, since x might be the
+     * pseudo_root */
+
+    if (x->type != Q_NODE) {
+        return (PQ_node *) NULL;
+    }
+    if (PQ_set_ISEMPTY (x->partial_children_set)) {
+        zstart = PQ_set_LEFT_ELEM (x->full_children_set);
+        assert (zstart->label == FULL);
+        full_count = 1;
+        zprev = zstart;
+        z = zstart->children_elem.ptr1;
+
+        PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+            if (z->label == FULL) {
+                full_count++;
+            } else if (z->type != DIR_NODE) {
+                break;
+            }
+        }
+
+        zprev = zstart;
+        z = zstart->children_elem.ptr2;
+
+        PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+            if (z->label == FULL) {
+                full_count++;
+            } else if (z->type != DIR_NODE) {
+                break;
+            }
+        }
+        if (full_count != PQ_set_SIZE (x->full_children_set)) {
+            return (PQ_node *) NULL;
+        }
+    } else {
+        zstart = PQ_set_LEFT_ELEM (x->partial_children_set);
+        z = PQ_next_nondir (zstart->children_elem.ptr1, zstart);
+
+        if (z && !IS_EMPTY (z)) {
+            z = zstart->children_elem.ptr1;
+        } else {
+            z = zstart->children_elem.ptr2;
+        }
+
+        zprev = zstart;
+        full_count = 0;
+        PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+            if (z->label == FULL) {
+                full_count++;
+            } else if (z->type != DIR_NODE) {
+                break;
+            }
+        }
+        if (full_count != PQ_set_SIZE (x->full_children_set)) {
+            return (PQ_node *) NULL;
+        }
+        if (z && z->label == PARTIAL && PQ_set_SIZE (x->partial_children_set) != 2) {
+            return (PQ_node *) NULL;
+        }
+        if (z && z->label != PARTIAL && PQ_set_SIZE (x->partial_children_set) != 1) {
+            return (PQ_node *) NULL;
+        }
+    }
+
+    PQ_set_FOREACH_DEL (x->partial_children_set, z, partial_children_elem, zprev, znext) {
+        PQ_set_DELETE (z, x->partial_children_set, partial_children_elem);
+        PQ_merge_qnode (z);
+    }
+
+    return x;
+}
+
+/* PQ_label_full marks a node as full, and if it has a parent, adds it to the
+ * parents list of full children */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_label_full (PQ_node *x)
+#else
+static void PQ_label_full (x)
+PQ_node *x;
+#endif
+{
+    x->label = FULL;
+    if (x->parent) {
+        PQ_set_ADD (x, x->parent->full_children_set, full_children_elem);
+    }
+} /* PQ_LABEL_FULL */
+
+/* PQ_label_partial marks a node as partial, and if it has a parent, adds it
+ * to the parents list of partial children */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_label_partial (PQ_node *x)
+#else
+static void PQ_label_partial (x)
+PQ_node *x;
+#endif
+{
+    x->label = PARTIAL;
+    if (x->parent) {
+        PQ_set_ADD (x, x->parent->partial_children_set, partial_children_elem);
+    }
+}
+
+/* PQ_collect_full_children collects all the full children of x, and places
+ * them under a new P-node below x.  It sets the parenttype of the new node
+ * to t */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_collect_full_children (PQ_node *x, int t)
+#else
+static void PQ_collect_full_children (x, t)
+PQ_node *x;
+int t;
+#endif
+{
+    PQ_node *new_node;
+    PQ_node *z, *zprev, *znext;
+
+    assert (x->type == P_NODE);
+    if (PQ_set_SIZE (x->full_children_set) > 1) {
+        new_node = PQ_node_alloc ();
+        PQ_set_INIT (new_node->children_set);
+        PQ_set_INIT (new_node->full_children_set);
+        PQ_set_INIT (new_node->partial_children_set);
+        new_node->label = FULL;
+        new_node->type = P_NODE;
+        PQ_set_FOREACH_DEL (x->full_children_set, z, full_children_elem, zprev, znext) {
+            PQ_set_DELETE (z, x->children_set, children_elem);
+            PQ_set_DELETE (z, x->full_children_set, full_children_elem);
+            z->parent = new_node;
+            z->parenttype = P_NODE;
+            PQ_set_ADD (z, new_node->children_set, children_elem);
+            PQ_set_ADD (z, new_node->full_children_set, full_children_elem);
+        }
+        assert (PQ_set_ISEMPTY (x->full_children_set));
+        new_node->parent = x;
+        new_node->parenttype = t;
+        PQ_set_ADD (new_node, x->children_set, children_elem);
+        PQ_set_ADD (new_node, x->full_children_set, full_children_elem);
+    } else if (PQ_set_SIZE (x->full_children_set) == 1) {
+        z = PQ_set_LEFT_ELEM (x->full_children_set);
+        z->parenttype = t;
+    }
+} /* PQ_COLLECT_FULL_CHILDREN */
+
+/* PQ_collect_empty_children collects all the emtpy children of x, and places
+ * them under a new P-node below x.  It sets the parenttype of the new node
+ * to t.  If there is more than 1 empty child, it actually does this by
+ * creating a new node to replace x, and moves all the full children of x to
+ * the new node, and moves x down.  It returns a pointer to the node that is
+ * where x used to be. */
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_collect_empty_children (PQ_node *x, int t)
+#else
+static PQ_node *PQ_collect_empty_children (x, t)
+PQ_node *x;
+int t;
+#endif
+{
+    PQ_node *y;
+    PQ_node *z, *zprev, *znext;
+    PQ_node *new_node;
+
+    assert (x->type == P_NODE);
+    assert (PQ_set_ISEMPTY (x->partial_children_set));
+    assert (PQ_set_SIZE (x->children_set) > PQ_set_SIZE (x->full_children_set));
+
+    if (PQ_set_SIZE (x->children_set) - PQ_set_SIZE (x->full_children_set) > 1) {
+        new_node = PQ_node_alloc ();
+        PQ_set_INIT (new_node->children_set);
+        PQ_set_INIT (new_node->full_children_set);
+        PQ_set_INIT (new_node->partial_children_set);
+        new_node->label = x->label;
+        new_node->type = t;
+
+        PQ_set_FOREACH_DEL (x->full_children_set, z, full_children_elem, zprev, znext) {
+            PQ_set_DELETE (z, x->children_set, children_elem);
+            PQ_set_DELETE (z, x->full_children_set, full_children_elem);
+            z->parent = new_node;
+            z->parenttype = t;
+            PQ_set_ADD (z, new_node->children_set, children_elem);
+            PQ_set_ADD (z, new_node->full_children_set, full_children_elem);
+        }
+
+        y = x->parent;
+        new_node->parent = y;
+        new_node->parenttype = x->parenttype;
+        new_node->children_elem.ptr1 = x->children_elem.ptr1;
+        new_node->children_elem.ptr2 = x->children_elem.ptr2;
+        if (y) {
+            PQ_neighbor_replace (new_node->children_elem.ptr1, &y->children_set, x, new_node);
+            PQ_neighbor_replace (new_node->children_elem.ptr2, &y->children_set, x, new_node);
+        }
+        x->parent = new_node;
+        x->parenttype = t;
+
+        x->label = EMPTY;
+        PQ_set_ADD (x, new_node->children_set, children_elem);
+
+        x = new_node;
+    } else if (PQ_set_SIZE (x->children_set) - PQ_set_SIZE (x->full_children_set) == 1) {
+        PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+            if (IS_EMPTY (z)) {
+                z->parenttype = t;
+                break;
+            }
+        }
+        x->type = t;
+    }
+    return x;
+}
+
+/* PQ_neighbor_replace replaces the pointer to q in the children list with a
+ * pointer to r */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_neighbor_replace (PQ_node *x, PQ_set *s, PQ_node *q,
+                                 PQ_node *r)
+#else
+static void PQ_neighbor_replace (x, s, q, r)
+PQ_node *x;
+PQ_set *s;
+PQ_node *q;
+PQ_node *r;
+#endif
+{
+    if (x) {
+        PQ_set_PTR_REPLACE (x->children_elem, q, r);
+    } else {
+        if (s->left == q) {
+            s->left = r;
+        } else {
+            assert (s->right == q);
+            s->right = r;
+        }
+    }
+}
+
+/* PQ_merge_qnode merges x into its parent */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_merge_qnode (PQ_node *x)
+#else
+static void PQ_merge_qnode (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *parent = x->parent;
+    PQ_node *full_end, *empty_end;
+    PQ_node *z, *zprev, *znext;
+    PQ_node *empty_neighbor, *full_neighbor;
+    PQ_node *empty_neighbor2, *full_neighbor2;
+
+    assert (x->type == Q_NODE);
+    if (PQ_left_end_is_full (x)) {
+        full_end = PQ_set_LEFT_ELEM (x->children_set);
+        empty_end = PQ_set_RIGHT_ELEM (x->children_set);
+    } else {
+        full_end = PQ_set_RIGHT_ELEM (x->children_set);
+        empty_end = PQ_set_LEFT_ELEM (x->children_set);
+    }
+
+    PQ_set_FOREACH_DEL (x->full_children_set, z, full_children_elem, zprev, znext) {
+        PQ_set_DELETE (z, x->full_children_set, full_children_elem);
+        PQ_set_ADD (z, parent->full_children_set, full_children_elem);
+        z->parent = parent;
+    }
+
+    full_end->parent = parent;
+    empty_end->parent = parent;
+    empty_neighbor = x->children_elem.ptr1;
+    full_neighbor = x->children_elem.ptr2;
+    empty_neighbor2 = PQ_next_nondir (empty_neighbor, x);
+    full_neighbor2 = PQ_next_nondir (full_neighbor, x);
+    if ((empty_neighbor2 && !IS_EMPTY (empty_neighbor2)) ||
+        (full_neighbor2 && IS_EMPTY (full_neighbor2))) {
+        SWAP (empty_neighbor, full_neighbor, z);
+        SWAP (empty_neighbor2, full_neighbor2, z);
+    }
+    assert (full_end != empty_end);
+    assert (empty_neighbor2 == 0 || IS_EMPTY (empty_neighbor2));
+    assert (full_neighbor2 == 0 || full_neighbor2->label == FULL || full_neighbor2->label == PARTIAL);
+    assert (empty_neighbor2 || full_neighbor2);
+
+    PQ_set_PTR_REPLACE (full_end->children_elem, 0, full_neighbor);
+    PQ_set_PTR_REPLACE (empty_end->children_elem, 0, empty_neighbor);
+    PQ_neighbor_replace (full_neighbor, &parent->children_set, x, full_end);
+    PQ_neighbor_replace (empty_neighbor, &parent->children_set, x, empty_end);
+
+    parent->children_set.size += x->children_set.size - 1;
+
+    PQ_node_free (x);
+}
+
+/* PQ_replace_node replaces old with new */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_replace_node (PQ_node *old, PQ_node *new)
+#else
+static void PQ_replace_node (old, new)
+PQ_node *old;
+PQ_node *new;
+#endif
+{
+    new->parent = old->parent;
+    new->parenttype = old->parenttype;
+
+    new->children_elem.ptr1 = old->children_elem.ptr1;
+    new->children_elem.ptr2 = old->children_elem.ptr2;
+
+    if (new->parent) {
+        PQ_neighbor_replace (new->children_elem.ptr1, &new->parent->children_set, old, new);
+        PQ_neighbor_replace (new->children_elem.ptr2, &new->parent->children_set, old, new);
+    } else {
+        if (new->children_elem.ptr1) {
+            PQ_set_PTR_REPLACE (new->children_elem.ptr1->children_elem, old, new);
+        }
+        if (new->children_elem.ptr2) {
+            PQ_set_PTR_REPLACE (new->children_elem.ptr2->children_elem, old, new);
+        }
+    }
+}
+
+/* PQ_left_end_is_full is a boolean which indicates whether the left end of a
+ * partial Q_NODE is full or not */
+
+#ifdef CC_PROTOTYPE_ANSI
+static int PQ_left_end_is_full (PQ_node *x)
+#else
+static int PQ_left_end_is_full (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *left_end;
+    PQ_node *right_end;
+
+    assert (x->type == Q_NODE);
+
+    left_end = PQ_next_nondir (PQ_set_LEFT_ELEM (x->children_set), (PQ_node *) NULL);
+    right_end = PQ_next_nondir (PQ_set_RIGHT_ELEM (x->children_set), (PQ_node *) NULL);
+    return IS_EMPTY (right_end) || left_end->label == FULL;
+}
+
+/* PQ_next_nondir finds the next neighbor which is not of type DIR_NODE,
+ * heading from z away from zprev */
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_next_nondir (PQ_node *z, PQ_node *zprev)
+#else
+static PQ_node *PQ_next_nondir (z, zprev)
+PQ_node *z;
+PQ_node *zprev;
+#endif
+{
+    PQ_node *znext;
+
+    PQ_set_FOREACH_FROM (z, children_elem, zprev, znext) {
+        if (z->type != DIR_NODE)
+            return z;
+    }
+    return (PQ_node *) NULL;
+}
+
+static int node_counter = -1;
+static PQ_node *PQ_node_freelist = (PQ_node *) NULL;
+
+#define PQ_alloc_chunk (((1<<17)-16)/sizeof (PQ_node))
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_node_alloc_work (void)
+#else
+static PQ_node *PQ_node_alloc_work ()
+#endif
+{
+    PQ_node *x;
+    int i;
+
+    if (!PQ_node_freelist) {
+        PQ_node_freelist = CC_SAFE_MALLOC (PQ_alloc_chunk, PQ_node);
+        if (!PQ_node_freelist) {
+            fprintf (stderr, "out of memory in PQ_node_alloc_work\n");
+            exit (1);
+        }
+        printf ("MALLOC %d PQ NODES\n", (int) PQ_alloc_chunk);
+        fflush (stdout);
+        if (!PQ_node_freelist) {
+            fprintf (stderr, "Out of memory\n");
+            exit (1);
+        }
+        for (i = 0; i < (int) PQ_alloc_chunk - 1; i++) {
+            PQ_node_freelist[i].next = &PQ_node_freelist[i + 1];
+        }
+        PQ_node_freelist[PQ_alloc_chunk - 1].next = (PQ_node *) NULL;
+    }
+    x = PQ_node_freelist;
+    PQ_node_freelist = PQ_node_freelist->next;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_node_alloc (void)
+#else
+static PQ_node *PQ_node_alloc ()
+#endif
+{
+    PQ_node *x;
+
+    x = PQ_node_alloc_work ();
+    x->next = (PQ_node *) NULL;
+    x->number = node_counter;
+    node_counter--;
+    x->base_edge = (struct Xedge *) NULL;
+    x->queue_elem.ptr1 = (PQ_node *) NULL;
+    x->queue_elem.ptr2 = (PQ_node *) NULL;
+    PQ_set_INIT (x->children_set);
+    PQ_set_INIT (x->partial_children_set);
+    PQ_set_INIT (x->full_children_set);
+    x->children_elem.ptr1 = (PQ_node *) NULL;
+    x->children_elem.ptr2 = (PQ_node *) NULL;
+    x->partial_children_elem.ptr1 = (PQ_node *) NULL;
+    x->partial_children_elem.ptr2 = (PQ_node *) NULL;
+    x->full_children_elem.ptr1 = (PQ_node *) NULL;
+    x->full_children_elem.ptr2 = (PQ_node *) NULL;
+    x->blocked_elem.ptr1 = (PQ_node *) NULL;
+    x->blocked_elem.ptr2 = (PQ_node *) NULL;
+    x->leaves_elem.ptr1 = (PQ_node *) NULL;
+    x->leaves_elem.ptr2 = (PQ_node *) NULL;
+    x->parent = (PQ_node *) NULL;
+    x->pertinent_child_count = 0;
+    x->pertinent_leaf_count = 0;
+    x->mark = 0;
+    x->type = 0;
+    x->parenttype = 0;
+    x->label = 0;
+    x->magiclabel = 0;
+
+    return x;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_node_free (PQ_node *x)
+#else
+static void PQ_node_free (x)
+PQ_node *x;
+#endif
+{
+    x->next = PQ_node_freelist;
+    PQ_node_freelist = x;
+}
+
+/* PQ_tree_free recursively frees the tree rooted at x */
+
+#ifdef CC_PROTOTYPE_ANSI
+static void PQ_tree_free (PQ_node *x, int saveleaves)
+#else
+static void PQ_tree_free (x, saveleaves)
+PQ_node *x;
+int saveleaves;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+
+    PQ_set_FOREACH_DEL (x->children_set, z, children_elem, zprev, znext) {
+        PQ_set_DELETE (z, x->children_set, children_elem);
+        PQ_tree_free (z, saveleaves);
+    }
+    if (!(saveleaves && (x->type == DIR_NODE || x->type == LEAF_NODE))) {
+        PQ_node_free (x);
+    }
+}
+
+/* PQ_free_all frees storage for a tree */
+
+#ifdef CC_PROTOTYPE_ANSI
+void XPQ_free_all (PQ_node *x, int saveleaves)
+#else
+void XPQ_free_all (x, saveleaves)
+PQ_node *x;
+int saveleaves;
+#endif
+{
+    PQ_tree_free (XPQ_find_root (x), saveleaves);
+}
+
+/* PQ_find_root is only used by the dump and check routines, and PQ_free_all */
+
+#ifdef CC_PROTOTYPE_ANSI
+PQ_node *XPQ_find_root (PQ_node *x)
+#else
+PQ_node *XPQ_find_root (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *zprev, *znext;
+
+    for (;;) {
+        if (x->parenttype == P_NODE) {
+            if (x->parent)
+                x = x->parent;
+            else
+                return x;
+        } else {
+            zprev = x->children_elem.ptr1;
+            PQ_set_FOREACH_FROM (x, children_elem, zprev, znext);
+            if (zprev->parent)
+                x = zprev->parent;
+            else
+                return zprev;
+        }
+    }
+}
+
+#ifndef NDEBUG
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_solution (PQ_node *x)
+#else
+static void dump_solution (x)
+PQ_node *x;
+#endif
+{
+    dump_subtree (XPQ_find_root (x));
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void dump_subtree (PQ_node *x)
+#else
+static void dump_subtree (x)
+PQ_node *x;
+#endif
+{
+    print_solution (x, (PQ_node *) NULL);
+    printf ("\n");
+}
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+static void print_solution (PQ_node *x, PQ_node *xprev)
+#else
+static void print_solution (x, xprev)
+PQ_node *x;
+PQ_node *xprev;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+
+    if (x->type == LEAF_NODE) {
+        printf ("%d ", x->number);
+    } else if (x->type == DIR_NODE) {
+        if (x->children_elem.ptr1 == xprev) {
+            printf ("<<%d<< ", x->number);
+        } else {
+            printf (">>%d>> ", x->number);
+        }
+    } else if (x->type == P_NODE) {
+        printf ("(");
+        PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+            print_solution (z, zprev);
+        }
+        printf (")<%d> ", x->number);
+    } else {
+        printf ("[");
+        PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+            print_solution (z, zprev);
+        }
+        printf ("]<%d> ", x->number);
+    }
+}
+
+/* the various check routines are for debugging use only, to verify that the
+ * state of the PQ_tree is valid. */
+
+#ifndef NDEBUG
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkout_before (PQ_node *x, int isroot)
+#else
+static int checkout_before (x, isroot)
+PQ_node *x;
+int isroot;
+#endif
+{
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int checkout_after (PQ_node *x, int isroot)
+#else
+static int checkout_after (x, isroot)
+PQ_node *x;
+int isroot;
+#endif
+{
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_tree (PQ_node *x)
+#else
+static int check_tree (x)
+PQ_node *x;
+#endif
+{
+    if (!check_subtree (XPQ_find_root (x))) {
+        dump_solution (x);
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_subtree (PQ_node *x)
+#else
+static int check_subtree (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+
+    if (!check_node (x)) {
+        return 0;
+    }
+    PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+        if (!check_subtree (z)) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_node (PQ_node *x)
+#else
+static int check_node (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+    int cnt;
+
+    cnt = 0;
+
+    if (x == &pseudo_root) {
+        return 1;
+    }
+    PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+        cnt++;
+        if (z->parenttype != x->type) {
+            printf ("Node %x has parenttype %d, parent %x has type %d\n",
+                    (unsigned int) z, z->parenttype, (unsigned int) x,
+                    x->type);
+            return 0;
+        }
+        if (x->type == P_NODE && z->parent != x) {
+            printf ("Node %x has parent %x, should be P-node %x\n",
+                    (unsigned int) z, (unsigned int) z->parent,
+                    (unsigned int) x);
+            return 0;
+        }
+        if (!((z->children_elem.ptr1 == zprev && z->children_elem.ptr2 != zprev) ||
+              (z->children_elem.ptr2 == zprev && z->children_elem.ptr1 != zprev))) {
+            printf ("Node %x has children ptr1 %x ptr2 %x, should be =, != %x\n",
+                    (unsigned int) z, (unsigned int) z->children_elem.ptr1,
+                    (unsigned int) z->children_elem.ptr2,
+                    (unsigned int) zprev);
+            return 0;
+        }
+    }
+    if (x->type == P_NODE && cnt != PQ_set_SIZE (x->children_set)) {
+        printf ("P-node %x has %d children, set size %d\n", (unsigned int) x,
+                cnt, PQ_set_SIZE (x->children_set));
+        return 0;
+    }
+    if (x->type == Q_NODE && PQ_set_LEFT_ELEM (x->children_set)->parent != x) {
+        printf ("Q_node %x left child %x has parent %x\n", (unsigned int) x,
+                (unsigned int) PQ_set_LEFT_ELEM (x->children_set),
+                (unsigned int) PQ_set_LEFT_ELEM (x->children_set)->parent);
+        return 0;
+    }
+    if (x->type == Q_NODE && PQ_set_RIGHT_ELEM (x->children_set)->parent != x) {
+        printf ("Q_node %x right child %x has parent %x\n", (unsigned int) x,
+                (unsigned int) PQ_set_RIGHT_ELEM (x->children_set),
+                (unsigned int) PQ_set_RIGHT_ELEM (x->children_set)->parent);
+        return 0;
+    }
+    if (x->type != LEAF_NODE && x->type != DIR_NODE && PQ_set_ISEMPTY (x->children_set)) {
+        printf ("node %x is type %d, but has no children\n", (unsigned int) x,
+                x->type);
+        return 0;
+    }
+    if (x->type == LEAF_NODE && !PQ_set_ISEMPTY (x->children_set)) {
+        printf ("leaf node %x has children\n", (unsigned int) x);
+        return 0;
+    }
+    if (x->type == DIR_NODE && !PQ_set_ISEMPTY (x->children_set)) {
+        printf ("dir node %x has children\n", (unsigned int) x);
+        return 0;
+    }
+    if (x->type == DIR_NODE && (x->children_elem.ptr1 == (PQ_node *) NULL ||
+                                x->children_elem.ptr2 == (PQ_node *) NULL)) {
+        printf ("dir node doesn't have 2 neighbors\n");
+        return 0;
+    }
+    if (x->type == P_NODE && cnt < 2) {
+        printf ("P-node %d only has %d children\n", x->number, cnt);
+        return 0;
+    }
+    if (x->type == Q_NODE && cnt < ((x->label == PARTIAL) ? 2 : 3)) {
+        printf ("Q-node %d only has %d children\n", x->number, cnt);
+        return 0;
+    }
+    return 1;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_node_pert (PQ_node *x)
+#else
+static int check_node_pert (x)
+PQ_node *x;
+#endif
+{
+    if (!check_node_pert_work (x)) {
+        dump_solution (x);
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+static int check_node_pert_work (PQ_node *x)
+#else
+static int check_node_pert_work (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *z, *zprev, *znext;
+    int cnt, full_cnt, partial_cnt, empty_cnt;
+
+    if (!check_node (x)) {
+        return 0;
+    }
+    if (x != &pseudo_root) {
+        empty_cnt = 0;
+        full_cnt = 0;
+        partial_cnt = 0;
+        PQ_set_FOREACH (x->children_set, z, children_elem, zprev, znext) {
+            if (IS_EMPTY (z))
+                empty_cnt++;
+            else if (z->label == PARTIAL)
+                partial_cnt++;
+            else if (z->label == FULL)
+                full_cnt++;
+            else {
+                printf ("Node %x has label %d\n", (unsigned int) z, z->label);
+                return 0;
+            }
+            if (!IS_EMPTY (z) && x != &pseudo_root && z->parent != x) {
+                printf ("Node %x has parent %x, should be %x\n",
+                        (unsigned int) z, (unsigned int) z->parent,
+                        (unsigned int) x);
+                return 0;
+            }
+        }
+
+        if (full_cnt != PQ_set_SIZE (x->full_children_set)) {
+            printf ("node %x has full children size %d, but has %d children full\n",
+                    (unsigned int) x, PQ_set_SIZE (x->full_children_set),
+                    full_cnt);
+            return 0;
+        }
+        if (partial_cnt != PQ_set_SIZE (x->partial_children_set)) {
+            printf ("node %x has partial children size %d, but has %d children partial\n",
+                    (unsigned int) x, PQ_set_SIZE (x->partial_children_set),
+                    partial_cnt);
+            return 0;
+        }
+    }
+    cnt = 0;
+    PQ_set_FOREACH (x->full_children_set, z, full_children_elem, zprev, znext) {
+        cnt++;
+        if (!((z->full_children_elem.ptr1 == zprev && z->full_children_elem.ptr2 != zprev) ||
+              (z->full_children_elem.ptr2 == zprev && z->full_children_elem.ptr1 != zprev) ||
+              (z->full_children_elem.ptr1 == zprev &&
+        z->full_children_elem.ptr2 == zprev && zprev == (PQ_node *) NULL))) {
+            printf ("Node %x has full_children ptr1 %x ptr2 %x, should be =, != %x\n",
+                    (unsigned int) z,
+                    (unsigned int) z->full_children_elem.ptr1,
+                    (unsigned int) z->full_children_elem.ptr2,
+                    (unsigned int) zprev);
+            return 0;
+        }
+        if (z->label != FULL) {
+            printf ("Node %x has label %d, but is in full set\n",
+                    (unsigned int) z, z->label);
+            return 0;
+        }
+    }
+    if (cnt != PQ_set_SIZE (x->full_children_set)) {
+        printf ("node %x has %d full children, set size %d\n",
+                (unsigned int) x, cnt, PQ_set_SIZE (x->full_children_set));
+        return 0;
+    }
+    cnt = 0;
+    PQ_set_FOREACH (x->partial_children_set, z, partial_children_elem, zprev, znext) {
+        cnt++;
+        if (!((z->partial_children_elem.ptr1 == zprev && z->partial_children_elem.ptr2 != zprev) ||
+              (z->partial_children_elem.ptr2 == zprev && z->partial_children_elem.ptr1 != zprev) ||
+              (z->partial_children_elem.ptr1 == zprev &&
+               z->partial_children_elem.ptr2 == zprev && zprev == (PQ_node *) NULL))) {
+            printf ("Node %x has partial_children ptr1 %x ptr2 %x, should be =, != %x\n",
+                    (unsigned int) z,
+                    (unsigned int) z->partial_children_elem.ptr1,
+                    (unsigned int) z->partial_children_elem.ptr2,
+                    (unsigned int) zprev);
+            return 0;
+        }
+        if (z->label != PARTIAL) {
+            printf ("Node %x has label %d, but is in partial set\n",
+                    (unsigned int) z, (unsigned int) z->label);
+            return 0;
+        }
+    }
+    if (cnt != PQ_set_SIZE (x->partial_children_set)) {
+        printf ("node %x has %d partial children, set size %d\n",
+                (unsigned int) x, cnt, PQ_set_SIZE (x->partial_children_set));
+        return 0;
+    }
+    return 1;
+}
+
+#endif /* NDEBUG */
+
+#ifdef CC_PROTOTYPE_ANSI
+PQ_node *XPQ_save_tree (PQ_node *x)
+#else
+PQ_node *XPQ_save_tree (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *rootcopy = PQ_save_work (XPQ_find_root (x));
+
+    rootcopy->parent = (PQ_node *) NULL;
+    rootcopy->parenttype = P_NODE;
+
+    return rootcopy;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_save_work (PQ_node *x)
+#else
+static PQ_node *PQ_save_work (x)
+PQ_node *x;
+#endif
+{
+    PQ_node *xcopy = PQ_node_alloc_work ();
+    PQ_node *y, *yprev, *ynext;
+    PQ_node *ycopy;
+
+    xcopy->type = x->type;
+    xcopy->number = x->number;
+    xcopy->next = x;
+    PQ_set_INIT (xcopy->children_set);
+
+    PQ_set_FOREACH (x->children_set, y, children_elem, yprev, ynext) {
+        ycopy = PQ_save_work (y);
+        ycopy->parent = xcopy;
+        ycopy->parenttype = xcopy->type;
+        PQ_set_ADD_LEFT (ycopy, xcopy->children_set, children_elem);
+    }
+    return xcopy;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+PQ_node *XPQ_restore_tree (PQ_node *x, int saveleaves)
+#else
+PQ_node *XPQ_restore_tree (x, saveleaves)
+PQ_node *x;
+int saveleaves;
+#endif
+{
+    PQ_node *rootcopy = PQ_restore_work (x, saveleaves);
+
+    rootcopy->parent = (PQ_node *) NULL;
+    rootcopy->parenttype = P_NODE;
+
+    return rootcopy;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static PQ_node *PQ_restore_work (PQ_node *x, int saveleaves)
+#else
+static PQ_node *PQ_restore_work (x, saveleaves)
+PQ_node *x;
+int saveleaves;
+#endif
+{
+    PQ_node *xcopy;
+    PQ_node *y, *yprev, *ynext;
+    PQ_node *ycopy;
+
+    if (saveleaves && (x->type == DIR_NODE || x->type == LEAF_NODE)) {
+        xcopy = x->next;
+    } else {
+        xcopy = PQ_node_alloc_work ();
+    }
+
+    xcopy->type = x->type;
+    xcopy->number = x->number;
+    PQ_set_INIT (xcopy->full_children_set);
+    PQ_set_INIT (xcopy->partial_children_set);
+    xcopy->label = 0;
+    xcopy->mark = 0;
+    xcopy->pertinent_child_count = 0;
+    xcopy->pertinent_leaf_count = 0;
+
+    PQ_set_INIT (xcopy->children_set);
+
+    PQ_set_FOREACH (x->children_set, y, children_elem, yprev, ynext) {
+        ycopy = PQ_restore_work (y, saveleaves);
+        ycopy->parent = xcopy;
+        ycopy->parenttype = xcopy->type;
+        PQ_set_ADD_LEFT (ycopy, xcopy->children_set, children_elem);
+    }
+    return xcopy;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void XPQ_save_tree_free (PQ_node *x)
+#else
+void XPQ_save_tree_free (x)
+PQ_node *x;
+#endif
+{
+    PQ_tree_free (x, 0);
+}
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xpqsets.h b/contrib/blossom/concorde97/XSTUFF/Xpqsets.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2874d22990ef82c273c4e690ddc5ce4316dbe96
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xpqsets.h
@@ -0,0 +1,278 @@
+#ifndef __XPQSETS_H
+#define __XPQSETS_H
+
+typedef struct PQ_set {
+    int size;
+    struct PQ_node *left;
+    struct PQ_node *right;
+} PQ_set;
+
+typedef struct PQ_elem {
+    struct PQ_node *ptr1;
+    struct PQ_node *ptr2;
+} PQ_elem;
+
+/* Summary of the macros:
+   PQ_set_INIT(PQ_set s) initializes s to the empty set
+
+   PQ_set_ISEMPTY(PQ_set s) is an expression which tests if s is empty
+
+   PQ_set_SIZE(PQ_set s) is the size of s
+
+   PQ_set_PTR_TO(PQ_elem e, PQ_node *q) is the field of e which points to q
+
+   PQ_set_PTR_REPLACE(PQ_elem e, PQ_node *q, PQ_node *r) replaces q with r
+   in e
+
+   PQ_set_PTR_AWAY(PQ_elem e, PQ_node *q) is the field of e which doesn't
+   point to q
+
+   PQ_set_ADD_WORK(PQ_node *x, PQ_set s, ELEM_FIELD efield, DIRECTION dir)
+   adds x to s at the dir end, using the efield field to link things
+   together. It is intended to be an internal macro used by PQ_set_ADD_LEFT
+   and PQ_set_ADD_RIGHT.
+
+   PQ_set_ADD_LEFT(PQ_node *x, PQ_set s, ELEM_FIELD efield) adds x to s at
+   the left end.
+
+   PQ_set_ADD_RIGHT(PQ_node *x, PQ_set s, ELEM_FIELD efield) adds x to s at
+   the right end.
+
+   PQ_set_ADD(PQ_node *x, PQ_set s, ELEM_FIELD efield) adds x to s
+
+   PQ_set_DELETE(PQ_node *x, PQ_set s, ELEM_FIELD efield) deletes x from s
+
+   PQ_set_DELETE2(PQ_node *x, SET_FIELD sfield, ELEM_FIELD efield) deletes
+   x from the sfield set of its parent.  If x is an endmost child in this
+   set, then DELETE2 uses the parent pointer to find the set field.
+   Otherwise, the parent pointer is not used.
+
+   PQ_set_LEFT_ELEM(PQ_set s) is the left element of s, or NULL if s is
+   empty
+
+   PQ_set_RIGHT_ELEM(PQ_set s) is the right element of s, or NULL if s is
+   empty
+
+   PQ_set_FOREACH(PQ_set s, PQ_node *x, ELEM_FIELD efield, PQ_node *xprev,
+                  PQ_node *xnext) iterates x over elements of s using
+   temporary variables xprev and xnext.
+
+   PQ_set_FOREACH_FROM(PQ_node *x, ELEM_FIELD efield, PQ_node *xprev,
+                       PQ_node *xnext) iterates x over elements of s starting
+   at x and going away from xprev.  xnext is a temporary variable used in
+   the loop, which also changes xprev and x
+
+   PQ_set_FOREACH_DEL(PQ_set s, PQ_node *x, ELEM_FIELD efield,
+                      PQ_node *xprev, PQ_node *xnext) iterates x over
+   elements of s using temporary variables xprev and xnext.  x may be deleted
+   from the set in the body of the loop (but delete any other element from s
+   at your own risk).
+
+   PQ_set_FOREACH_ADJ(PQ_node *x, ELEM_FIELD efield, PQ_node *z, int itemp)
+   iterates z over the immediate neighbors of x using itemp as a temporary
+   variable. It is just used to save code replication when you want to do
+   something for each of the two neighbors.
+
+*/
+
+
+/* PQ_set_INIT(PQ_set s) initializes s to the empty set */
+
+#define PQ_set_INIT(s) {                                                \
+    (s).size = 0;                                                       \
+    (s).left = (PQ_node *) NULL;                                        \
+    (s).right = (PQ_node *) NULL;                                       \
+}
+
+/* In the comments below, something of type ELEM_FIELD is the name of a field
+   in a PQ_node of type PQ_elem, and something of type DIRECTION is either
+   left or right. */
+
+/* PQ_set_ISEMPTY(PQ_set s) is an expression which tests if s is empty */
+
+#define PQ_set_ISEMPTY(s)       ((s).left == (PQ_node *) NULL)
+
+/* PQ_set_SIZE(PQ_set s) is the size of s */
+
+#define PQ_set_SIZE(s)  ((s).size)
+
+/* PQ_set_PTR_TO(PQ_elem e, PQ_node *q) is the field of e which points to q */
+
+#define PQ_set_PTR_TO(e,q)      (((e).ptr1 == (q)) ? ((e).ptr1) : ((e).ptr2))
+
+/* PQ_set_PTR_REPLACE(PQ_elem e, PQ_node *q, PQ_node *r) replaces q with r
+   in e */
+
+#define PQ_set_PTR_REPLACE(e,q,r) {                                     \
+        if ((e).ptr1 == (q)) {                                          \
+                (e).ptr1 = (r);                                         \
+        } else {                                                        \
+                (e).ptr2 = (r);                                         \
+        }                                                               \
+}
+
+/* PQ_set_PTR_AWAY(pq_elem e, PQ_node *q) is the field of e which doesn't
+   point to q */
+
+#define PQ_set_PTR_AWAY(e,q)    (((e).ptr1 == (q)) ? ((e).ptr2) : ((e).ptr1))
+
+/* PQ_set_ADD_WORK(PQ_node *x, PQ_set s, ELEM_FIELD efield, DIRECTION dir)
+   adds x to s at the dir end, using the efield field to link things
+   together. It is intended to be an internal macro used by PQ_set_ADD_LEFT
+   and PQ_set_ADD_RIGHT. */
+
+#define PQ_set_ADD_WORK(x,s,efield,dir) {                               \
+    (x)->efield.ptr1 = (s).dir;                                         \
+    (x)->efield.ptr2 = (PQ_node *) NULL;                                \
+    if ((s).dir) {                                                      \
+        PQ_set_PTR_REPLACE((s).dir->efield,(PQ_node *) NULL, (x));              \
+        (s).dir = (x);                                                  \
+    } else {                                                            \
+        (s).left = (s).right = (x);                                     \
+    }                                                                   \
+    (s).size++;                                                         \
+}
+
+/* PQ_set_ADD_LEFT(PQ_node *x, PQ_set s, ELEM_FIELD efield) adds x to s at
+   the left end. */
+
+#define PQ_set_ADD_LEFT(x,s,efield) PQ_set_ADD_WORK(x,s,efield,left)
+
+/* PQ_set_ADD_RIGHT(PQ_node *x, PQ_set s, ELEM_FIELD efield) adds x to s at
+   the right end. */
+
+#define PQ_set_ADD_RIGHT(x,s,efield) PQ_set_ADD_WORK(x,s,efield,right)
+
+/* PQ_set_ADD(PQ_node *x, PQ_set s, ELEM_FIELD efield) adds x to s */
+
+#define PQ_set_ADD(x,s,efield) PQ_set_ADD_LEFT(x,s,efield)
+
+/* PQ_set_DELETE(PQ_node *x, PQ_set s, ELEM_FIELD efield) deletes x from s */
+
+#define PQ_set_DELETE(x,s,efield) {                                     \
+    if (PQ_set_ISEMPTY(s)) {                                            \
+        fprintf (stderr, "Error - attempt to delete from empty set\n"); \
+    }                                                                   \
+    if ((x)->efield.ptr1) {                                             \
+        PQ_set_PTR_REPLACE((x)->efield.ptr1->efield,(x),(x)->efield.ptr2); \
+    } else {                                                            \
+        if ((s).left == (x)) {                                          \
+                (s).left = (x)->efield.ptr2;                            \
+        } else {                                                        \
+                (s).right = (x)->efield.ptr2;                           \
+        }                                                               \
+    }                                                                   \
+    if ((x)->efield.ptr2) {                                             \
+        PQ_set_PTR_REPLACE((x)->efield.ptr2->efield,(x),(x)->efield.ptr1);\
+    } else {                                                            \
+        if ((s).right == (x)) {                                         \
+                (s).right = (x)->efield.ptr1;                           \
+        } else {                                                        \
+                (s).left = (x)->efield.ptr1;                            \
+        }                                                               \
+    }                                                                   \
+    (s).size--;                                                         \
+}
+
+/* PQ_set_DELETE2(PQ_node *x, SET_FIELD sfield, ELEM_FIELD efield) deletes
+   x from the sfield set of its parent.  If x is an endmost child in this
+   set, then DELETE2 uses the parent pointer to find the set field.
+   Otherwise, the parent pointer is not used.  If the parent pointer is
+   NULL, then the parent update is ignored. */
+
+#define PQ_set_DELETE2(x,sfield,efield) {                               \
+    if ((x)->efield.ptr1) {                                             \
+        PQ_set_PTR_REPLACE((x)->efield.ptr1->efield,(x),(x)->efield.ptr2); \
+    } else if ((x)->parent) {                                           \
+        if ((x)->parent->sfield.left == (x)) {                          \
+                (x)->parent->sfield.left = (x)->efield.ptr2;            \
+        } else {                                                        \
+                (x)->parent->sfield.right = (x)->efield.ptr2;           \
+        }                                                               \
+    }                                                                   \
+    if ((x)->efield.ptr2) {                                             \
+        PQ_set_PTR_REPLACE((x)->efield.ptr2->efield,(x),(x)->efield.ptr1);\
+    } else if ((x)->parent) {                                           \
+        if ((x)->parent->sfield.right == (x)) {                         \
+                (x)->parent->sfield.right = (x)->efield.ptr1;           \
+        } else {                                                        \
+                (x)->parent->sfield.left = (x)->efield.ptr1;            \
+        }                                                               \
+    }                                                                   \
+    if ((x)->parent) {                                                  \
+        (x)->parent->sfield.size--;                                     \
+    }                                                                   \
+}
+
+/* PQ_set_LEFT_ELEM(PQ_set s) is the left element of s, or NULL if s is
+   empty */
+
+#define PQ_set_LEFT_ELEM(s) ((s).left)
+
+/* PQ_set_RIGHT_ELEM(PQ_set s) is the right element of s, or NULL if s is
+   empty */
+
+#define PQ_set_RIGHT_ELEM(s) ((s).right)
+
+/* PQ_set_FOREACH(PQ_set s, PQ_node *x, ELEM_FIELD efield, PQ_node *xprev,
+                  PQ_node *xnext) iterates x over elements of s using
+   temporary variables xprev and xnext. */
+
+#define PQ_set_FOREACH(s,x,efield,xprev,xnext)                          \
+        for ((xprev) = (PQ_node *) NULL,                                \
+             (x) = (s).left;                                            \
+            (x);                                                        \
+             (xnext) = PQ_set_PTR_AWAY((x)->efield,xprev),              \
+             (xprev) = (x),                                             \
+             (x) = (xnext)                                              \
+)
+
+/* PQ_set_FOREACH_FROM(PQ_node *x, ELEM_FIELD efield, PQ_node *xprev,
+                       PQ_node *xnext) iterates x over elements of s starting
+   at x and going away from xprev.  xnext is a temporary variable used in
+   the loop, which also changes xprev and x */
+
+#define PQ_set_FOREACH_FROM(x,efield,xprev,xnext)                       \
+        for (;                                                          \
+            (x);                                                        \
+             (xnext) = PQ_set_PTR_AWAY((x)->efield,xprev),              \
+             (xprev) = (x),                                             \
+             (x) = (xnext)                                              \
+)
+
+/* PQ_set_FOREACH_DEL(PQ_set s, PQ_node *x, ELEM_FIELD efield,
+                      PQ_node *xprev, PQ_node *xnext) iterates x over
+   elements of s using temporary variables xprev and xnext.  x may be deleted
+   from the set in the body of the loop (but delete any other element from s
+   at your own risk). */
+
+#define PQ_set_FOREACH_DEL(s,x,efield,xprev,xnext)                      \
+        for ((xprev) = (PQ_node *) NULL,                                \
+             (x) = (s).left,                                            \
+             (xnext) = ((x) ? PQ_set_PTR_AWAY((x)->efield,(PQ_node *) NULL) \
+                            : (PQ_node *) NULL);                        \
+            (x);                                                        \
+             (xprev) = (((xprev) ? (((xprev)->efield.ptr1 == (x))       \
+                                 || ((xprev)->efield.ptr2 == (x)))      \
+                                 : ((s).left == (x)))                   \
+                        ? (x) : (xprev)),                               \
+             (x) = (xnext),                                             \
+             (xnext) = ((x) ? PQ_set_PTR_AWAY((x)->efield, xprev)       \
+                            : (PQ_node *) NULL) \
+)
+
+/* PQ_set_FOREACH_ADJ(PQ_node *x, ELEM_FIELD efield, PQ_node *z, int itemp)
+   iterates z over the immediate neighbors of x using itemp as a temporary
+   variable. It is just used to save code replication when you want to do
+   something for each of the two neighbors. */
+
+#define PQ_set_FOREACH_ADJ(x,efield,z,itemp)                            \
+        for (z = x->efield.ptr1, itemp = 0;                             \
+             itemp < 2;                                                 \
+             z = x->efield.ptr2, itemp++)
+
+#ifndef SWAP
+#define SWAP(x, y, t) (((t) = (x)),((x) = (y)),((y) = (t)))
+#endif
+
+#endif  /* __XPQSETS_H */
diff --git a/contrib/blossom/concorde97/XSTUFF/Xshrink.c b/contrib/blossom/concorde97/XSTUFF/Xshrink.c
new file mode 100644
index 0000000000000000000000000000000000000000..7af67b61ea4929221c84ab64f9b0423715b11ce3
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xshrink.c
@@ -0,0 +1,482 @@
+/**************************************************************************/
+/*                                                                        */
+/* EXPORTED FUNCTIONS:                                                    */
+/*                                                                        */
+/*    int shrinkprocess ();                                               */
+/*    void buildpseudonodelist ();                                        */
+/*    void buildpseudonodenumbers ();                                     */
+/*    void destroypseudonodelist ();                                      */
+/*    void dumppseudograph ();                                            */
+/*    void dumppseudograph_edgelist ()                                    */
+/*    void simpleshrink ();                                               */
+/*    void rebuildcadj ();                                                */
+/*                                                                        */
+/**************************************************************************/
+
+#include "machdefs.h"
+#include "Xsubtour.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static void
+    markedge (Xgraph *G, Xedge *e),
+    marknode (Xnode *n, int v),
+    deletepseudonode (Xgraph *G, Xnode *),
+    destroynode (Xnode *),
+    mergebase (Xnode *, Xnode *),
+    rebuildnodecadj (Xnode *);
+
+static int
+    mergeadj (Xgraph *G, Xcplane **, Xnode *, Xnode *, Xnode **, int);
+
+#else
+
+static void
+    markedge (),
+    marknode (),
+    deletepseudonode (),
+    destroynode (),
+    mergebase (),
+    rebuildnodecadj ();
+
+static int
+    mergeadj ();
+
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xbuildpseudonodelist (Xgraph *G, int all)
+#else
+void Xbuildpseudonodelist (G, all)
+Xgraph *G;
+int all;
+#endif
+{
+    int i;
+    Xnode *n;
+    Xedge *e;
+    Xedgeptr *e1;
+    static Xnode pseudodummy;
+
+    G->pseudonodelist = &pseudodummy;
+    pseudodummy.prev = (Xnode *) NULL;
+    pseudodummy.next = G->nodelist;
+    for (i = 0, n = G->nodelist; i < G->nnodes; i++, n++) {
+        n->base.head = Xnodeptralloc ();
+        n->base.tail = n->base.head;
+        n->base.head->next = (Xnodeptr *) NULL;
+        n->base.head->this = n;
+        n->cadj.head = n->cadj.tail = (Xedgeptr *) NULL;
+        n->prev = n - 1;
+        n->next = n + 1;
+    }
+    G->nodelist->prev = G->pseudonodelist;
+    G->nodelist[G->nnodes - 1].next = (Xnode *) NULL;
+
+    for (i = G->nedges, e = G->edgelist; i; i--, e++)
+        if (all || e->x > 0.00001) {    /* 0.0 */
+            e->stay = 1;
+            e->cends[0] = e->ends[0];
+            e->cends[1] = e->ends[1];
+            e1 = Xedgeptralloc ();
+            e1->next = (e->cends[0])->cadj.head;
+            e1->this = e;
+            (e->cends[0])->cadj.head = e1;
+            if ((e->cends[0])->cadj.tail == (Xedgeptr *) NULL)
+                (e->cends[0])->cadj.tail = e1;
+            e1 = Xedgeptralloc ();
+            e1->next = (e->cends[1])->cadj.head;
+            e1->this = e;
+            (e->cends[1])->cadj.head = e1;
+            if ((e->cends[1])->cadj.tail == (Xedgeptr *) NULL)
+                (e->cends[1])->cadj.tail = e1;
+        } else
+            e->stay = 0;
+    G->npseudonodes = G->nnodes;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xbuildpseudonodenumbers (Xgraph *G)
+#else
+void Xbuildpseudonodenumbers (G)
+Xgraph *G;
+#endif
+{
+    int i = 0;
+    Xnode *n;
+
+    for (n = G->pseudonodelist->next; n; n = n->next, i++)
+        n->pseudonumber = i;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xdumppseudograph (Xgraph *G)
+#else
+void Xdumppseudograph (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n;
+    Xedge *e;
+    Xedgeptr *ep;
+    int i;
+
+    printf ("PSEUDOGRAPH:\n");
+    printf ("nnodes = %d  nodes: ", G->npseudonodes);
+    for (i = 0, n = G->pseudonodelist->next; n; n = n->next, i++) {
+        printf (" %d", (int) (n - G->nodelist));
+        if (i % 10 == 9)
+            printf ("\n");
+    }
+    if (i % 10)
+        printf ("\n");
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        printf ("node %d: ", (int) (n - G->nodelist));
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->stay)
+                printf (" (%d, %d, %.2f)",
+                        (int) (e->cends[0] - G->nodelist),
+                        (int) (e->cends[1] - G->nodelist),
+                        e->x);
+        }
+/*
+        printf ("  base: ");
+        for (np = n->base.head; np; np = np->next)
+            printf ("%d ", (int) (np->this - G->nodelist));
+*/
+        printf ("\n");
+    }
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xdumppseudograph_edgelist (Xgraph *G)
+#else
+void Xdumppseudograph_edgelist (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n;
+    Xedge *e;
+    Xedgeptr *ep;
+    int count;
+
+    printf ("PSEUDOGRAPH EDGELIST:\n");
+    Xbuildpseudonodenumbers (G);
+    for (count = 0, n = G->pseudonodelist->next; n; n = n->next)
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->stay)
+                count++;
+        }
+    printf ("%d %d\n", G->npseudonodes, count / 2);
+    G->magicedgenum++;
+    for (n = G->pseudonodelist->next; n; n = n->next)
+        for (ep = n->cadj.head; ep; ep = ep->next) {
+            e = ep->this;
+            if (e->stay && e->magiclabel != G->magicedgenum) {
+                e->magiclabel = G->magicedgenum;
+                printf ("%d %d %f\n",
+                        e->cends[0]->pseudonumber,
+                        e->cends[1]->pseudonumber,
+                        e->x);
+            }
+        }
+
+    fflush (stdout);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xdestroypseudonodelist (Xgraph *G)
+#else
+void Xdestroypseudonodelist (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n;
+
+    for (n = G->pseudonodelist->next; n; n = n->next) {
+        destroynode (n);
+    }
+    G->npseudonodes = 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void destroynode (Xnode *n)
+#else
+static void destroynode (n)
+Xnode *n;
+#endif
+{
+    Xedgeptr *e, *enext;
+    Xnodeptr *np, *npnext;
+
+
+    for (e = n->cadj.head; e; e = enext) {
+        enext = e->next;
+        Xedgeptrfree (e);
+    }
+    for (np = n->base.head; np; np = npnext) {
+        npnext = np->next;
+        Xnodeptrfree (np);
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xshrinkprocess (Xgraph *G, Xcplane **list)
+#else
+int Xshrinkprocess (G, list)
+Xgraph *G;
+Xcplane **list;
+#endif
+{
+    Xnode *stack, headstack, *n1, *n2;
+    int i, returnval = 0;
+    Xedge *e;
+
+    stack = &headstack;
+    stack->snext = (Xnode *) NULL;
+
+    for (i = G->nedges, e = G->edgelist; i; e++, i--) {
+        if (G->npseudonodes <= 3)
+            return returnval;
+        if (!e->stay)
+            continue;
+        if (e->x < 1.0 - XEPSILON)
+            continue;
+        if (e->x > 1.0 + XEPSILON) {
+            markedge (G, e);
+            returnval += Xloadcplane_cut (G, list, G->magicnum);
+        }
+        n1 = e->cends[0];
+        e->cends[1]->snext = stack;
+        stack = e->cends[1];
+        n1->stacklabel = ++(G->stacknum);
+        do {
+            if (G->npseudonodes <= 3)
+                return returnval;
+            n2 = stack;
+            stack = stack->snext;
+
+            mergebase (n1, n2);
+            returnval += mergeadj (G, list, n1, n2, &stack, 1);
+            deletepseudonode (G, n2);
+        } while (stack != &headstack);
+    }
+    return returnval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xsimpleshrink (Xgraph *G, Xnode *n1, Xnode *n2)
+#else
+void Xsimpleshrink (G, n1, n2)
+Xgraph *G;
+Xnode *n1, *n2;
+#endif
+{
+    Xnode dummystack, *stack, *n3;
+    Xedgeptr *e;
+
+    stack = &dummystack;
+    mergebase (n1, n2);
+    mergeadj (G, (Xcplane **) NULL, n1, n2, &stack, 0);
+          /* since repeat = 0, dont load */
+    deletepseudonode (G, n2);
+    for (e = n1->cadj.head; e; e = e->next)
+        if (e->this->stay) {
+            n3 = OTHERCURRENTEND (e->this, n1);
+            rebuildnodecadj (n3);
+        }
+    rebuildnodecadj (n1);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void markedge (Xgraph *G, Xedge *e)
+#else
+static void markedge (G, e)
+Xgraph *G;
+Xedge *e;
+#endif
+{
+    G->magicnum++;
+    marknode (e->cends[0], G->magicnum);
+    marknode (e->cends[1], G->magicnum);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void marknode (Xnode *n, int v)
+#else
+static void marknode (n, v)
+Xnode *n;
+int v;
+#endif
+{
+    Xnodeptr *np;
+
+    n->magiclabel = v;
+    for (np = n->base.head; np; np = np->next) {
+        np->this->magiclabel = v;
+    }
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void mergebase (Xnode *n1, Xnode *n2)
+#else
+static void mergebase (n1, n2)
+Xnode *n1, *n2;
+#endif
+{
+    n1->base.tail->next = n2->base.head;
+    n1->base.tail = n2->base.tail;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int mergeadj (Xgraph *G, Xcplane **list, Xnode *n1, Xnode *n2,
+                     Xnode **pstack, int repeat)
+#else
+static int mergeadj (G, list, n1, n2, pstack, repeat)
+Xgraph *G;
+Xcplane **list;
+Xnode *n1, *n2, **pstack;
+int repeat;
+#endif
+{
+    Xedgeptr *e, *memo;
+    Xnode *stack, *n3;
+    int returnval = 0;
+
+    stack = *pstack;
+
+    for (e = n2->cadj.head; e != (Xedgeptr *) NULL; e = e->next) {
+        if (!e->this->stay)
+            continue;
+        if (OTHERCURRENTEND (e->this, n2) == n1)
+            e->this->stay = 0;
+        else
+            (OTHERCURRENTEND (e->this, n2))->pe = (Xedge *) NULL;
+    }
+
+    for (e = n1->cadj.head; e != (Xedgeptr *) NULL; e = e->next)
+        if (e->this->stay)
+            (OTHERCURRENTEND (e->this, n1))->pe = e->this;
+
+    for (e = n2->cadj.head; e != (Xedgeptr *) NULL;) {
+        if (!e->this->stay) {
+            memo = e;
+            e = e->next;
+            Xedgeptrfree (memo);
+        } else if ((n3 = (OTHERCURRENTEND (e->this, n2)))->pe
+                      != (Xedge *) NULL) {
+            n3->pe->x += e->this->x;
+            n3->pe->rc += e->this->rc;
+            e->this->stay = 0;
+            memo = e;
+            e = e->next;
+            Xedgeptrfree (memo);
+            if (n3->pe->x > 1.0 + XEPSILON && repeat) {
+                markedge (G, n3->pe);
+                returnval += Xloadcplane_cut (G, list, G->magicnum);
+                if (n3->stacklabel != G->stacknum) {
+                    n3->snext = stack;
+                    stack = n3;
+                    n3->stacklabel = G->stacknum;
+                }
+            }
+            if (n3->pe->x > 1.0 - XEPSILON &&
+                n3->stacklabel != G->stacknum && repeat) {
+                n3->snext = stack;
+                stack = n3;
+            }
+        } else {
+            n1->cadj.tail->next = e;
+            n1->cadj.tail = e;
+            if (e->this->cends[0] == n2)
+                e->this->cends[0] = n1;
+            else
+                e->this->cends[1] = n1;
+            e = e->next;
+        }
+    }
+    n1->cadj.tail->next = (Xedgeptr *) NULL;
+    return returnval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void deletepseudonode (Xgraph *G, Xnode *n2)
+#else
+static void deletepseudonode (G, n2)
+Xgraph *G;
+Xnode *n2;
+#endif
+{
+    n2->prev->next = n2->next;
+    if (n2->next != (Xnode *) NULL)
+        n2->next->prev = n2->prev;
+    G->npseudonodes--;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+void Xrebuildcadj (Xgraph *G)
+#else
+void Xrebuildcadj (G)
+Xgraph *G;
+#endif
+{
+    Xnode *n;
+
+    for (n = G->pseudonodelist->next; n; n = n->next)
+        rebuildnodecadj (n);
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void rebuildnodecadj (Xnode *n)
+#else
+static void rebuildnodecadj (n)
+Xnode *n;
+#endif
+{
+    Xedgeptr *e, *olde, *memo;
+
+    olde = n->cadj.head;
+    while (olde && !olde->this->stay) {
+        memo = olde;
+        olde = olde->next;
+        Xedgeptrfree (memo);
+    }
+    n->cadj.head = olde;
+    if (!olde)
+        return;
+
+    e = olde->next;
+    while (e) {
+        if (!e->this->stay) {
+            olde->next = e->next;
+            memo = e;
+            e = e->next;
+            Xedgeptrfree (memo);
+        } else {
+            olde = e;
+            e = e->next;
+        }
+    }
+    n->cadj.tail = olde;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xheavy_edge_cuts (Xgraph *G, Xcplane **list, double *x)
+#else
+int Xheavy_edge_cuts (G, list, x)
+Xgraph *G;
+Xcplane **list;
+double *x;
+#endif
+{
+    int cnt;
+
+    Xloadx (G, x);
+    Xbuildpseudonodelist (G, 0);
+    cnt = Xshrinkprocess (G, list);
+    Xdestroypseudonodelist (G);
+    return cnt;
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xstuff.c b/contrib/blossom/concorde97/XSTUFF/Xstuff.c
new file mode 100644
index 0000000000000000000000000000000000000000..8a1924ffe7c22ae827f06e9588c1231aece088f7
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xstuff.c
@@ -0,0 +1,892 @@
+/***************************************************************************/
+/*                                                                         */
+/*           Interface to a subset of the old subtour routines             */
+/*                                                                         */
+/*                                                                         */
+/*   WARNING: These routines are messy ports of old cut, they use many     */
+/*   static variables, may not clean up their memory, and are known to     */
+/*   have bugs. These routines will not be included in future versions     */
+/*   of concorde.                                                          */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: Novemeber 6, 1995                                                */
+/*                                                                         */
+/*  Exported Functions:                                                    */
+/*                                                                         */
+/*    int                                                                  */
+/*       Xfastcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,      */
+/*                  int ecount, int *elist, double *x),                    */
+/*       Xslowcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,      */
+/*                  int ecount, int *elist, double *x),                    */
+/*       Xfastsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,  */
+/*                  int ecount, int *elist, double *x),                    */
+/*       Xexactsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, */
+/*                  int ecount, int *elist, double *x),                    */
+/*       Xcliquetrees (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,   */
+/*                  int ecount, int *elist, double *x),                    */
+/*       Xconsecutiveones (CCtsp_lpcut_in **cuts, int *cutcount,           */
+/*                  int ncount, int ecount, int *elist, double *x,         */
+/*                  CCtsp_lpcuts *pool)                                    */
+/*       Xnecklacecuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,  */
+/*                   int ecount, int *elist, double *x, CCtsp_lpcuts *pool)*/
+/*         -cuts should point to a NULL terminated cutlist. The new cuts   */
+/*          will be added to the front of this list.                       */
+/*         -cutcount will return the number of new cuts found.             */
+/*                                                                         */
+/*  Link with:                                                             */
+/*    SEE conmake.grs                                                      */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+#include "Xsubtour.h"
+#include "Xstuff.h"
+
+#ifdef CC_PROTOTYPE_ANSI
+
+static int
+    munch_the_list (CCtsp_lpcut_in **cuts, int *cutcount, Xgraph *G,
+        Xcplane *list),
+    send_the_cut (CCtsp_lpcut_in **cuts, Xgraph *G, Xcplane *c),
+    cplane_to_lpcut_in (Xgraph *G, Xcplane *c, CCtsp_lpcut_in *lc),
+    nodeptr_to_lpclique (Xgraph *G, Xnodeptr *npclique, CCtsp_lpclique *cliq);
+
+#else
+
+static int
+    munch_the_list (),
+    send_the_cut (),
+    cplane_to_lpcut_in (),
+    nodeptr_to_lpclique ();
+
+#endif
+
+static CCtsp_lpcuts *xpool = (CCtsp_lpcuts *) NULL;
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xfastcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x)
+#else
+int Xfastcuts (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    double tzeit;
+    Xcplane *list = (Xcplane *) NULL;
+    int i, cnt;
+    int *elen = (int *) NULL;
+    Xgraph G;
+    int rval = 0;
+
+    *cutcount = 0;
+
+    G.nodelist = (Xnode *) NULL;
+    G.edgelist = (Xedge *) NULL;
+
+    elen = CC_SAFE_MALLOC (ecount, int);
+    if (!elen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < ecount; i++)
+        elen[i] = 0;
+
+    if (Xbuildgraph (&G, ncount, ecount, elist, elen)) {
+        fprintf (stderr, "Xbuildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Xfastcuts:\n"); fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xrunconnectcuts (&G, &list, x);
+    printf ("  %d connect cuts  in %.2f seconds\n", cnt,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xheavy_edge_cuts (&G, &list, x);
+    printf ("  %d heavy-edge cuts in %.2f seconds\n", cnt,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xblobcuts (&G, &list, x);
+    printf ("  %d blob cuts in %.2f seconds\n", cnt, CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xblockcombs (&G, &list, x);
+    printf ("  %d block combs in %.2f seconds\n", cnt, CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xlocalcombs (&G, &list, x);
+    printf ("  %d local combs in %.2f seconds\n", cnt, CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xglobalcombs (&G, &list, x);
+    printf ("  %d global combs in %.2f seconds\n", cnt,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    {
+        Xcplane *c, *cnext;
+        int ksub = 0, kcomb = 0, kctree = 0, k = 0;
+
+        for (c = list; c; c = c->next) {
+            k++;
+            if (c->handle) {
+                if (!c->teeth)
+                    ksub++;
+                else
+                    kcomb++;
+            } else {
+                if (!c->teeth)
+                    ksub++;
+                else {
+                    if (!c->handles->next)
+                        kcomb++;
+                    else
+                        kctree++;
+                }
+            }
+        }
+
+        printf ("\n%d CUTS (%d subtours, %d combs, %d cliquetrees)\n",
+                 k, ksub, kcomb, kctree);
+        for (c = list; c; c = cnext) {
+            cnext = c->next;
+            if (send_the_cut (cuts, &G, c)) {
+                fprintf (stderr, "send_the_cut failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            Xfreecplanestruct (c);
+            (*cutcount)++;
+        }
+    }
+
+
+    printf ("Total Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    Xfreegraph (&G);
+    CC_IFFREE (elen, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xslowcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+       int *elist, double *x)
+#else
+int Xslowcuts (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+#endif
+{
+    double szeit = CCutil_zeit ();
+    double tzeit;
+    Xcplane *list = (Xcplane *) NULL;
+    int i, cnt;
+    int *elen = (int *) NULL;
+    Xgraph G;
+    int rval = 0;
+
+    *cutcount = 0;
+
+    G.nodelist = (Xnode *) NULL;
+    G.edgelist = (Xedge *) NULL;
+
+    elen = CC_SAFE_MALLOC (ecount, int);
+    if (!elen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    for (i = 0; i < ecount; i++)
+        elen[i] = 0;
+
+    if (Xbuildgraph (&G, ncount, ecount, elist, elen)) {
+        fprintf (stderr, "Xbuildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Xslowcuts:\n"); fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xexactblossoms_run (&G, &list, x);
+    printf ("  %d exact blossoms in %.2f seconds\n", cnt,
+          CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xolaf_combs (&G, &list, x);
+    printf ("  %d olaf combs in %.2f seconds\n", cnt, CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    {
+        Xcplane *c, *cnext;
+        int ksub = 0, kcomb = 0, kctree = 0, k = 0;
+
+        for (c = list; c; c = c->next) {
+            k++;
+            if (c->handle) {
+                if (!c->teeth)
+                    ksub++;
+                else
+                    kcomb++;
+            } else {
+                if (!c->teeth)
+                    ksub++;
+                else {
+                    if (!c->handles->next)
+                        kcomb++;
+                    else
+                        kctree++;
+                }
+            }
+        }
+
+        printf ("\n%d CUTS (%d subtours, %d combs, %d cliquetrees)\n",
+                 k, ksub, kcomb, kctree);
+        for (c = list; c; c = cnext) {
+            cnext = c->next;
+            if (send_the_cut (cuts, &G, c)) {
+                fprintf (stderr, "send_the_cut failed\n");
+                rval = 1;
+                goto CLEANUP;
+            }
+            Xfreecplanestruct (c);
+            (*cutcount)++;
+        }
+    }
+
+    printf ("Total Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    Xfreegraph (&G);
+    CC_IFFREE (elen, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xfastsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+        int ecount, int *elist, double *x)
+#else
+int Xfastsubtours (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+#endif
+{
+    double tzeit;
+    Xcplane *list = (Xcplane *) NULL;
+    int i, cnt, rval = 0;
+    int *elen = (int *) NULL;
+    Xgraph G;
+
+    *cutcount = 0;
+
+    G.nodelist = (Xnode *) NULL;
+    G.edgelist = (Xedge *) NULL;
+
+    elen = CC_SAFE_MALLOC (ecount, int);
+    if (!elen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++)
+        elen[i] = 0;
+
+    if (Xbuildgraph (&G, ncount, ecount, elist, elen)) {
+        fprintf (stderr, "Xbuildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Xfastsubtours:\n"); fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xrunconnectcuts (&G, &list, x);
+    printf ("  %d connect cuts  in %.2f seconds\n", cnt,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xheavy_edge_cuts (&G, &list, x);
+    printf ("  %d heavy-edge cuts in %.2f seconds\n", cnt,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    cnt = Xblobcuts (&G, &list, x);
+    printf ("  %d blob cuts in %.2f seconds\n", cnt,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+
+    if (munch_the_list (cuts, cutcount, &G, list)) {
+        fprintf (stderr, "munch_the_list failed\n");
+        return 1;
+    }
+
+CLEANUP:
+
+    Xfreegraph (&G);
+    CC_IFFREE (elen, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xexactsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+        int ecount, int *elist, double *x)
+#else
+int Xexactsubtours (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+#endif
+{
+    double tzeit;
+    Xcplane *list = (Xcplane *) NULL;
+    int i, rval = 0;
+    int *elen = (int *) NULL;
+    Xgraph G;
+
+    *cutcount = 0;
+
+    G.nodelist = (Xnode *) NULL;
+    G.edgelist = (Xedge *) NULL;
+
+    elen = CC_SAFE_MALLOC (ecount, int);
+    if (!elen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++)
+        elen[i] = 0;
+
+    if (Xbuildgraph (&G, ncount, ecount, elist, elen)) {
+        fprintf (stderr, "Xbuildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Xexactcutcheck:\n"); fflush (stdout);
+    tzeit = CCutil_zeit ();
+    i = Xexactcutcheck (&G, &list, x);
+    printf ("  %d exact cuts in %.2f seconds\n", i, CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    if (munch_the_list (cuts, cutcount, &G, list)) {
+        fprintf (stderr, "munch_the_list failed\n");
+        return 1;
+    }
+
+CLEANUP:
+
+    Xfreegraph (&G);
+    CC_IFFREE (elen, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xconsecutiveones (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+        int ecount, int *elist, double *x, CCtsp_lpcuts *pool)
+#else
+int Xconsecutiveones (cuts, cutcount, ncount, ecount, elist, x, pool)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+CCtsp_lpcuts *pool;
+#endif
+{
+    double tzeit;
+    Xcplane *list = (Xcplane *) NULL;
+    int i, rval = 0;
+    int *elen = (int *) NULL;
+    Xgraph G;
+
+    xpool = pool;
+
+    *cutcount = 0;
+
+    G.nodelist = (Xnode *) NULL;
+    G.edgelist = (Xedge *) NULL;
+
+    elen = CC_SAFE_MALLOC (ecount, int);
+    if (!elen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++)
+        elen[i] = 0;
+
+    if (Xbuildgraph (&G, ncount, ecount, elist, elen)) {
+        fprintf (stderr, "Xbuildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Xconsecutiveones:\n"); fflush (stdout);
+    tzeit = CCutil_zeit ();
+    i = Xnewkids (&G, x, &list);
+    printf ("  %d consecutive ones cuts in %.2f seconds\n", i,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    if (munch_the_list (cuts, cutcount, &G, list)) {
+        fprintf (stderr, "munch_the_list failed\n");
+        return 1;
+    }
+
+CLEANUP:
+
+    Xfreegraph (&G);
+    CC_IFFREE (elen, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xnecklacecuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+        int *elist, double *x, CCtsp_lpcuts *pool)
+#else
+int Xnecklacecuts (cuts, cutcount, ncount, ecount, elist, x, pool)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+CCtsp_lpcuts *pool;
+#endif
+{
+    double tzeit;
+    Xcplane *list = (Xcplane *) NULL;
+    int i, rval = 0;
+    int *elen = (int *) NULL;
+    Xgraph G;
+
+    xpool = pool;
+
+    *cutcount = 0;
+
+    G.nodelist = (Xnode *) NULL;
+    G.edgelist = (Xedge *) NULL;
+
+    elen = CC_SAFE_MALLOC (ecount, int);
+    if (!elen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++)
+        elen[i] = 0;
+
+    if (Xbuildgraph (&G, ncount, ecount, elist, elen)) {
+        fprintf (stderr, "Xbuildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Xnecklaces:\n"); fflush (stdout);
+    tzeit = CCutil_zeit ();
+    i = Xnecklaces (&G, &list, x);
+    printf ("  %d necklace cuts in %.2f seconds\n", i, CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    if (munch_the_list (cuts, cutcount, &G, list)) {
+        fprintf (stderr, "munch_the_list failed\n");
+        return 1;
+    }
+
+CLEANUP:
+
+    Xfreegraph (&G);
+    CC_IFFREE (elen, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xcliquetrees (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+        int *elist, double *x)
+#else
+int Xcliquetrees (cuts, cutcount, ncount, ecount, elist, x)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+int ncount;
+int ecount;
+int *elist;
+double *x;
+#endif
+{
+    double tzeit, szeit = CCutil_zeit ();
+    Xcplane *list = (Xcplane *) NULL;
+    int i, rval = 0;
+    int *elen = (int *) NULL;
+    Xgraph G;
+
+    *cutcount = 0;
+
+    G.nodelist = (Xnode *) NULL;
+    G.edgelist = (Xedge *) NULL;
+
+    elen = CC_SAFE_MALLOC (ecount, int);
+    if (!elen) {
+        rval = 1;
+        goto CLEANUP;
+    }
+    for (i = 0; i < ecount; i++)
+        elen[i] = 0;
+
+    if (Xbuildgraph (&G, ncount, ecount, elist, elen)) {
+        fprintf (stderr, "Xbuildgraph failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    printf ("Xcliquetrees:\n"); fflush (stdout);
+    tzeit = CCutil_zeit ();
+    i = Xcliquetree (&G, &list, x);
+    printf ("  %d cliquetrees in %.2f seconds\n", i, CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    tzeit = CCutil_zeit ();
+    i = Xbasiccliques (&G, &list, x);
+    printf ("  %d basic cliquetrees in %.2f seconds\n", i,
+            CCutil_zeit () - tzeit);
+    fflush (stdout);
+
+    if (munch_the_list (cuts, cutcount, &G, list)) {
+        fprintf (stderr, "munch_the_list failed\n");
+        return 1;
+    }
+
+    printf ("Total Running Time: %.2f (seconds)\n", CCutil_zeit () - szeit);
+    fflush (stdout);
+
+CLEANUP:
+
+    Xfreegraph (&G);
+    CC_IFFREE (elen, int);
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int munch_the_list (CCtsp_lpcut_in **cuts, int *cutcount, Xgraph *G,
+        Xcplane *list)
+#else
+static int munch_the_list (cuts, cutcount, G, list)
+CCtsp_lpcut_in **cuts;
+int *cutcount;
+Xgraph *G;
+Xcplane *list;
+#endif
+{
+    Xcplane *c, *cnext;
+
+    for (c = list; c; c = cnext) {
+        cnext = c->next;
+        if (send_the_cut (cuts, G, c)) {
+            fprintf (stderr, "send_the_cut failed\n");
+            return 1;
+        }
+        Xfreecplanestruct (c);
+        (*cutcount)++;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int send_the_cut (CCtsp_lpcut_in **cuts, Xgraph *G, Xcplane *c)
+#else
+static int send_the_cut (cuts, G, c)
+CCtsp_lpcut_in **cuts;
+Xgraph *G;
+Xcplane *c;
+#endif
+{
+    CCtsp_lpcut_in *lc;
+
+    lc = CC_SAFE_MALLOC (1, CCtsp_lpcut_in);
+    if (!lc) {
+        fprintf (stderr, "out of memory in send_the_cut\n");
+        return 1;
+    }
+
+    if (cplane_to_lpcut_in (G, c, lc)) {
+        fprintf (stderr,  "cplane_to_lpcut_in failed\n");
+        CC_FREE (lc, CCtsp_lpcut_in);
+        return 1;
+    }
+
+    lc->next = *cuts;
+    *cuts = lc;
+
+#ifdef XSTUFF_DEBUG
+    CCtsp_print_lpcut_in (lc);
+#endif
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int cplane_to_lpcut_in (Xgraph *G, Xcplane *c, CCtsp_lpcut_in *lc)
+#else
+static int cplane_to_lpcut_in (G, c, lc)
+Xgraph *G;
+Xcplane *c;
+CCtsp_lpcut_in *lc;
+#endif
+{
+    Xnodeptrptr *npp;
+    int hcnt = 0, ccnt = 0;
+
+    lc->handlecount = 0;
+    lc->cliquecount = 0;
+    lc->cliques = (CCtsp_lpclique *) NULL;
+
+    if (c->handle) {
+        ccnt++;
+        if (c->teeth)
+            hcnt++;
+    } else {
+        for (npp = c->handles; npp; npp = npp->next) {
+            hcnt++;
+            ccnt++;
+        }
+    }
+    for (npp = c->teeth; npp; npp = npp->next)
+        ccnt++;
+
+    lc->cliques = CC_SAFE_MALLOC (ccnt, CCtsp_lpclique);
+    if (!lc->cliques) {
+        fprintf (stderr, "out of memory in cplane_to_lpcut_in\n");
+        return 1;
+    }
+
+    ccnt = 0;
+    if (c->handle) {
+        if (nodeptr_to_lpclique (G, c->handle, &(lc->cliques[ccnt++]))) {
+            fprintf (stderr, "nodeptr_to_lpclique failed\n");
+            CC_FREE (lc->cliques, CCtsp_lpclique);
+            return 1;
+        }
+    } else {
+        for (npp = c->handles; npp; npp = npp->next) {
+            if (nodeptr_to_lpclique (G, npp->this, &(lc->cliques[ccnt++]))) {
+                fprintf (stderr, "nodeptr_to_lpclique failed\n");
+                CC_FREE (lc->cliques, CCtsp_lpclique);
+                return 1;
+            }
+        }
+    }
+    for (npp = c->teeth; npp; npp = npp->next) {
+        if (nodeptr_to_lpclique (G, npp->this, &(lc->cliques[ccnt++]))) {
+            fprintf (stderr, "nodeptr_to_lpclique failed\n");
+            CC_FREE (lc->cliques, CCtsp_lpclique);
+            return 1;
+        }
+    }
+    lc->handlecount = hcnt;
+    lc->cliquecount = ccnt;
+    lc->rhs         = CCtsp_CUTRHS(lc);
+    lc->sense       = 'G';
+    lc->branch      = 0;
+
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int nodeptr_to_lpclique (Xgraph *G, Xnodeptr *npcliq,
+         CCtsp_lpclique *cliq)
+#else
+static int nodeptr_to_lpclique (G, npcliq, cliq)
+Xgraph *G;
+Xnodeptr *npcliq;
+CCtsp_lpclique *cliq;
+#endif
+{
+    int i, k = 0;
+    Xnodeptr *np;
+    int *ac = (int *) NULL;
+    int nseg;
+
+    cliq->segcount = 0;
+    cliq->nodes = (CCtsp_segment *) NULL;
+
+    for (np = npcliq; np; np = np->next)
+        k++;
+
+    if (!k) {
+        fprintf (stderr, "empty clique in nodeptr_to_lpclique\n");
+        return 1;
+    }
+
+    ac = CC_SAFE_MALLOC (k, int);
+    if (!ac) {
+        fprintf (stderr, "out of memory in nodeptr_to_lpclique\n");
+        return 1;
+    }
+
+    for (i = 0, np = npcliq; np; np = np->next, i++) {
+        ac[i] = np->this - G->nodelist;
+    }
+
+    CCutil_int_array_quicksort (ac, k);
+
+    nseg = 0;
+    i = 0;
+    while (i < k) {
+        while (i < (k - 1) && ac[i + 1] == (ac[i] + 1))
+            i++;
+        i++;
+        nseg++;
+    }
+
+    cliq->nodes = CC_SAFE_MALLOC (nseg, CCtsp_segment);
+    if (!cliq->nodes) {
+        fprintf (stderr, "out of memory in in nodeptr_to_lpclique\n");
+        CC_FREE (ac, int);
+        return 1;
+    }
+    cliq->segcount = nseg;
+
+    nseg = 0;
+    i = 0;
+    while (i < k) {
+        cliq->nodes[nseg].lo = ac[i];
+        while (i < (k - 1) && ac[i + 1] == (ac[i] + 1))
+            i++;
+        cliq->nodes[nseg].hi = ac[i++];
+        nseg++;
+    }
+
+    CC_FREE (ac, int);
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+int Xsearch_cutpool_for_slack_cliques (Xgraph *G, double maxslack,
+         int request, int *kcount, Xportableclique **klist, int ecount,
+         int *elist, double *x)
+#else
+int Xsearch_cutpool_for_slack_cliques (G, maxslack, request, kcount, klist,
+         ecount, elist, x)
+Xgraph *G;
+double maxslack;
+int request;
+int *kcount;
+Xportableclique **klist;
+int ecount;
+int *elist;
+double *x;
+#endif
+{
+    int i, j, isize, k, p;
+    CCtsp_lpclique *c;
+    CCtsp_lpclique *cliquelist = (CCtsp_lpclique *) NULL;
+    double   *cliquevals = (double *) NULL;
+    int      cliquecount = 0;
+    double maxdelta = maxslack * 2.0 + 2.0;
+    int maxcliques = request;
+    int rval = 0;
+
+    *kcount = 0;
+    *klist = (Xportableclique *) NULL;
+
+    printf ("Checking Xpoolcliques...\n"); fflush (stdout);
+
+    rval = CCtsp_search_cutpool_cliques (xpool, &cliquelist, &cliquecount,
+                       G->nnodes, ecount, elist, x, maxdelta, maxcliques,
+                       &cliquevals);
+
+    printf ("Back from CCtsp_search_cutpool_cliques\n"); fflush (stdout);
+    if (rval) {
+        fprintf (stderr, "CCtsp_search_cutpool_cliques failed\n");
+        goto CLEANUP;
+    }
+
+    if (!cliquecount) {
+        printf ("Found no nearly tight cliques\n"); fflush (stdout);
+        goto CLEANUP;
+    }
+
+    *klist = CC_SAFE_MALLOC (cliquecount, Xportableclique);
+    if (!(*klist)) {
+        fprintf (stderr, "out of memory in Xsearch_cutpool\n");
+        rval = 1; goto CLEANUP;
+    }
+
+    for (i = 0; i < cliquecount; i++) {
+        c = &(cliquelist[i]);
+        isize = 0;
+        for (k = 0; k < c->segcount; k++) {
+            isize += (c->nodes[k].hi - c->nodes[k].lo + 1);
+        }
+        (*klist)[i].size = isize;
+        (*klist)[i].nodes = CC_SAFE_MALLOC (isize, int);
+        if (!(*klist)[i].nodes) {
+            fprintf (stderr, "out of memory in Xsearch_cutpool A\n");
+            CC_FREE (*klist, Xportableclique);
+            rval = 1; goto CLEANUP;
+        }
+        p = 0;
+        for (k = 0; k < c->segcount; k++) {
+            for (j = c->nodes[k].lo; j <= c->nodes[k].hi; j++) {
+                (*klist)[i].nodes[p++] = j;
+            }
+        }
+        (*klist)[i].cutval = ((2.0 *((double) isize)) - cliquevals[i])/2.0;
+        (*klist)[i].cutval = (double) isize - 1.0 - (*klist)[i].cutval;
+    }
+    *kcount = cliquecount;
+
+CLEANUP:
+
+    for (i = 0; i < cliquecount; i++) {
+        CC_IFFREE (cliquelist[i].nodes, CCtsp_segment);
+    }
+    CC_IFFREE (cliquelist, CCtsp_lpclique);
+    CC_IFFREE (cliquevals, double);
+    return rval;
+}
diff --git a/contrib/blossom/concorde97/XSTUFF/Xsubtour.h b/contrib/blossom/concorde97/XSTUFF/Xsubtour.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae5679e9ba0666fc29759addb9ec45bb9c6a04b0
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xsubtour.h
@@ -0,0 +1,718 @@
+#ifndef __XSUBTOUR_H
+#define __XSUBTOUR_H
+
+#include "Xcutpool.h"
+
+#define XFALSE 0
+#define XEPSILON .0001
+#define XCUTTOLERANCE .01
+#define XBLOTOLERANCE .01
+#define XCUTTWO (2.0-XCUTTOLERANCE)
+#define XCUTNUM 150
+#define XMAXWEIGHT 1e30
+#define XBIGNEG -10000000000.0
+#define SWAP(x,y,temp) (temp = x, x = y, y = temp)
+#define OTHEREND(e,n) (e->ends[0] == n ? e->ends[1] : e->ends[0])
+#define OTHERCURRENTEND(e,n) ((e)->cends[0] == (n) ? (e)->cends[1] : (e)->cends[0])
+
+typedef struct Xedge {
+    struct Xnode  *ends[2];
+    struct Xnode  *cends[2];
+    struct Xnode  *splitter;
+    int           weight;
+    double        x;
+    double        rc;
+    double        flow;
+    int           stay;
+    int           elim;
+    int           weak;
+    int           hold;
+    int           fixed;
+    int           magiclabel;
+    struct Xedge  *next;
+} Xedge;
+
+typedef struct Xextraedge {
+    int ends[2];
+    int weight;
+    int elim;
+} Xextraedge;
+
+typedef struct Xextralink {
+    int ends[2];
+    int weight;
+    struct Xextralink *next;
+} Xextralink;
+
+typedef struct Xedgeptr {
+    struct Xedge     *this;
+    struct Xedgeptr  *next;
+} Xedgeptr;
+
+typedef struct Xedgeset {
+    struct Xedgeptr *head;
+    struct Xedgeptr *tail;
+} Xedgeset;
+
+typedef struct Xnodeset {
+    struct Xnodeptr  *head;
+    struct Xnodeptr  *tail;
+} Xnodeset;
+
+typedef struct Xnode {
+    Xedgeset adj;
+    Xedgeset cadj;
+    Xnodeset base;
+    int degree;
+    int     magiclabel;
+    int     stacklabel;
+    int     pseudonumber;
+    double  excess;
+    int     flowlabel;
+    Xedgeptr *current;
+    int     active;
+    struct  Xnode  *next, *prev;
+    struct  Xnode  *snext;
+    struct  Xnode  *tnext;  /* Only use locally */
+    Xedge *pe;
+    struct  Xclink *cuts;
+    struct  Xblink *blossoms;
+    int     mark;
+    int     Tmark;
+    int     rand1;
+    int     rand2;
+} Xnode;
+
+typedef struct Xnodeptr {
+    struct Xnode     *this;
+    struct Xnodeptr  *next;
+} Xnodeptr;
+
+typedef struct Xnodeptrptr {
+    struct Xnodeptr    *this;
+    struct Xnodeptrptr *next;
+} Xnodeptrptr;
+
+typedef struct Xclink {
+    int            cut;
+    struct Xclink *next;
+} Xclink;
+
+typedef struct Xblink {
+    int             cut;
+    char            handle;
+    int             tooth;
+    struct Xblink   *next;
+} Xblink;
+
+typedef struct Xconstraint {
+    int             sort;
+    struct Xnodeptr *teeth;
+    int             rhs;
+} Xconstraint;
+
+typedef struct Xcplane {
+    unsigned long       val;
+    struct Xnodeptr     *handle;
+    struct Xnodeptrptr  *handles;
+    struct Xnodeptrptr  *teeth;
+    struct Xcplane      *next;
+} Xcplane;
+
+typedef struct Xiplane {
+    struct Xintptr      *handle;
+    struct Xintptrptr   *handles;
+    struct Xintptrptr   *teeth;
+    struct Xiplane      *next;
+} Xiplane;
+
+typedef struct Xcuttree_node {
+    struct Xcuttree_node *parent;
+    struct Xcuttree_node *sibling;
+    struct Xcuttree_node *child;
+    double cutval;
+    int ndescendants;
+    Xnode *special;
+    Xnodeset nlist;
+    Xnode *pseudonode;
+    struct Xcuttree_node *next;
+} Xcuttree_node;
+
+typedef struct Xintptr {
+    int              this;
+    struct Xintptr   *next;
+} Xintptr;
+
+typedef struct Xintptrptr {
+    Xintptr           *this;
+    struct Xintptrptr *next;
+} Xintptrptr;
+
+typedef struct Xblock {
+    Xnodeptr           *members;
+    struct Xcutnodeptr *cutnodes;
+    struct Xblockptr   *neighbors;
+    Xedgeptr           *one;
+    double             weight;
+    double             x;
+    int                mark;
+} Xblock;
+
+typedef struct Xblockptr {
+    struct Xblockptr *next;
+    struct Xblock    *this;
+    double           hood_weight;
+} Xblockptr;
+
+typedef struct Xcutnode {
+    Xnode           *name;
+    Xblockptr       *blocks;
+    int             mark;
+} Xcutnode;
+
+typedef struct Xcutnodeptr {
+    struct Xcutnode  *this;
+    struct Xcutnodeptr  *next;
+} Xcutnodeptr;
+
+typedef struct Xcombhash {
+    unsigned long    val;
+    struct Xcombhash *next;
+} Xcombhash;
+
+typedef struct Xclique {
+    double slack;
+    Xintptr *nodes;
+    struct Xclique *next;
+    struct Xclique *prev;
+} Xclique;
+
+typedef struct Xgraph {
+    int      nnodes;
+    Xnode    *nodelist;
+    int      nedges;
+    Xedge    *edgelist;
+    Xnode    *pseudonodelist;
+    Xedge    *pseudoedgelist;
+    int      npseudonodes;
+    int      magicnum;
+    int      stacknum;
+    int      magicedgenum;
+} Xgraph;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+/* adjacency.c */
+
+void
+    Xbuildpanadjlist (void),
+    Xbuildmatadjlist (void);
+
+/* allcuts.c */
+
+void
+    Xall_tightcuts (Xgraph *Gin, Xclique **cliquelistin, int *ncliquesin);
+
+/* Xblock.c */
+
+void
+    Xlocalshrink_a (Xgraph *G, int component),
+    Xlocalshrink_b (Xgraph *G, int component),
+    Xlocalshrink_c (Xgraph *G, int component),
+    Xadd_tooth (Xnode *t, Xnodeptr **list);
+
+int
+    Xblockcombs (Xgraph *G, Xcplane **cplanelist, double *x),
+    Xlocalcombs (Xgraph *G, Xcplane **cplanelist, double *x),
+    Xglobalcombs (Xgraph *G, Xcplane **cplanelist, double *x),
+    XTmark_components (Xgraph *G),
+    Xbasiccliques (Xgraph *G, Xcplane **list, double *x),
+    Xsearchbasiccliques (Xgraph *G, Xcplane **list, int pseudo, double *x),
+    Xbasicclique (Xgraph *G, Xcplane **list, double *x, Xblock *bigtooth),
+    Xmarktooth (Xedge *e, Xnodeptr **list),
+    Xmarktoothend (Xnode *n, Xnodeptr **list),
+    Xrepeat_1_shrink (Xgraph *G, Xnode *n, Xedge *e);
+
+Xedge
+    *Xcurrentedge (Xnode *n1, Xnode *n2);
+
+
+/* Xblocheck.c */
+
+int
+    Xexactblossoms_run (Xgraph *G, Xcplane **list, double *x),
+    Xexactblossomcheck (Xgraph *G, Xcplane **list, int pseudo, double *x),
+    Xolaf (Xgraph *G, int choice);
+
+
+/* Xclique.c */
+
+int
+    Xcliquetree (Xgraph *G, Xcplane **list, double *x),
+    Xcliquetree_work (Xgraph *G, Xcplane **list, int pseudo, double *x,
+          int type_of_grow);
+
+
+/* Xcuthash.c */
+
+void
+    Xinit_hash_values (Xgraph *G);
+
+unsigned long
+    Xcut_hash_value (Xnodeptr *h),
+    Xcomb_hash_value (Xnodeptr *h, Xnodeptrptr *t),
+    Xclique_hash_value (Xnodeptrptr *h, Xnodeptrptr *t);
+
+
+/* Xblobs.c */
+
+void
+    Xpancakex (Xgraph *G, double *x),
+    Xfreepancake (void),
+    Xshrinksmallblobs (Xgraph *G, int rnum, int biggest),
+    Xtightblobs (Xgraph *G);
+
+int
+    Xblobsviolated (Xgraph *G, Xcplane **list );
+
+
+/* Xcclean.c */
+
+void
+    Xcleancomb (Xgraph *G, Xnodeptr **handle, Xnodeptrptr **teeth,
+          int *nteeth, double *x);
+int
+    Xcheckcomb (Xgraph *G, Xnodeptr *handle, Xnodeptrptr *teeth),
+    Xcliquefluff (Xgraph *G, Xnodeptrptr **handles, Xnodeptrptr **teeth),
+    Xtemp_combfluff (Xgraph *G, Xnodeptr **handle, Xnodeptrptr **teeth),
+    Xcombfluff (Xgraph *G, Xnodeptrptr **handles, Xnodeptrptr **teeth,
+         int cliquetest),
+    Xhistok (unsigned int *hist),
+    Xtemp_combcheck (Xgraph *G, Xnodeptr *handle, Xnodeptrptr *teeth),
+    Xcheckclique (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth);
+
+/* Xcutload.c */
+
+void
+    Xcliquetree_slack_rhs_flow (Xgraph *G, Xnodeptrptr *handles,
+             Xnodeptrptr *teeth, double *x, double *slack, double *rhs),
+    Xfreecplanelist (Xcplane **list);
+
+int
+    Xcutchecksout (Xgraph *G, int x),
+    Xtemp_doblossom (Xgraph *G, Xcplane **cplanelist, Xnodeptr *handle,
+                     Xedgeptr *teeth),
+    Xviolated_clique_flow (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth,
+                           double *x),
+    Xloadcplane (Xcplane **list, Xnodeptr *h, Xnodeptrptr *H,
+                 Xnodeptrptr *t, int countcheck),
+    Xloadcplane_cut (Xgraph *G, Xcplane **list, int num);
+
+
+/* Xcuts.c */
+
+int
+    Xolaf_combs (Xgraph *G, Xcplane **list, double *x),
+    Xblobcuts (Xgraph *G, Xcplane **list, double *x);
+
+int
+    Xreallyfaststuff (Xcplane **, double *, double *),
+    Xfaststuff (Xcplane **, double *, double *),
+    Xmediumstuff (Xcplane **, double *, double *),
+    Xslowstuff (Xcplane **, double *, double *),
+    Xreallyslowstuff (Xcplane **, double *, double *),
+    Xall_run_olaf (Xcplane **, double *),
+    Xheuristiccutcheck (Xcplane **, double *);
+
+/* Xcututil.c */
+
+void
+    Xfreecplanestruct (Xcplane *c),
+    Xfreeiplanestruct (Xiplane *c),
+    Xcplane_to_iplane (Xgraph *G, Xcplane *c, Xiplane **ipl),
+    Xiplane_to_cplane (Xgraph *G, Xiplane *c, Xcplane **cpl),
+    Xportablecut_to_cplane (Xgraph *G, Xportablecut *p, Xcplane **cpl),
+    Xportablecut_to_handles_and_teeth (Xgraph *G, Xportablecut *p,
+          Xnodeptrptr **handles, Xnodeptrptr **teeth),
+    Xportablecut_to_iplane (Xportablecut *p, Xiplane **ipl),
+    Xiplane_to_portablecut (Xiplane *c, Xportablecut *p),
+    Xfreeteeth (Xnodeptrptr *teeth),
+    Xprintchvatalcomb (Xgraph *G, Xnodeptr *h, Xnodeptrptr *t),
+    Xprintcliquetree (Xgraph *G, Xnodeptrptr *h, Xnodeptrptr *t),
+    Xdumpchvatalcomb (FILE *out, Xintptr *h, Xintptrptr *t),
+    Xdumpcliquetree (FILE *out, Xintptrptr *h, Xintptrptr *t);
+
+int
+    Xslackclique (Xgraph *G, Xnodeptrptr *handles, Xnodeptrptr *teeth,
+                  double *slack),
+    Xinduced_edges_flow (Xgraph *G, Xnodeptr *set);
+
+
+/* Xflow.c */
+
+double
+    Xflow (Xgraph *G, Xnode *, Xnode *, double);
+
+int
+    Xmincut (Xgraph *G, Xnode *, Xnode *, double, double *, int *),
+    Xexactcutcheck (Xgraph *G, Xcplane **list, double *x),
+    Xrunconnectcuts (Xgraph *G, Xcplane **, double *);
+
+
+/* Xgomhu.c */
+
+Xcuttree_node
+    *Xgomory_hu (Xgraph *G);
+
+void
+    Xcuttree_free (Xcuttree_node *n);
+
+/* necklace.c */
+
+int
+    Xnecklaces (Xgraph *Gin, Xcplane **, double *);
+
+/* newkids.c */
+
+int
+    Xnewkids (Xgraph *Gin, double *x, Xcplane **list);
+
+/* Xourallo.c */
+
+Xblink *Xblinkalloc (void);
+Xblockptr *Xblockptralloc (void);
+Xclink *Xclinkalloc (void);
+Xclique *Xcliquealloc (void);
+Xcombhash *Xcombhashalloc (void);
+Xcplane *Xcplanealloc (void);
+Xcutnodeptr *Xcutnodeptralloc (void);
+Xcuttree_node *Xcuttree_nodealloc (void);
+Xedge *Xedgealloc (void);
+Xedgeptr *Xedgeptralloc (void);
+Xintptr *Xintptralloc (void);
+Xintptrptr *Xintptrptralloc (void);
+void Xadd_intptrptr (Xintptrptr **, Xintptr *);
+Xiplane *Xiplanealloc (void);
+Xnode *Xnodealloc (void);
+Xnodeptr *Xnodeptralloc (void);
+Xnodeptrptr *Xnodeptrptralloc (void);
+void Xadd_edgeptr (Xedgeptr **, Xedge *);
+void Xadd_extralink (Xextralink **, int, int, int);
+void Xadd_nodeptr (Xnodeptr **, Xnode *);
+void Xadd_nodeptrptr (Xnodeptrptr **, Xnodeptr *);
+void Xblinkfree (Xblink *);
+void Xblockptrfree (Xblockptr *);
+void Xclinkfree (Xclink *);
+void Xcliquefree (Xclique *);
+void Xcombhashfree (Xcombhash *);
+void Xcplane_list_free (Xcplane *);
+void Xcplanefree (Xcplane *);
+void Xcutnodeptrfree (Xcutnodeptr *);
+void Xcuttree_nodefree (Xcuttree_node *);
+void Xedgefree (Xedge *);
+void Xedge_list_free (Xedge *);
+void Xedgeptr_list_free (Xedgeptr *);
+void Xedgeptrfree (Xedgeptr *);
+void Xextralink_list_free (Xextralink *);
+void Xinitialize_ouralloc (void);
+void Xintptr_list_free (Xintptr *);
+void Xintptrfree (Xintptr *);
+void Xintptrptr_list_free (Xintptrptr *);
+void Xintptrptr_list_freeall(Xintptrptr *);
+void Xintptrptrfree (Xintptrptr *);
+void Xiplane_list_free (Xiplane *);
+void Xiplanefree (Xiplane *);
+void Xnodefree (Xnode *);
+void Xnodeptr_list_free (Xnodeptr *);
+void Xnodeptrfree (Xnodeptr *);
+void Xnodeptrptr_list_free (Xnodeptrptr *);
+void Xnodeptrptrfree (Xnodeptrptr *);
+void Xunion_nodeptr (Xgraph *G, Xnodeptr *, Xnodeptr *, Xnodeptr **);
+
+
+/* Xshrink.c */
+
+void
+    Xbuildpseudonodelist (Xgraph *G, int all),
+    Xbuildpseudonodenumbers (Xgraph *G),
+    Xdestroypseudonodelist (Xgraph *G),
+    Xdumppseudograph (Xgraph *G),
+    Xdumppseudograph_edgelist (Xgraph *G),
+    Xsimpleshrink (Xgraph *G, Xnode *, Xnode *),
+    Xrebuildcadj (Xgraph *G);
+
+int
+    Xshrinkprocess (Xgraph *G, Xcplane **),
+    Xheavy_edge_cuts (Xgraph *G, Xcplane **list, double *x);
+
+
+/* Xgraph.c */
+
+void
+    Xfreegraph (Xgraph *G),
+    Xloadx (Xgraph *G, double *x);
+
+int
+    Xbuildgraph (Xgraph *G, int ncount, int ecount, int *elist, int *elen);
+
+/* Xstuff.c */
+
+int
+    Xsearch_cutpool_for_slack_cliques (Xgraph *G, double maxslack,
+         int request, int *kcount, Xportableclique **klist, int ecount,
+         int *elist, double *x);
+
+#else
+
+/* adjacency.c */
+
+void
+    Xbuildpanadjlist (),
+    Xbuildmatadjlist ();
+
+/* allcuts.c */
+
+void
+    Xall_tightcuts ();
+
+/* Xblock.c */
+
+void
+    Xlocalshrink_a (),
+    Xlocalshrink_b (),
+    Xlocalshrink_c (),
+    Xadd_tooth ();
+
+int
+    Xblockcombs (),
+    Xlocalcombs (),
+    Xglobalcombs (),
+    XTmark_components (),
+    Xbasiccliques (),
+    Xsearchbasiccliques (),
+    Xbasicclique (),
+    Xmarktooth (),
+    Xmarktoothend (),
+    Xrepeat_1_shrink ();
+
+Xedge
+    *Xcurrentedge ();
+
+
+/* Xblocheck.c */
+
+int
+    Xexactblossoms_run (),
+    Xexactblossomcheck (),
+    Xolaf ();
+
+
+/* Xclique.c */
+
+int
+    Xcliquetree (),
+    Xcliquetree_work ();
+
+
+/* Xcuthash.c */
+
+void
+    Xinit_hash_values ();
+
+unsigned long
+    Xcut_hash_value (),
+    Xcomb_hash_value (),
+    Xclique_hash_value ();
+
+
+/* Xblobs.c */
+
+void
+    Xpancakex (),
+    Xfreepancake (),
+    Xshrinksmallblobs (),
+    Xtightblobs ();
+
+int
+    Xblobsviolated ();
+
+
+/* Xcclean.c */
+
+void
+    Xcleancomb ();
+int
+    Xcheckcomb (),
+    Xcliquefluff (),
+    Xtemp_combfluff (),
+    Xcombfluff (),
+    Xhistok (),
+    Xtemp_combcheck (),
+    Xcheckclique ();
+
+/* Xcutload.c */
+
+void
+    Xcliquetree_slack_rhs_flow (),
+    Xfreecplanelist ();
+
+int
+    Xcutchecksout (),
+    Xtemp_doblossom (),
+    Xviolated_clique_flow (),
+    Xloadcplane (),
+    Xloadcplane_cut ();
+
+
+/* Xcuts.c */
+
+int
+    Xolaf_combs (),
+    Xblobcuts ();
+
+int
+    Xreallyfaststuff (),
+    Xfaststuff (),
+    Xmediumstuff (),
+    Xslowstuff (),
+    Xreallyslowstuff (),
+    Xall_run_olaf (),
+    Xheuristiccutcheck ();
+
+/* Xcututil.c */
+
+void
+    Xfreecplanestruct (),
+    Xfreeiplanestruct (),
+    Xcplane_to_iplane (),
+    Xiplane_to_cplane (),
+    Xportablecut_to_cplane (),
+    Xportablecut_to_handles_and_teeth (),
+    Xportablecut_to_iplane (),
+    Xiplane_to_portablecut (),
+    Xfreeteeth (),
+    Xprintchvatalcomb (),
+    Xprintcliquetree (),
+    Xdumpchvatalcomb (),
+    Xdumpcliquetree ();
+
+int
+    Xslackclique (),
+    Xinduced_edges_flow ();
+
+
+/* Xflow.c */
+
+double
+    Xflow ();
+
+int
+    Xmincut (),
+    Xexactcutcheck (),
+    Xrunconnectcuts ();
+
+
+/* Xgomhu.c */
+
+Xcuttree_node
+    *Xgomory_hu ();
+
+void
+    Xcuttree_free ();
+
+/* necklace.c */
+
+int
+    Xnecklaces ();
+
+/* newkids.c */
+
+int
+    Xnewkids ();
+
+/* Xourallo.c */
+
+Xblink *Xblinkalloc ();
+Xblockptr *Xblockptralloc ();
+Xclink *Xclinkalloc ();
+Xclique *Xcliquealloc ();
+Xcombhash *Xcombhashalloc ();
+Xcplane *Xcplanealloc ();
+Xcutnodeptr *Xcutnodeptralloc ();
+Xcuttree_node *Xcuttree_nodealloc ();
+Xedge *Xedgealloc ();
+Xedgeptr *Xedgeptralloc ();
+Xintptr *Xintptralloc ();
+Xintptrptr *Xintptrptralloc ();
+void Xadd_intptrptr ();
+Xiplane *Xiplanealloc ();
+Xnode *Xnodealloc ();
+Xnodeptr *Xnodeptralloc ();
+Xnodeptrptr *Xnodeptrptralloc ();
+void Xadd_edgeptr ();
+void Xadd_extralink ();
+void Xadd_nodeptr ();
+void Xadd_nodeptrptr ();
+void Xblinkfree ();
+void Xblockptrfree ();
+void Xclinkfree ();
+void Xcliquefree ();
+void Xcombhashfree ();
+void Xcplane_list_free ();
+void Xcplanefree ();
+void Xcutnodeptrfree ();
+void Xcuttree_nodefree ();
+void Xedgefree ();
+void Xedge_list_free ();
+void Xedgeptr_list_free ();
+void Xedgeptrfree ();
+void Xextralink_list_free ();
+void Xinitialize_ouralloc ();
+void Xintptr_list_free ();
+void Xintptrfree ();
+void Xintptrptr_list_free ();
+void Xintptrptr_list_freeall();
+void Xintptrptrfree ();
+void Xiplane_list_free ();
+void Xiplanefree ();
+void Xnodefree ();
+void Xnodeptr_list_free ();
+void Xnodeptrfree ();
+void Xnodeptrptr_list_free ();
+void Xnodeptrptrfree ();
+void Xunion_nodeptr ();
+
+
+/* Xshrink.c */
+
+void
+    Xbuildpseudonodelist (),
+    Xbuildpseudonodenumbers (),
+    Xdestroypseudonodelist (),
+    Xdumppseudograph (),
+    Xdumppseudograph_edgelist (),
+    Xsimpleshrink (),
+    Xrebuildcadj ();
+
+int
+    Xshrinkprocess (),
+    Xheavy_edge_cuts ();
+
+
+/* Xgraph.c */
+
+void
+    Xfreegraph (),
+    Xloadx ();
+
+int
+    Xbuildgraph ();
+
+/* Xstuff.c */
+
+int
+    Xsearch_cutpool_for_slack_cliques ();
+
+#endif
+#endif /* __XSUBTOUR_H */
+
diff --git a/contrib/blossom/concorde97/XSTUFF/Xtest.c b/contrib/blossom/concorde97/XSTUFF/Xtest.c
new file mode 100644
index 0000000000000000000000000000000000000000..27d8155e0e7d719ea18692f3ba011490a27a4b15
--- /dev/null
+++ b/contrib/blossom/concorde97/XSTUFF/Xtest.c
@@ -0,0 +1,229 @@
+/***************************************************************************/
+/*                                                                         */
+/*                  THE MAIN PROGRAM FOR CONCORDE                          */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: September 25, 1995                                               */
+/*                                                                         */
+/*  SEE short decsribtion in usage ().                                     */
+/*                                                                         */
+/*  Link with:                                                             */
+/*    SEE conmake.grs                                                      */
+/*                                                                         */
+/***************************************************************************/
+
+#include "machdefs.h"
+#include "util.h"
+#include "tsp.h"
+#include "Xstuff.h"
+
+static int seed = 0;
+static char *xfilename = (char *) NULL;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    main (int ac, char **av);
+
+static void
+    usage (char *f);
+
+static int
+    parseargs (int ac, char **av),
+    getxvector (char *f, int *ncount, int *ecount, int **elist, double **x);
+
+#else  /* CC_PROTOTYPE_ANSI */
+
+int
+    main ();
+
+static void
+    usage ();
+
+static int
+    parseargs (),
+    getxvector ();
+
+#endif /* CC_PROTOTYPE_ANSI */
+
+
+#ifdef CC_PROTOTYPE_ANSI
+int main (int ac, char **av)
+#else
+int main (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int ncount, ecount;
+    int *elist = (int *) NULL;
+    double *x = (double *) NULL;
+    int cnt;
+    CCtsp_lpcut_in *cuts = (CCtsp_lpcut_in *) NULL;
+    int rval = 0;
+
+    seed = (int) CCutil_real_zeit ();
+    if (parseargs (ac, av))
+        return 0;
+    CCutil_sprand (seed);
+
+    if (xfilename == (char *) NULL) {
+        usage (av[0]);
+        return 0;
+    }
+
+    if (getxvector (xfilename, &ncount, &ecount, &elist, &x)) {
+        fprintf (stderr, "getxvector failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (Xfastcuts (&cuts, &cnt, ncount, ecount, elist, x)) {
+        fprintf (stderr, "Xfastcuts failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+    if (Xexactsubtours (&cuts, &cnt, ncount, ecount, elist, x)) {
+        fprintf (stderr, "Xfastcuts failed\n");
+        rval = 1;
+        goto CLEANUP;
+    }
+
+CLEANUP:
+
+    CC_IFFREE (elist, int);
+    CC_IFFREE (x, double);
+
+    if (CCutil_bigchunk_free_world ()) {
+        fprintf (stderr, "ERROR: bigchunk_free_world failed\n");
+        return 1;
+    }
+
+    return rval;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int parseargs (int ac, char **av)
+#else
+static int parseargs (ac, av)
+int ac;
+char **av;
+#endif
+{
+    int c;
+
+    while ((c = CCutil_bix_getopt (ac, av, "s:x:")) != EOF)
+        switch (c) {
+        case 's':
+            seed = atoi (CCutil_bix_optarg);
+            break;
+        case 'x':
+            xfilename = CCutil_bix_optarg;
+            break;
+        case CC_BIX_GETOPT_UNKNOWN:
+        case '?':
+        default:
+            usage (av[0]);
+            return 1;
+        }
+    if (CCutil_bix_optind != ac) {
+        usage (av[0]);
+        return 1;
+    }
+    return 0;
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static void usage (char *f)
+#else
+static void usage (f)
+char *f;
+#endif
+{
+    fprintf (stderr, "Usage: %s [-see below-]\n", f);
+    fprintf (stderr, "   -s #  random seed\n");
+    fprintf (stderr, "   -x f  x-vector file\n");
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+static int getxvector (char *f, int *ncount, int *ecount, int **elist,
+                       double **x)
+#else
+static int getxvector (f, ncount, ecount, elist, x)
+char *f;
+int *ncount, *ecount;
+int **elist;
+double **x;
+#endif
+{
+    FILE *in = fopen (f, "r");
+    int i;
+
+    *ncount = 0;
+    *ecount = 0;
+    *elist = (int *) NULL;
+    *x = (double *) NULL;
+
+    if (in == (FILE *) NULL) {
+        perror (f);
+        fprintf (stderr, "Unable to open %s for input\n", f);
+        return 1;
+    }
+
+    fscanf (in, "%d %d\n", ncount, ecount);
+    printf ("nnodes = %d, nedges = %d\n", *ncount, *ecount);
+    fflush (stdout);
+
+    *elist = CC_SAFE_MALLOC ((*ecount) * 2, int);
+    if (!(*elist)) {
+        fprintf (stderr, "Out of memory\n");
+        fclose (in);
+        return 1;
+    }
+    *x = CC_SAFE_MALLOC (*ecount, double);
+    if (!(*x)) {
+        fprintf (stderr, "Out of memory\n");
+        CC_FREE (*elist, int);
+        fclose (in);
+        return 1;
+    }
+
+    for (i = 0; i < *ecount; i++) {
+        fscanf (in, "%d %d %lf", &((*elist)[2 * i]), &((*elist)[(2 * i) + 1]),
+                                 &((*x)[i]));
+    }
+
+    fclose (in);
+    return 0;
+}
+
+/*  Dummies for now */
+
+/*
+#ifdef CC_PROTOTYPE_ANSI
+int Xloadcplane_cut (Xgraph *G, Xcplane **list, int k)
+#else
+int Xloadcplane_cut (G, list, k)
+Xgraph *G;
+Xcplane **list;
+int k;
+#endif
+{
+    int i;
+
+    printf ("Subtour: ");
+    for (i = 0; i < G->nnodes; i++) {
+        if (G->nodelist[i].magiclabel == k)
+            printf ("%d ", i);
+    }
+    printf ("\n");
+    fflush (stdout);
+
+    return 1;
+}
+*/
diff --git a/contrib/blossom/concorde97/concorde.h b/contrib/blossom/concorde97/concorde.h
new file mode 100644
index 0000000000000000000000000000000000000000..20ec25de96aac14403f70c3c2c045a904255d686
--- /dev/null
+++ b/contrib/blossom/concorde97/concorde.h
@@ -0,0 +1,2735 @@
+#ifndef  __PREFIX_H
+#define  __PREFIX_H
+
+#define CC_PROTOTYPE_ANSI
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#endif  /* __PREFIX_H */
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN UTIL                       */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+
+#ifndef __UTIL_H
+#define __UTIL_H
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             allocrus.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+/***************************************************************************/
+/*                                                                         */
+/*                   MEMORY ALLOCATION MACROS                              */
+/*                                                                         */
+/*                           TSP CODE                                      */
+/*                                                                         */
+/*                                                                         */
+/*  Written by:  Applegate, Bixby, Chvatal, and Cook                       */
+/*  Date: February 24, 1995 (cofeb24)                                      */
+/*                                                                         */
+/*                                                                         */
+/*  EXPORTED MACROS:                                                       */
+/*    CC_SAFE_MALLOC (nnum,type)                                           */
+/*         int nnum (the number of objects to be malloced)                 */
+/*         data type (the sort of objects to be malloced)                  */
+/*         RETURNS a pointer to the allocated space. If out of memory,     */
+/*                 it prints an error message and returns NULL.            */
+/*                                                                         */
+/*    CC_FREE (object,type)                                                */
+/*         type *object (pointer to previously allocated space)            */
+/*         data type (the sort of object)                                  */
+/*         ACTION: frees the memory and sets the object to NULL.           */
+/*                                                                         */
+/*    CC_IFFREE (object,type)                                              */
+/*         type *object (pointer to previously allocated space)            */
+/*         data type (the sort of object)                                  */
+/*         ACTION: if *object is not NULL, frees the memory and sets       */
+/*                 the object to NULL.                                     */
+/*                                                                         */
+/*    CC_PTR_ALLOC_ROUTINE (type, functionname, chunklist, freelist)       */
+/*         data type (the sort of objects)                                 */
+/*         string functionname (the generated function)                    */
+/*         CCbigchunkptr *chunklist (used to accumulate bigchunks)         */
+/*         type *freelist (used for the linked list of objects)            */
+/*         ACTION: Generates a function ("functionname") that returns      */
+/*                 (type *) objects, keeping the free ones on freelist     */
+/*                 and getting its space from calls to bigchunkalloc.      */
+/*                                                                         */
+/*    CC_PTR_FREE_ROUTINE (type, functionname, freelist)                   */
+/*         Parameters as above.                                            */
+/*         ACTION: Generates a function that adds an object to the         */
+/*                 freelist.                                               */
+/*                                                                         */
+/*    CC_PTR_FREE_LIST_ROUTINE (type, functionname, freefunction)          */
+/*         Parameters defined as above, with freefunction the function     */
+/*         generated by PTR_FREE_ROUTINE.                                  */
+/*         ACTION: Generates a function to free a linked list of           */
+/*                 objects using calls to freefunction.                    */
+/*                                                                         */
+/*    CC_PTR_FREE_WORLD_ROUTINE( type, functionname, chunklist, freelist)  */
+/*         Parameters defined as above.                                    */
+/*         ACTION: Generates a function that returns all of the            */
+/*                 memory used in the PTR_ALLOC_ROUTINE allocations        */
+/*                 back to the global supply of CCbigchunkptrs.            */
+/*                                                                         */
+/*    CC_PTR_LEAKS_ROUTINE (type, name, chunklist, freelist, field,        */
+/*            fieldtype)                                                   */
+/*          As above, with "field" the name of a "fieldtype" field in the  */
+/*          object type that can be set to 0 or to 1.                      */
+/*          ACTION: Generates a function that checks to see that we have   */
+/*                  not leaked any of the objects.                         */
+/*                                                                         */
+/*    CC_PTR_STATUS_ROUTINE (type, name, chunklist, freelist)              */
+/*          ACTION: Like LEAKS, but does not check for duplicates (and so  */
+/*                  does not corrupt the objects).                         */
+/*                                                                         */
+/*  NOTES:                                                                 */
+/*     These routines use the functions in allocrus.c.  The PTR macros     */
+/*  The PTR macros generate the functions for allocating objects for       */
+/*  linked lists. They get their raw memory from the bigchunk supply, so   */
+/*  so foo_free_world (geneated by PTR_FREE_WORLD_ROUTINE) should be       */
+/*  called for each type of linked object "foo" when closing down the      */
+/*  local memory.                                                          */
+/*     To use these functions, put the macros near the top of the file     */
+/*  before any calls to the functions (since the macros also write the     */
+/*  function prototypes). If you use PTR_FREE_LIST_ROUTINE for foo, you    */
+/*  must also use PTR_FREE_ROUTINE, and PTR_FREE_LIST_ROUTINE must be      */
+/*  listed after CC_PTR_FREE_ROUTINE (to get the prototype).               */
+/*                                                                         */
+/***************************************************************************/
+
+
+#define CC_SAFE_MALLOC(nnum,type)                                          \
+    (type *) CCutil_allocrus (((unsigned int) (nnum)) * sizeof (type))
+
+#define CC_FREE(object,type) {                                             \
+    CCutil_freerus ((void *) (object));                                    \
+    object = (type *) NULL;                                                \
+}
+
+#define CC_IFFREE(object,type) {                                           \
+    if ((object)) CC_FREE ((object),type);                                 \
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_ALLOC_ROUTINE(type, functionname)                    \
+static type * functionname (void);                                         \
+static type * functionname (void)
+#else
+#define CC_HEADER_PTR_ALLOC_ROUTINE(type, functionname)                    \
+static type * functionname ();                                             \
+static type * functionname ()
+#endif
+
+#define CC_PTR_ALLOC_ROUTINE(type, functionname, chunklist, freelist)      \
+static  type * freelist = ( type * ) NULL;                                 \
+static  CCbigchunkptr * chunklist = ( CCbigchunkptr * ) NULL;              \
+ CC_HEADER_PTR_ALLOC_ROUTINE (type, functionname)                          \
+{                                                                          \
+    type *p;                                                               \
+                                                                           \
+    if (! freelist ) {                                                     \
+        int count = CC_BIGCHUNK / sizeof ( type );                         \
+        CCbigchunkptr *bp;                                                 \
+                                                                           \
+        bp = CCutil_bigchunkalloc ();                                      \
+        if (!bp) {                                                         \
+            fprintf (stderr, "ptr alloc failed\n");                        \
+            return ( type * ) NULL;                                        \
+        }                                                                  \
+        freelist = ( type * ) bp->this;                                    \
+        bp->next = chunklist ;                                             \
+        chunklist = bp;                                                    \
+                                                                           \
+        for (p = freelist + count - 2; p >= freelist ; p--)                \
+            p->next = p + 1;                                               \
+        freelist [count - 1].next = ( type * ) NULL;                       \
+    }                                                                      \
+    p = freelist ;                                                         \
+    freelist = p->next;                                                    \
+                                                                           \
+    return p;                                                              \
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_FREE_ROUTINE(type, functionname)                     \
+static void functionname ( type *p );                                      \
+static void functionname ( type *p )
+#else
+#define CC_HEADER_PTR_FREE_ROUTINE(type, functionname)                     \
+static void functionname ();                                               \
+static void functionname ( p )                                             \
+type *p;
+#endif
+
+#define CC_PTR_FREE_ROUTINE(type, functionname, freelist)                  \
+ CC_HEADER_PTR_FREE_ROUTINE(type, functionname)                            \
+{                                                                          \
+    p->next = freelist ;                                                   \
+    freelist = p;                                                          \
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_FREE_LIST_ROUTINE(type, functionname)                \
+static void functionname ( type *p );                                      \
+static void functionname ( type *p )
+#else
+#define CC_HEADER_PTR_FREE_LIST_ROUTINE(type, functionname)                \
+static void functionname ();                                               \
+static void functionname ( p )                                             \
+type *p;
+#endif
+
+#define CC_PTR_FREE_LIST_ROUTINE(type, functionname, freefunction)         \
+ CC_HEADER_PTR_FREE_LIST_ROUTINE (type, functionname)                      \
+{                                                                          \
+    type *next;                                                            \
+                                                                           \
+    while (p) {                                                            \
+        next = p->next;                                                    \
+        freefunction (p);                                                  \
+        p = next;                                                          \
+    }                                                                      \
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_FREE_WORLD_ROUTINE(functionname)                     \
+static void functionname (void);                                           \
+static void functionname (void)
+#else
+#define CC_HEADER_PTR_FREE_WORLD_ROUTINE(functionname)                     \
+static void functionname ();                                               \
+static void functionname ()
+#endif
+
+#define CC_PTR_FREE_WORLD_ROUTINE(type, functionname, chunklist, freelist) \
+ CC_HEADER_PTR_FREE_WORLD_ROUTINE(functionname)                            \
+{                                                                          \
+    CCbigchunkptr *bp, *bpnext;                                            \
+                                                                           \
+    for (bp = chunklist ; bp; bp = bpnext) {                               \
+        bpnext = bp->next;                                                 \
+        CCutil_bigchunkfree (bp);                                          \
+    }                                                                      \
+    chunklist = (CCbigchunkptr *) NULL;                                    \
+    freelist = (type *) NULL;                                              \
+}
+
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_LEAKS_ROUTINE(functionname)                          \
+static int functionname (int *total, int *onlist);                         \
+static int functionname (int *total, int *onlist)
+#else
+#define CC_HEADER_PTR_LEAKS_ROUTINE(functionname)                          \
+static int functionname ();                                                \
+static int functionname (total, onlist)                                    \
+int *total, *onlist;
+#endif
+
+#define CC_PTR_LEAKS_ROUTINE(type,name,chunklist,freelist,field,fieldtype) \
+ CC_HEADER_PTR_LEAKS_ROUTINE(name)                                         \
+{                                                                          \
+    int count = CC_BIGCHUNK / sizeof ( type );                             \
+    int duplicates = 0;                                                    \
+    type * p;                                                              \
+    CCbigchunkptr *bp;                                                     \
+                                                                           \
+    *total = 0;                                                            \
+    *onlist = 0;                                                           \
+                                                                           \
+    for (bp = chunklist ; bp; bp = bp->next)                               \
+        (*total) += count;                                                 \
+                                                                           \
+    for (p = freelist ; p; p = p->next) {                                  \
+        (*onlist)++;                                                       \
+        p-> field = ( fieldtype ) 0;                                       \
+    }                                                                      \
+    for (p = freelist ; p; p = p->next) {                                  \
+        if (p-> field == ( fieldtype ) 1)                                  \
+            duplicates++;                                                  \
+        else                                                               \
+            p-> field = ( fieldtype ) 1;                                   \
+    }                                                                      \
+    if (duplicates) {                                                      \
+        fprintf (stderr, "WARNING: %d duplicates on ptr free list \n",     \
+                 duplicates);                                              \
+    }                                                                      \
+    return *total - *onlist;                                               \
+}
+
+#ifdef CC_PROTOTYPE_ANSI
+#define CC_HEADER_PTR_STATUS_ROUTINE(functionname)                         \
+static int functionname (int *total, int *onlist);                         \
+static int functionname (int *total, int *onlist)
+#else
+#define CC_HEADER_PTR_STATUS_ROUTINE(functionname)                         \
+static int functionname ();                                                \
+static int functionname (total, onlist)                                    \
+int *total, *onlist;
+#endif
+
+#define CC_PTR_STATUS_ROUTINE(type, name, chunklist, freelist)             \
+ CC_HEADER_PTR_STATUS_ROUTINE(name)                                        \
+{                                                                          \
+    int count = CC_BIGCHUNK / sizeof ( type );                             \
+    type * p;                                                              \
+    CCbigchunkptr *bp;                                                     \
+                                                                           \
+    *total = 0;                                                            \
+    *onlist = 0;                                                           \
+                                                                           \
+    for (bp = chunklist ; bp; bp = bp->next)                               \
+        (*total) += count;                                                 \
+                                                                           \
+    for (p = freelist ; p; p = p->next)                                    \
+        (*onlist)++;                                                       \
+    return *total - *onlist;                                               \
+}
+
+
+#define CC_BIGCHUNK ((int) ((1<<16)-16))
+
+typedef struct CCbigchunkptr {
+    void                 *this;
+    struct CCbigchunkptr *next;
+} CCbigchunkptr;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+   *CCutil_allocrus (unsigned int size),
+   *CCutil_reallocrus (void *ptr, unsigned int size),
+    CCutil_freerus (void *p),
+    CCutil_bigchunkquery (int *total, int *reserve),
+    CCutil_bigchunkfree (CCbigchunkptr *bp);
+
+int
+    CCutil_reallocrus_scale (void **pptr, int *pnnum, int count, double scale,
+                      unsigned int size),
+    CCutil_reallocrus_count (void **pptr, int count, unsigned int size),
+    CCutil_bigchunk_free_world (void);
+
+CCbigchunkptr
+   *CCutil_bigchunkalloc (void);
+
+#else
+
+void
+   *CCutil_allocrus (),
+   *CCutil_reallocrus (),
+    CCutil_freerus (),
+    CCutil_bigchunkquery (),
+    CCutil_bigchunkfree ();
+
+int
+    CCutil_reallocrus_scale (),
+    CCutil_reallocrus_count (),
+    CCutil_bigchunk_free_world ();
+
+CCbigchunkptr
+    *CCutil_bigchunkalloc ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             bgetopt.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_bix_getopt (int, char **, char *);
+
+#else
+
+int
+    CCutil_bix_getopt ();
+
+#endif
+
+#define CC_BIX_GETOPT_UNKNOWN -3038
+
+extern int CCutil_bix_optind;
+extern char *CCutil_bix_optarg;
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             dheaps_i.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCdheap {
+    double  *key;
+    int     *entry;
+    int     *loc;
+    int     total_space;
+    int     size;
+} CCdheap;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_dheap_free (CCdheap *h),
+    CCutil_dheap_insert (CCdheap *h, int i),
+    CCutil_dheap_delete (CCdheap *h, int i),
+    CCutil_dheap_changekey (CCdheap *h, int i, double newkey);
+int
+    CCutil_dheap_init (CCdheap *h, int k),
+    CCutil_dheap_resize (CCdheap *h, int newsize),
+    CCutil_dheap_findmin (CCdheap *h),
+    CCutil_dheap_deletemin (CCdheap *h);
+
+#else
+
+void
+    CCutil_dheap_free (),
+    CCutil_dheap_insert (),
+    CCutil_dheap_delete (),
+    CCutil_dheap_changekey ();
+int
+    CCutil_dheap_init (),
+    CCutil_dheap_resize (),
+    CCutil_dheap_findmin (),
+    CCutil_dheap_deletemin ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edg2cyc.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_edge_to_cycle (int ncount, int *elist, int *cyc);
+
+#else
+
+int
+    CCutil_edge_to_cycle ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edgelen.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCdatagroup {
+    double  *x;
+    double  *y;
+    double  *z;
+    int    **adj;
+    int      norm;
+} CCdatagroup;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+extern int
+  (*CCutil_dat_edgelen) (int i, int j, CCdatagroup *dat);
+int
+    CCutil_init_dat_edgelen (CCdatagroup *dat),
+    CCutil_max_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_euclid_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_ibm_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_euclid_ceiling_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_euclid3d_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_geographic_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_att_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_dsjrand_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_crystal_edgelen (int i, int j, CCdatagroup *dat),
+    CCutil_matrix_edgelen (int i, int j, CCdatagroup *dat);
+void
+    CCutil_dsjrand_init (int maxdist, int seed),
+    CCutil_freedatagroup (int ncount, CCdatagroup *dat);
+
+#else
+
+extern int
+  (*CCutil_dat_edgelen) ();
+int
+    CCutil_init_dat_edgelen (),
+    CCutil_max_edgelen (),
+    CCutil_euclid_edgelen (),
+    CCutil_ibm_edgelen (),
+    CCutil_euclid_ceiling_edgelen (),
+    CCutil_euclid3d_edgelen (),
+    CCutil_geographic_edgelen (),
+    CCutil_att_edgelen (),
+    CCutil_dsjrand_edgelen (),
+    CCutil_crystal_edgelen (),
+    CCutil_matrix_edgelen ();
+void
+    CCutil_dsjrand_init (),
+    CCutil_freedatagroup ();
+
+#endif
+
+
+#define CC_KD_NORM_TYPE    128            /* Kdtrees work      */
+#define CC_X_NORM_TYPE     256            /* Old nearest works */
+#define CC_JUNK_NORM_TYPE  512            /* Nothing works     */
+
+#define CC_D2_NORM_SIZE      1024         /* x,y coordinates   */
+#define CC_D3_NORM_SIZE      2048         /* x,y,z coordinates */
+#define CC_MATRIX_NORM_SIZE  4096         /* adj matrix        */
+
+#define CC_NORM_BITS      (CC_KD_NORM_TYPE | CC_X_NORM_TYPE | CC_JUNK_NORM_TYPE)
+#define CC_NORM_SIZE_BITS (CC_D2_NORM_SIZE | CC_D3_NORM_SIZE | CC_MATRIX_NORM_SIZE)
+
+#define CC_MAXNORM        (0 |   CC_KD_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_EUCLIDEAN_CEIL (1 |   CC_KD_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_EUCLIDEAN      (2 |   CC_KD_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_EUCLIDEAN_3D   (3 |    CC_X_NORM_TYPE |     CC_D3_NORM_SIZE)
+#define CC_IBM            (4 | CC_JUNK_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_ATT            (5 |    CC_X_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_GEOGRAPHIC     (6 |    CC_X_NORM_TYPE |     CC_D2_NORM_SIZE)
+#define CC_MATRIXNORM     (7 | CC_JUNK_NORM_TYPE | CC_MATRIX_NORM_SIZE)
+#define CC_DSJRANDNORM    (8 | CC_JUNK_NORM_TYPE)
+#define CC_CRYSTAL        (9 |    CC_X_NORM_TYPE |     CC_D3_NORM_SIZE)
+
+#define CC_GEOGRAPHIC_SCALE (6378.388 * 3.14 / 180.0) /*    see edgelen.c   */
+#define CC_ATT_SCALE (.31622)                         /*    sqrt(1/10)      */
+
+/* For X-NORMS, scales are such that |x[i] - x[j]| * scale <= edgelen(i,j). */
+/* Ggeographic is slightly off, since the fractional part of x[i] is really */
+/* really minutes, not fractional degrees.                                  */
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             fastread.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_readint (FILE *);
+
+#else
+
+int
+    CCutil_readint ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             genhash.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCgenhash {
+    int                     nelem;
+    int                     maxelem;
+    int                     size;
+#ifdef CC_PROTOTYPE_ANSI
+    int                   (*hcmp) (void *key1, void *key2, void *u_data);
+    unsigned int          (*hfunc) (void *key, void *u_data);
+#else
+    int                   (*hcmp) ();
+    unsigned int          (*hfunc) ();
+#endif
+    void                   *u_data;
+    double                  maxdensity;
+    double                  lowdensity;
+    struct CCgenhash_elem **table;
+} CCgenhash;
+
+typedef struct CCgenhash_iter {
+    int                    i;
+    struct CCgenhash_elem *next;
+} CCgenhash_iter;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_genhash_init (CCgenhash *h, int size,
+            int (*hcmp) (void *key1, void *key2, void *u_data),
+            unsigned int (*hfunc) (void *key, void *u_data),
+            void *u_data, double maxdensity, double lowdensity),
+    CCutil_genhash_insert (CCgenhash *h, void *key, void *data),
+    CCutil_genhash_insert_h (CCgenhash *h, unsigned int hashval, void *key,
+            void *data),
+    CCutil_genhash_replace (CCgenhash *h, void *key, void *data),
+    CCutil_genhash_replace_h (CCgenhash *h, unsigned int hashval, void *key,
+                       void *data),
+    CCutil_genhash_delete (CCgenhash *h, void *key),
+    CCutil_genhash_delete_h (CCgenhash *h, unsigned int hashval, void *key);
+
+unsigned int
+    CCutil_genhash_hash (CCgenhash *h, void *key);
+
+void
+   *CCutil_genhash_lookup (CCgenhash *h, void *key),
+   *CCutil_genhash_lookup_h (CCgenhash *h, unsigned int hashval, void *key),
+   *CCutil_genhash_next (CCgenhash *h, CCgenhash_iter *iter, void **key,
+            int *keysize);
+
+void
+    CCutil_genhash_u_data (CCgenhash *h, void *u_data),
+    CCutil_genhash_free (CCgenhash *h, void (*freefunc)(void *key, void *data,
+            void *u_data)),
+    CCutil_genhash_start (CCgenhash *h, CCgenhash_iter *iter);
+
+#else
+
+int
+    CCutil_genhash_init (),
+    CCutil_genhash_insert (),
+    CCutil_genhash_insert_h (),
+    CCutil_genhash_replace (),
+    CCutil_genhash_replace_h (),
+    CCutil_genhash_delete (),
+    CCutil_genhash_delete_h ();
+
+unsigned int
+    CCutil_genhash_hash ();
+
+void
+   *CCutil_genhash_lookup (),
+   *CCutil_genhash_lookup_h (),
+   *CCutil_genhash_next ();
+
+void
+    CCutil_genhash_u_data (),
+    CCutil_genhash_free (),
+    CCutil_genhash_start ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             getdata.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#define CC_MASTER_NO_DAT  100
+#define CC_MASTER_DAT     101
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCutil_getdata (char *datname, int binary_in, int innorm, int *ncount,
+            CCdatagroup *dat),
+    CCutil_writemaster (char *mastername, int ncount, CCdatagroup *dat,
+            int *perm),
+    CCutil_getmaster (char *mastername, int *ncount, CCdatagroup *dat,
+            int **perm),
+    CCutil_getnodeweights (char *weightname, int ncount, int weight_limit,
+            double **wcoord),
+    CCutil_gettsplib (char *datname, int *ncount, CCdatagroup *dat),
+    CCutil_datagroup_perm (int ncount, CCdatagroup *dat, int *perm),
+    CCutil_getedgelist (int ncount, char *fname, int *ecount, int **elist,
+            int **elen),
+    CCutil_getedgelist_n (int *ncount, char *fname, int *ecount, int **elist,
+            int **elen),
+    CCutil_getcycle_edgelist (int ncount, char *cyclename, int *outcycle),
+    CCutil_getcycle (int ncount, char *cyclename, int *outcycle),
+    CCutil_getedges_double (int *ncount, char *fname, int *ecount, int **elist,
+            double **elen, int binary_in),
+    CCutil_writeedges (int ncount, char *outedgename, int ecount, int *elist,
+            CCdatagroup *dat),
+    CCutil_writecycle_edgelist (int ncount, char *outedgename, int *cycle,
+            CCdatagroup *dat),
+    CCutil_writecycle (int ncount, char *outcyclename, int *cycle),
+    CCutil_writeedges_double (int ncount, char *outedgename, int ecount,
+            int *elist, double *elen, int binary_out);
+
+#else
+
+int
+    CCutil_getdata (),
+    CCutil_writemaster (),
+    CCutil_getmaster (),
+    CCutil_getnodeweights (),
+    CCutil_gettsplib (),
+    CCutil_datagroup_perm (),
+    CCutil_getedgelist (),
+    CCutil_getedgelist_n (),
+    CCutil_getcycle_edgelist (),
+    CCutil_getcycle (),
+    CCutil_getedges_double (),
+    CCutil_writeedges (),
+    CCutil_writecycle_edgelist (),
+    CCutil_writecycle (),
+    CCutil_writeedges_double ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             priority.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCpriority {
+    CCdheap   heap;
+    union pri_data {
+        void *data;
+        int  next;
+    }        *pri_info;
+    int       space;
+    int       freelist;
+} CCpriority;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_priority_free (CCpriority *pri),
+    CCutil_priority_delete (CCpriority *pri, int handle),
+    CCutil_priority_changekey (CCpriority *pri, int handle, double newkey),
+   *CCutil_priority_findmin (CCpriority *pri, double *keyval),
+   *CCutil_priority_deletemin (CCpriority *pri, double *keyval);
+
+int
+    CCutil_priority_init (CCpriority *pri, int k),
+    CCutil_priority_insert (CCpriority *pri, void *data, double keyval);
+
+#else
+
+void
+    CCutil_priority_free (),
+    CCutil_priority_delete (),
+    CCutil_priority_changekey (),
+   *CCutil_priority_findmin (),
+   *CCutil_priority_deletemin ();
+
+int
+    CCutil_priority_init (),
+    CCutil_priority_insert ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             safe_io.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#define CC_SBUFFER_SIZE (4000)
+#define CC_SFNAME_SIZE (32)
+
+typedef struct CC_SFILE {
+    int           status;
+    int           desc;
+    int           chars_in_buffer;
+    int           current_buffer_char;     /* only used for reading */
+    int           bits_in_last_char;       /* writing: number of empty bits in
+                                            * buffer[chars_in_buffer];
+                                            * reading: number of full bits in
+                                            * buffer[?] */
+    int           pos;
+    char          fname[CC_SFNAME_SIZE];
+    unsigned char buffer[CC_SBUFFER_SIZE];
+} CC_SFILE;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+CC_SFILE
+   *CCutil_sopen (char *f, char *s),
+   *CCutil_sdopen (int d, char *s);
+
+int
+    CCutil_swrite (CC_SFILE *f, unsigned char *buf, int size),
+    CCutil_swrite_bits (CC_SFILE *f, unsigned int x, int xbits),
+    CCutil_swrite_char (CC_SFILE *f, unsigned char x),
+    CCutil_swrite_string (CC_SFILE *f, unsigned char *x),
+    CCutil_swrite_short (CC_SFILE *f, unsigned short x),
+    CCutil_swrite_int (CC_SFILE *f, unsigned int x),
+    CCutil_swrite_double (CC_SFILE *f, double x),
+    CCutil_sread (CC_SFILE *f, unsigned char *buf, int size),
+    CCutil_sread_bits (CC_SFILE *f, unsigned int *x, int xbits),
+    CCutil_sread_char (CC_SFILE *f, unsigned char *x),
+    CCutil_sread_string (CC_SFILE *f, unsigned char *x, int maxlen),
+    CCutil_sread_short (CC_SFILE *f, unsigned short *x),
+    CCutil_sread_short_r (CC_SFILE *f, unsigned short *x),
+    CCutil_sread_int (CC_SFILE *f, unsigned int *x),
+    CCutil_sread_int_r (CC_SFILE *f, unsigned int *x),
+    CCutil_sread_double (CC_SFILE *f, double *x),
+    CCutil_sread_double_r (CC_SFILE *f, double *x),
+    CCutil_sflush (CC_SFILE *f),
+    CCutil_stell (CC_SFILE *f),
+    CCutil_sseek (CC_SFILE *f, int offset),
+    CCutil_srewind (CC_SFILE *f),
+    CCutil_sclose (CC_SFILE *f),
+    CCutil_sbits (unsigned int x),
+    CCutil_sdelete_file (char *fname),
+    CCutil_sdelete_file_backup (char *fname);
+
+#else
+
+CC_SFILE
+   *CCutil_sopen (),
+   *CCutil_sdopen ();
+
+int
+    CCutil_swrite (),
+    CCutil_swrite_bits (),
+    CCutil_swrite_char (),
+    CCutil_swrite_string (),
+    CCutil_swrite_short (),
+    CCutil_swrite_int (),
+    CCutil_swrite_double (),
+    CCutil_sread (),
+    CCutil_sread_bits (),
+    CCutil_sread_char (),
+    CCutil_sread_string (),
+    CCutil_sread_short (),
+    CCutil_sread_short_r (),
+    CCutil_sread_int (),
+    CCutil_sread_int_r (),
+    CCutil_sread_double (),
+    CCutil_sread_double_r (),
+    CCutil_sflush (),
+    CCutil_stell (),
+    CCutil_sseek (),
+    CCutil_srewind (),
+    CCutil_sclose (),
+    CCutil_sbits (),
+    CCutil_sdelete_file (),
+    CCutil_sdelete_file_backup ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             sortrus.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_int_array_quicksort (int *len, int n),
+    CCutil_int_perm_quicksort (int *perm, int *len, int n),
+    CCutil_double_perm_quicksort (int *perm, double *len, int n),
+    CCutil_rselect (int *arr, int l, int r, int m, double *coord);
+
+char
+   *CCutil_linked_radixsort (char *data, char *datanext, char *dataval,
+            int valsize);
+
+#else
+
+void
+    CCutil_int_array_quicksort (),
+    CCutil_int_perm_quicksort (),
+    CCutil_double_perm_quicksort (),
+    CCutil_rselect ();
+
+char
+   *CCutil_linked_radixsort ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             urandom.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCutil_sprand (int);
+int
+    CCutil_lprand (void);
+
+#else
+
+void
+    CCutil_sprand ();
+int
+    CCutil_lprand ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             util.c                                      */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+char
+   *CCutil_strrchr (char *s, int c);
+
+unsigned int
+    CCutil_nextprime (unsigned int x);
+
+int
+    CCutil_our_gcd (int a, int b);
+
+#else
+
+char
+   *CCutil_strrchr ();
+
+unsigned int
+    CCutil_nextprime ();
+
+int
+    CCutil_our_gcd ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             zeit.c                                      */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+double
+    CCutil_zeit (void),
+    CCutil_real_zeit (void);
+
+#else
+
+double
+    CCutil_zeit (),
+    CCutil_real_zeit ();
+
+#endif
+
+
+#endif /* __UTIL_H */
+#ifndef  __BIGGUY_H
+#define  __BIGGUY_H
+
+
+#ifdef  CC_BIGGUY_LONGLONG
+
+typedef long long CCbigguy;
+
+#define CCbigguy_FRACBITS 32
+#define CCbigguy_DUALSCALE (((CCbigguy) 1) << CCbigguy_FRACBITS)
+#define CCbigguy_FRACPART(x) ((x) & (CCbigguy_DUALSCALE-1))
+#define CCbigguy_MAXBIGGUY (((((CCbigguy) 1) << 62) - 1) + \
+                            (((CCbigguy) 1) << 62))
+#define CCbigguy_MINBIGGUY (-CCbigguy_MAXBIGGUY)
+#define CCbigguy_bigguytod(x) (((double) (x)) / ((double) CCbigguy_DUALSCALE))
+#define CCbigguy_itobigguy(d) ((CCbigguy) ((d) * (double) CCbigguy_DUALSCALE))
+#define CCbigguy_ceil(x) (CCbigguy_FRACPART(x) ? \
+        ((x) + (CCbigguy_DUALSCALE - CCbigguy_FRACPART(x))) : (x))
+#define CCbigguy_cmp(x,y) (((x) < (y)) ? -1 : ((x) > (y)) ? 1 : 0)
+#define CCbigguy_ZERO ((CCbigguy) 0)
+#define CCbigguy_ONE ((CCbigguy) CCbigguy_DUALSCALE)
+#define CCbigguy_addmult(x,y,m) ((*x) += (y)*(m))
+#define CCbigguy_dtobigguy(d) ((CCbigguy) ((d) * (double) CCbigguy_DUALSCALE))
+
+#else /* CC_BIGGUY_LONGLONG */
+
+typedef struct CCbigguy {
+    unsigned short ihi;
+    unsigned short ilo;
+    unsigned short fhi;
+    unsigned short flo;
+} CCbigguy;
+
+extern const CCbigguy CCbigguy_MINBIGGUY;
+extern const CCbigguy CCbigguy_MAXBIGGUY;
+extern const CCbigguy CCbigguy_ZERO;
+extern const CCbigguy CCbigguy_ONE;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+    void
+        CCbigguy_addmult (CCbigguy *x, CCbigguy y, short m);
+
+    int
+        CCbigguy_cmp (CCbigguy x, CCbigguy y);
+
+    double
+        CCbigguy_bigguytod (CCbigguy x);
+
+    CCbigguy
+        CCbigguy_itobigguy (int d),
+        CCbigguy_dtobigguy (double d),
+        CCbigguy_ceil (CCbigguy x);
+
+#else
+
+    void
+        CCbigguy_addmult ();
+
+    int
+        CCbigguy_cmp ();
+
+    double
+        CCbigguy_bigguytod ();
+
+    CCbigguy
+        CCbigguy_itobigguy (),
+        CCbigguy_dtobigguy (),
+        CCbigguy_ceil ();
+
+#endif
+
+#endif /* CC_BIGGUY_LONGLONG */
+
+#define CCbigguy_add(x,y) (CCbigguy_addmult(x,y,1))
+#define CCbigguy_sub(x,y) (CCbigguy_addmult(x,y,-1))
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCbigguy_swrite (CC_SFILE *f, CCbigguy x),
+    CCbigguy_sread (CC_SFILE *f, CCbigguy *x);
+
+#else
+
+int
+    CCbigguy_swrite (),
+    CCbigguy_sread ();
+
+#endif
+
+#endif /* __BIGGUY_H */
+#ifndef __LP_H
+#define __LP_H
+
+#define  CClp_METHOD_DUAL    1
+#define  CClp_METHOD_BARRIER 2
+
+#define  CClp_SUCCESS        0
+#define  CClp_FAILURE        1
+#define  CClp_UNBOUNDED      2
+#define  CClp_INFEASIBLE     3
+#define  CClp_UNKNOWN        4
+
+typedef struct CClp {
+    struct cpxenv *cplex_env;
+    struct cpxlp  *cplex_lp;
+    int            lp_allocated;
+} CClp;
+
+typedef struct CClpbasis {
+    int       *rstat;
+    int       *cstat;
+    double    *dnorm;
+} CClpbasis;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CClp_init (CClp *lp),
+    CClp_loadlp (CClp *lp, char *name, int ncols, int nrows, int objsense,
+            double *obj, double *rhs, char *sense, int *matbeg, int *matcnt,
+            int *matind, double *matval, double *lb, double *ub),
+    CClp_opt (CClp *lp, int method),
+    CClp_dualopt (CClp *lp),
+    CClp_limited_dualopt (CClp *lp, int lim, int *status, double *upperbound),
+    CClp_primalopt (CClp *lp),
+    CClp_addrows (CClp *lp, int newrows, int newnz, double *rhs, char *sense,
+            int *rmatbeg, int *rmatind, double *rmatval),
+    CClp_addcols (CClp *lp, int newcols, int newnz, double *obj,
+            int *cmatbeg, int *cmatind, double *cmatval, double *lb,
+            double *ub),
+    CClp_delete_row (CClp *lp, int i),
+    CClp_delete_set_of_rows (CClp *lp, int *delstat),
+    CClp_delete_column (CClp *lp, int i),
+    CClp_delete_set_of_columns (CClp *lp, int *delstat),
+    CClp_setbnd (CClp *lp, int col, char lower_or_upper, double bnd),
+    CClp_get_basis_and_norms (CClp *lp, CClpbasis *b),
+    CClp_load_basis_and_norms (CClp *lp, CClpbasis *b),
+    CClp_basis (CClp *lp, int *cstat, int *rstat),
+    CClp_loadbasis (CClp *lp, int *cstat, int *rstat),
+    CClp_getbasis_and_norms (CClp *lp, int *cstat, int *rstat,
+            double *dnorm),
+    CClp_loadbasis_and_norms (CClp *lp, int *cstat, int *rstat,
+                              double *dnorm),
+    CClp_x (CClp *lp, double *x),
+    CClp_rc (CClp *lp, double *rc),
+    CClp_pi_range (CClp *lp, double *pi, int from, int to),
+    CClp_objval (CClp *lp, double *obj),
+    CClp_nonzeros (CClp *lp),
+    CClp_status (CClp *lp, int *status),
+    CClp_getweight (CClp *lp, int nrows, int *rmatbeg, int *rmatind,
+            double *rmatval, double *weight),
+    CClp_dump_lp (CClp *lp, char *fname),
+    CClp_getgoodlist (CClp *lp, int *goodlist, int *goodlen_p,
+            double *downpen, double *uppen),
+    CClp_strongbranch (CClp *lp, int *candidatelist, int ncand,
+            double *downpen, double *uppen, int iterations,
+            double *upperbound),
+    CClp_getfarkasmultipliers (CClp *lp, double *y);
+
+void
+    CClp_init_struct (CClp *lp),
+    CClp_free (CClp *lp),
+    CClp_init_basis (CClpbasis *b),
+    CClp_free_basis (CClpbasis *b),
+    CClp_pivotin (CClp *lp, int i);
+
+#else
+
+int
+    CClp_init (),
+    CClp_loadlp (),
+    CClp_opt (),
+    CClp_dualopt (),
+    CClp_limited_dualopt (),
+    CClp_primalopt (),
+    CClp_addrows (),
+    CClp_addcols (),
+    CClp_delete_row (),
+    CClp_delete_set_of_rows (),
+    CClp_delete_column (),
+    CClp_delete_set_of_columns (),
+    CClp_setbnd (),
+    CClp_get_basis_and_norms (),
+    CClp_load_basis_and_norms (),
+    CClp_basis (),
+    CClp_loadbasis (),
+    CClp_getbasis_and_norms (),
+    CClp_loadbasis_and_norms (),
+    CClp_x (),
+    CClp_rc (),
+    CClp_pi_range (),
+    CClp_objval (),
+    CClp_nonzeros (),
+    CClp_status (),
+    CClp_getweight (),
+    CClp_dump_lp (),
+    CClp_getgoodlist (),
+    CClp_strongbranch (),
+    CClp_getfarkasmultipliers ();
+
+void
+    CClp_init_struct (),
+    CClp_free (),
+    CClp_init_basis (),
+    CClp_free_basis (),
+    CClp_pivotin ();
+
+#endif
+
+
+#endif  /* __LP_H */
+#ifndef __KDTREE_H
+#define __KDTREE_H
+
+
+typedef struct CCkdnode {
+    double           cutval;
+    struct CCkdnode *loson;
+    struct CCkdnode *hison;
+    struct CCkdnode *father;
+    struct CCkdnode *next;
+    struct CCkdbnds *bnds;
+    int              lopt;
+    int              hipt;
+    char             bucket;
+    char             empty;
+    char             cutdim;
+} CCkdnode;
+
+typedef struct CCkdtree {
+    CCkdnode  *root;
+    CCkdnode **bucketptr;
+    int       *perm;
+} CCkdtree;
+
+typedef struct CCkdbnds {
+    double           x[2];
+    double           y[2];
+    struct CCkdbnds *next;
+} CCkdbnds;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCkdtree_free (CCkdtree *kt),
+    CCkdtree_delete (CCkdtree *kt, int k),
+    CCkdtree_delete_all (CCkdtree *kt, int ncount),
+    CCkdtree_undelete (CCkdtree *kt, int k),
+    CCkdtree_undelete_all (CCkdtree *kt, int ncount);
+int
+    CCkdtree_build (CCkdtree *kt, int ncount, CCdatagroup *dat, double *wcoord),
+    CCkdtree_k_nearest (CCkdtree *kt, int ncount, int k, CCdatagroup *dat,
+            double *wcoord, int wantlist, int *ocount, int **olist),
+    CCkdtree_quadrant_k_nearest (CCkdtree *kt, int ncount, int k,
+            CCdatagroup *dat, double *wcoord, int wantlist, int *ocount,
+            int **olist),
+    CCkdtree_node_k_nearest (CCkdtree *kt, int ncount, int n, int k,
+            CCdatagroup *dat, double *wcoord, int *list),
+    CCkdtree_node_quadrant_k_nearest (CCkdtree *kt, int ncount, int n, int k,
+            CCdatagroup *dat, double *wcoord, int *list),
+    CCkdtree_node_nearest (CCkdtree *kt, int n, CCdatagroup *dat,
+            double *wcoord),
+    CCkdtree_fixed_radius_nearest (CCkdtree *kt, CCdatagroup *dat,
+            double *wcoord, int n, double rad,
+            int (*doit_fn) (int, int, void *), void *pass_param),
+    CCkdtree_nearest_neighbor_tour (CCkdtree *kt, int ncount, int start,
+            CCdatagroup *dat, int *outcycle, double *val),
+    CCkdtree_nearest_neighbor_2match (CCkdtree *kt, int ncount, int start,
+            CCdatagroup *dat, int *outmatch, double *val),
+    CCkdtree_prim_spanningtree (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            double *wcoord, int *outtree, double *val),
+    CCkdtree_greedy_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *outcycle, double *val),
+    CCkdtree_far_add_tour (CCkdtree *kt, int ncount, int start,
+            CCdatagroup *dat, int *outcycle, double *val),
+    CCkdtree_qboruvka_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *outcycle, double *val),
+    CCkdtree_boruvka_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *outcycle, double *val),
+    CCkdtree_twoopt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *incycle, int *outcycle, double *val,
+            int in_run_two_and_a_half_opt, int run_silently),
+    CCkdtree_3opt_tour (CCkdtree *kt, int ncount, CCdatagroup *dat,
+            int *incycle, int *outcycle, double *val, int run_silently);
+
+#else
+
+void
+    CCkdtree_free (),
+    CCkdtree_delete (),
+    CCkdtree_delete_all (),
+    CCkdtree_undelete (),
+    CCkdtree_undelete_all ();
+int
+    CCkdtree_build (),
+    CCkdtree_k_nearest (),
+    CCkdtree_quadrant_k_nearest (),
+    CCkdtree_node_k_nearest (),
+    CCkdtree_node_quadrant_k_nearest (),
+    CCkdtree_node_nearest (),
+    CCkdtree_fixed_radius_nearest (),
+    CCkdtree_nearest_neighbor_tour (),
+    CCkdtree_nearest_neighbor_2match (),
+    CCkdtree_prim_spanningtree (),
+    CCkdtree_greedy_tour (),
+    CCkdtree_far_add_tour (),
+    CCkdtree_qboruvka_tour (),
+    CCkdtree_boruvka_tour (),
+    CCkdtree_twoopt_tour (),
+    CCkdtree_3opt_tour ();
+#endif
+
+#endif  /* __KDTREE_H */
+
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN CUT                        */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+
+#ifndef  __CUT_H
+#define  __CUT_H
+
+
+#define CC_MINCUT_BIGDOUBLE   (100000000000.0)
+#define CC_MINCUT_ONE_EPSILON (0.000001)
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCcut_mincut (int ncount, int ecount, int *elist, double *dlen,
+            double *valval, int **cut, int *cutcount),
+    CCcut_violated_cuts (int ncount, int ecount, int *elist, double *dlen,
+            double cutoff, int (*doit_fn) (double, int, int *, void *),
+            void *pass_param),
+    CCcut_mincut_st (int ncount, int ecount, int *elist, double *ecap,
+            int s, int t, double *value, int **cut, int *cutcount),
+    CCcut_linsub (int ncount, int ecount, int *elist, double *x, double cutoff,
+        int (*doit_fn) (double, int, int, void *), void *pass_param),
+    CCcut_connect_components (int ncount, int ecount, int *elist, double *x,
+        int *ncomp, int **compscount, int **comps);
+
+#else
+
+int
+    CCcut_mincut (),
+    CCcut_violated_cuts (),
+    CCcut_mincut_st (),
+    CCcut_linsub (),
+    CCcut_connect_components ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             shrink.c                                    */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CC_SRKnode {
+    struct CC_SRKedge *adj;
+    struct CC_SRKnode *next;
+    struct CC_SRKnode *prev;
+    struct CC_SRKnode *members;
+    struct CC_SRKnode *parent;
+    struct CC_SRKnode *qnext;
+    double             prweight;
+    double             weight;
+    int                num;
+    int                newnum;
+    int                onecnt;
+    int                onqueue;
+} CC_SRKnode;
+
+typedef struct CC_SRKedge {
+    struct CC_SRKnode *end;
+    struct CC_SRKedge *other;
+    struct CC_SRKedge *next;
+    struct CC_SRKedge *prev;
+    double             weight;
+} CC_SRKedge;
+
+typedef struct CC_SRKgraph {
+    struct CC_SRKnode  *nodespace;
+    struct CC_SRKedge  *edgespace;
+    struct CC_SRKnode  *head;
+    struct CC_SRKedge **hit;
+    int                 original_ncount;
+    int                 original_ecount;
+} CC_SRKgraph;
+
+typedef struct CC_SRKexpinfo {
+    int *members;
+    int *memindex;
+} CC_SRKexpinfo;
+
+typedef struct CC_SRKcallback {
+    double  cutoff;
+    void   *pass_param;
+#ifdef CC_PROTOTYPE_ANSI
+    int   (*doit_fn) (double, int, int *, void *);
+#else
+    int   (*doit_fn) ();
+#endif
+} CC_SRKcallback;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCcut_SRK_identify_paths (CC_SRKgraph *G, int *newcount, int onecnt_okay),
+    CCcut_SRK_identify_paths_to_edges (CC_SRKgraph *G, int *newcount,
+        int onecnt_okay),
+    CCcut_SRK_identify_ones (CC_SRKgraph *G, int *count, double epsilon),
+    CCcut_SRK_identify_one_triangles (CC_SRKgraph *G, int *count,
+        CC_SRKnode *qstart, double epsilon),
+    CCcut_SRK_identify_nodes (CC_SRKgraph *G, CC_SRKnode *n, CC_SRKnode *m),
+    CCcut_SRK_init_graph (CC_SRKgraph *G),
+    CCcut_SRK_free_graph (CC_SRKgraph *G),
+    CCcut_SRK_init_expinfo (CC_SRKexpinfo *expand),
+    CCcut_SRK_free_expinfo (CC_SRKexpinfo *expand),
+    CCcut_SRK_init_callback (CC_SRKcallback *cb);
+
+int
+    CCcut_SRK_buildgraph (CC_SRKgraph *G, int ncount, int ecount, int *elist,
+        double *dlen),
+    CCcut_SRK_subtour_shrink (CC_SRKgraph *G, double *minval, double epsilon,
+        CC_SRKcallback *cb, int **cut, int *cutcount),
+    CCcut_SRK_identify_pr_edges (CC_SRKgraph *G, double *minval, int *count,
+        CC_SRKnode *qstart, double epsilon, CC_SRKcallback *cb, int **cut,
+        int *cutcount),
+    CCcut_SRK_defluff (CC_SRKgraph *G),
+    CCcut_SRK_grab_edges (CC_SRKgraph *G, int *oncount, int *oecount,
+        int **olist, double **olen, CC_SRKexpinfo *expand),
+    CCcut_SRK_grab_nodes (CC_SRKgraph *G, CC_SRKexpinfo *expand),
+    CCcut_SRK_trivial (int ncount, CC_SRKexpinfo *expand),
+    CCcut_SRK_expand (CC_SRKexpinfo *expand, int *arr, int size, int **pnewarr,
+        int *pnewsize);
+
+#else
+
+void
+    CCcut_SRK_identify_paths (),
+    CCcut_SRK_identify_paths_to_edges (),
+    CCcut_SRK_identify_ones (),
+    CCcut_SRK_identify_one_triangles (),
+    CCcut_SRK_identify_nodes (),
+    CCcut_SRK_init_graph (),
+    CCcut_SRK_free_graph (),
+    CCcut_SRK_init_expinfo (),
+    CCcut_SRK_free_expinfo (),
+    CCcut_SRK_init_callback ();
+
+int
+    CCcut_SRK_buildgraph (),
+    CCcut_SRK_subtour_shrink (),
+    CCcut_SRK_identify_pr_edges (),
+    CCcut_SRK_defluff (),
+    CCcut_SRK_grab_edges (),
+    CCcut_SRK_grab_nodes (),
+    CCcut_SRK_trivial (),
+    CCcut_SRK_expand ();
+
+#endif
+
+#endif  /* __CUT_H */
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN EDGEGEN                    */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+#ifndef __EDGEGEN_H
+#define __EDGEGEN_H
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edgegen.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCedgegengroup {
+    struct {
+        int count;
+        int quadnearest;
+        int nearest;
+        int nearest_start;
+        int greedy_start;
+        int random_start;
+        int nkicks;
+    } linkern;
+
+    struct {
+        int twoopt_count;
+        int twoopt5_count;
+        int threeopt_count;
+        int greedy;
+        int nearest_count;
+        int random_count;
+    } tour;
+
+    struct {
+        int wantit;
+        int basic;
+        int priced;
+    } f2match;
+
+    struct {
+        int number;
+        int basic;
+        int priced;
+    } f2match_nearest;
+
+    int    nearest;
+    int    quadnearest;
+    int    want_tree;
+    int    nearest_twomatch_count;
+    int    delaunay;
+    int    mlinkern;
+} CCedgegengroup;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCedgegen_read (char *egname, CCedgegengroup *plan),
+    CCedgegen_edges (CCedgegengroup *plan, int ncount, CCdatagroup *dat,
+        double *wcoord, int *ecount, int **elist);
+void
+    CCedgegen_init_edgegengroup (CCedgegengroup *plan);
+
+#else
+
+int
+    CCedgegen_read (),
+    CCedgegen_edges ();
+void
+    CCedgegen_init_edgegengroup ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             xnear.c                                     */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCxnear {
+    struct CCdatagroup  dat;
+    double             *w;
+    int                *nodenames;
+    int                *invnames;
+} CCxnear;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCedgegen_x_k_nearest (int ncount, int num, CCdatagroup *dat,
+        double *wcoord, int wantlist, int *ecount, int **elist),
+    CCedgegen_x_quadrant_k_nearest (int ncount, int num, CCdatagroup *dat,
+        double *wcoord, int wantlist, int *ecount, int **elist),
+    CCedgegen_x_node_k_nearest (CCxnear *xn, int n, int nearnum, int ncount,
+        int *list),
+    CCedgegen_x_node_quadrant_k_nearest (CCxnear *xn, int n, int nearnum,
+        int ncount, int *list),
+    CCedgegen_x_node_nearest (CCxnear *xn, int ncount, int ni, char *marks),
+    CCedgegen_x_nearest_neighbor_tour (int ncount, int start, CCdatagroup *dat,
+        int *outcycle, double *val),
+    CCedgegen_junk_k_nearest (int ncount, int num, CCdatagroup *dat,
+        double *wcoord, int wantlist, int *ecount, int **elist),
+    CCedgegen_junk_node_k_nearest (CCdatagroup *dat, double *wcoord, int n,
+        int nearnum, int ncount, int *list),
+    CCedgegen_junk_node_nearest (CCdatagroup *dat, double *wcoord, int ncount,
+        int n, char *marks),
+    CCedgegen_junk_nearest_neighbor_tour (int ncount, int start,
+        CCdatagroup *dat, int *outcycle, double *val),
+    CCedgegen_xnear_build (int ncount, CCdatagroup *dat, double *wcoord,
+        CCxnear *xn);
+
+void
+    CCedgegen_xnear_free (int ncount, CCxnear *xn);
+
+#else
+
+int
+    CCedgegen_x_k_nearest (),
+    CCedgegen_x_quadrant_k_nearest (),
+    CCedgegen_x_node_k_nearest (),
+    CCedgegen_x_node_quadrant_k_nearest (),
+    CCedgegen_x_node_nearest (),
+    CCedgegen_x_nearest_neighbor_tour (),
+    CCedgegen_junk_k_nearest (),
+    CCedgegen_junk_node_k_nearest (),
+    CCedgegen_junk_node_nearest (),
+    CCedgegen_junk_nearest_neighbor_tour (),
+    CCedgegen_xnear_build ();
+void
+    CCedgegen_xnear_free ();
+
+#endif
+
+#endif  /* __EDGEGEN_H */
+/***************************************************************************/
+/***************************************************************************/
+/*                                                                         */
+/*                      PROTOTYPES FOR FILES IN CUT                        */
+/*                                                                         */
+/***************************************************************************/
+/***************************************************************************/
+
+
+#ifndef __TSP_H
+#define __TSP_H
+
+
+/*************** Tolerances for the LP and Cutting routines ***************/
+
+#define CCtsp_MIN_VIOL (0.00001)   /* min violation for cut to be added to lp */
+#define CCtsp_CUTS_NEXT_TOL (0.0001)       /* to try next level  */
+#define CCtsp_CUTS_NEXT_ROUND (0.00000001) /* if improve is less, stop round */
+#define CCtsp_PRICE_RCTHRESH  (-0.00001)   /* to add a bad edge */
+#define CCtsp_PRICE_MAXPENALTY (0.49)      /* penalty permitted in addbad */
+#define CCtsp_PHASE1_RCTHRESH (-0.000000001)
+#define CCtsp_PHASE1_MAXPENALTY (0.00000001)
+#define CCtsp_EDGE_LIFE (1000000) /* 200 */  /* Large for subtour runs */
+#define CCtsp_CUT_LIFE  (50)
+#define CCtsp_CUT_BATCH (250)     /* number of new cuts before lp optimize */
+#define CCtsp_STORE_BATCH (50)    /* number of new cuts before lp addrows  */
+#define CCtsp_INTTOL (0.0001)     /* used to check if lp soln is integral  */
+
+/************************** Branching Strategies  ************************/
+
+#define CCtsp_BRANCH_MIDDLE 1
+#define CCtsp_BRANCH_STRONG 2
+
+/*************************************************************************/
+
+#define CCtsp_LP_MAXDOUBLE  1e30
+
+#define CCtsp_CUTRHS(c) (3*(c)->cliquecount - (c)->handlecount - 1)
+
+typedef struct CCtsp_lpnode {
+    int                 deg;
+    int                 mark;
+    struct CCtsp_lpadj *adj;
+} CCtsp_lpnode;
+
+typedef struct CCtsp_lpedge {
+    int ends[2];   /* ends[0] should always be < ends[1] */
+    int fixed;
+    int branch;    /* < 0 means set to 0 and > 0 means set to 1 */
+    int len;
+    int age;
+    int coef;      /* should be maintained at zero */
+    int coefnext;  /* should be maintained at -2 */
+} CCtsp_lpedge;
+
+typedef struct CCtsp_lpadj {
+    int to;
+    int edge;
+} CCtsp_lpadj;
+
+typedef struct CCtsp_lpgraph {
+    int           ncount;
+    int           espace;
+    int           ecount;
+    int           nodemarker;
+    CCtsp_lpnode *nodes;
+    CCtsp_lpedge *edges;
+    CCtsp_lpadj  *adjspace;
+    int           adjstart;
+    int           adjend;
+} CCtsp_lpgraph;
+
+typedef struct CCtsp_predge {
+    int    ends[2];
+    int    len;
+    double rc;
+} CCtsp_predge;
+
+typedef struct CCtsp_pricegroup {
+    int                    ncount;
+    int                    espace;
+    int                    ecount;
+    CCtsp_lpnode          *nodes;
+    CCtsp_predge          *edges;
+    int                    cliquecount;
+    struct CCtsp_lpclique *cliques; /* just a copy of the pointer */
+    CCtsp_lpgraph         *graph;   /* pointer to the copy in a CCtsp_lp */
+    CCtsp_lpadj           *adjspace;
+    double                *node_pi;
+    double                *clique_pi;
+    double                 penalty;
+} CCtsp_pricegroup;
+
+typedef struct CCtsp_extraedge {
+    int ends[2];
+} CCtsp_extraedge;
+
+typedef struct CCtsp_sparser {
+    unsigned int node : 24;
+    unsigned int mult : 8;
+} CCtsp_sparser;
+
+typedef struct CCtsp_segment {
+    int lo;
+    int hi;
+} CCtsp_segment;
+
+typedef struct CCtsp_lpclique {
+    int                   segcount;
+    struct CCtsp_segment *nodes;
+    int                   hashnext;
+    int                   refcount;
+} CCtsp_lpclique;
+
+#define CC_FOREACH_NODE_IN_CLIQUE(i,c,tmp) \
+    for(tmp=0;tmp<(c).segcount;tmp++) \
+        for(i=(c).nodes[tmp].lo;i<=(c).nodes[tmp].hi;i++)
+
+#define CCtsp_NEWCUT_AGE (-1)
+
+typedef struct CCtsp_lpcut {
+    int                   handlecount;
+    int                   cliquecount;
+    int                   modcount;
+    int                   age;
+    int                   rhs;
+    char                  sense;
+    char                  branch;
+    int                  *cliques;
+    struct CCtsp_sparser *mods;
+} CCtsp_lpcut;
+
+typedef struct CCtsp_lpcut_in {
+    int                    handlecount;
+    int                    cliquecount;
+    int                    rhs;
+    char                   sense;
+    char                   branch;
+    CCtsp_lpclique        *cliques;
+    struct CCtsp_lpcut_in *next;
+    struct CCtsp_lpcut_in *prev;
+} CCtsp_lpcut_in;
+
+typedef struct CCtsp_lp_result {
+    double         ub;
+    double         lb;
+    int            ecount;
+    int           *elist;
+    double        *x;
+    double        *rc;
+} CCtsp_lp_result;
+
+typedef struct CCtsp_lpcuts {
+    int            cutcount;
+    int            cliqueend;
+    int            cutspace;
+    int            cliquespace;
+    int            cliquehashsize;
+    int            cliquefree;
+    int            *cliquehash;
+    CCtsp_lpcut    *cuts;
+    CCtsp_lpclique *cliques;
+    CCgenhash      *cuthash;
+    char           *tempcuthash;
+    int            tempcuthashsize;
+} CCtsp_lpcuts;
+
+typedef struct CCtsp_bigdual {
+    int            cutcount;
+    CCbigguy      *node_pi;
+    CCbigguy      *cut_pi;
+} CCtsp_bigdual;
+
+typedef struct CCtsp_tighten_info {
+    int    ncall;
+    int    nfail;
+    int    nadd;
+    int    nadd_tied;
+    int    ndel;
+    int    ndel_tied;
+    double add_delta;
+    double del_delta;
+    double time;
+} CCtsp_tighten_info;
+
+typedef struct CCtsp_branchobj {
+    int             depth;
+    int             rhs;
+    int             ends[2];
+    char            sense;
+    CCtsp_lpclique *clique;
+} CCtsp_branchobj;
+
+typedef struct CCtsp_cutselect {
+    int    cutpool;
+    int    connect;
+    int    segments;
+    int    exactsubtour;
+    int    tighten_lp;
+    int    decker_lp;
+    int    teething_lp;
+    int    tighten_pool;
+    int    decker_pool;
+    int    teething_pool;
+    int    maxchunksize;
+    int    Xfastcuts;
+    int    Xexactsubtours;
+    int    Xslowcuts;
+    int    consecutiveones;
+    int    necklace;
+    int    usetighten;     /* set to 1 to tighten before cuts are added */
+    int    extra_connect;  /* set to 1 to force a connected solution */
+    double nexttol;
+    double roundtol;
+} CCtsp_cutselect;
+
+/* nodes are reordered to match compression tour */
+
+typedef struct CCtsp_genadj {
+    int                     deg;
+    struct CCtsp_genadjobj *list;
+} CCtsp_genadj;
+
+typedef struct CCtsp_genadjobj {
+    int end;
+    int len;
+} CCtsp_genadjobj;
+
+typedef struct CCtsp_edgegenerator {
+    double                    *node_piest;
+    struct CCdatagroup        *dg;
+    int                       *supply;
+    CCkdtree                  *kdtree;
+    CCxnear                   *xnear;
+    struct CCtsp_xnorm_pricer *xprice;
+    CCtsp_genadjobj           *adjobjspace;
+    CCtsp_genadj              *adj;
+    int                        ncount;
+    int                        nneighbors;
+    int                        start;
+    int                        current;
+    int                        supplyhead;
+    int                        supplycount;
+} CCtsp_edgegenerator;
+
+typedef struct CCtsp_xnorm_pricer_val {
+    double                         val;
+    struct CCtsp_xnorm_pricer_val *next;
+    struct CCtsp_xnorm_pricer_val *prev;
+    int                            index;
+} CCtsp_xnorm_pricer_val;
+
+typedef struct CCtsp_xnorm_pricer {
+    CCdatagroup            *dat;
+    double                 *pi;
+    int                    *order;
+    CCtsp_xnorm_pricer_val *xminuspi_space;
+    CCtsp_xnorm_pricer_val *xminuspi;
+    int                    *invxminuspi;
+    int                     ncount;
+} CCtsp_xnorm_pricer;
+
+typedef struct CCtsp_lp {
+    CCtsp_lpgraph              graph;
+    CCtsp_lpcuts               cuts;
+    CCtsp_lpcuts              *pool;
+    CClp                       lp;
+    int                       *perm;
+    CCdatagroup               *dat;
+    int                        fullcount;
+    struct CCtsp_genadj       *fulladj;
+    struct CCtsp_genadjobj    *fulladjspace;
+    int                        nfixededges;
+    int                       *fixededges;
+    struct CCtsp_qsparsegroup *sparsifier;
+    int                        edge_life;
+    int                        cut_life;
+    char                      *name;
+    int                        id;
+    int                        parent_id;
+    int                        root;
+    double                     upperbound;
+    double                     lowerbound;
+    CCbigguy                   exact_lowerbound;
+    CCtsp_bigdual             *exact_dual;
+    int                        infeasible;
+    int                        full_edges_valid;
+    CClpbasis                 *basis;
+    CCtsp_lpcut_in             cutqueue;    /* dummy entry for doubly-linked
+                                               list */
+    CCtsp_lp_result            result;
+    CCtsp_tighten_info         tighten_stats;
+    int                        branchdepth;
+    CCtsp_branchobj           *branchhistory;
+} CCtsp_lp;
+
+typedef struct CCtsp_lprow {
+    int           rowcnt;
+    int           nzcnt;
+    char         *sense;
+    double       *rhs;
+    int          *begin;      /* offset into the array for start of row */
+    int           indexspace;
+    int          *indices;    /* the column indices of the row entries  */
+    int           entryspace;
+    double       *entries;    /* the matrix entries                     */
+} CCtsp_lprow;
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             tsp_lp.c                                    */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_cutting_loop (CCtsp_lp *lp, CCtsp_cutselect *sel, int savelp),
+    CCtsp_subtour_loop (CCtsp_lp *lp),
+    CCtsp_pricing_loop (CCtsp_lp *lp, double *bnd),
+    CCtsp_init_cutselect (CCtsp_lp *lp, CCtsp_cutselect *s),
+    CCtsp_call_x_heuristic (CCtsp_lp *lp, double *val, int *outcyc),
+    CCtsp_bb_cutting (char *probname, int probnum, int ncount,
+            CCdatagroup *dat, int *ptour, double *upbound, CCtsp_lpcuts *pool,
+            CCtsp_cutselect *sel, double *val, int *prune, int *foundtour,
+            int *besttour),
+    CCtsp_init_lp (CCtsp_lp **lp, char *probname, int probnum,
+            char *probfilename, int ncount, CCdatagroup *dat, int ecount,
+            int *elist, int *elen, int excount, int *exlist, int *exlen,
+            int exvalid, int *ptour, double initial_ub, CCtsp_lpcuts *pool),
+    CCtsp_bb_init_lp (CCtsp_lp **lp, char *probname, int probnum,
+            int ncount, CCdatagroup *dat, int *ptour, double initial_ub,
+            CCtsp_lpcuts *pool),
+    CCtsp_get_lp_result (CCtsp_lp *lp, double *lb, double *ub, int *ecount,
+            int **elist, double **x, double **rc, double **node_pi,
+            double **cut_pi),
+    CCtsp_process_cuts (CCtsp_lp *lp, int *pnadded, int tighten),
+    CCtsp_add_cut_to_cutlist (CCtsp_lpcuts *cuts, CCtsp_lpcut *c),
+    CCtsp_add_cut (CCtsp_lp *lp, CCtsp_lpcut_in *d, CCtsp_lprow *cr),
+    CCtsp_lpcut_in_nzlist (CCtsp_lpgraph *g, CCtsp_lpcut_in *c),
+    CCtsp_add_nzlist_to_lp (CCtsp_lp *lp, int nzlist, int rhs, char sense,
+            CCtsp_lprow *cr),
+    CCtsp_add_vars_to_lp (CCtsp_lp *lp, CCtsp_predge *prlist, int n),
+    CCtsp_update_result (CCtsp_lp *lp),
+    CCtsp_infeas_recover (CCtsp_lp *lp),
+    CCtsp_test_cut_branch (CCtsp_lp *lp, CCtsp_lpclique *c, double *down,
+            double *up),
+    CCtsp_register_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut_in *c,
+            CCtsp_lpcut *new),
+    CCtsp_addbad_variables (CCtsp_lp *lp, struct CCtsp_edgegenerator *eg,
+            double *ppenalty, int *pnadded, double rcthresh,
+            double maxpenalty, int phase1, int *feasible),
+    CCtsp_eliminate_variables (CCtsp_lp *lp),
+    CCtsp_build_lpgraph (CCtsp_lpgraph *g, int ncount, int ecount,
+            int *elist, int *elen),
+    CCtsp_build_lpadj (CCtsp_lpgraph *g, int estart, int eend),
+    CCtsp_add_multiple_rows (CCtsp_lp *lp, CCtsp_lprow *cr),
+    CCtsp_delete_cut (CCtsp_lp *lp, int i),
+    CCtsp_find_edge (CCtsp_lpgraph *g, int from, int to),
+    CCtsp_find_branch (CCtsp_lp *lp, int nwant, int *ngot,
+            CCtsp_branchobj **bobj, double *val, int **cyc, int usecliques),
+    CCtsp_bb_find_branch (char *probname, int probnum, int ncount,
+            CCdatagroup *dat, int *ptour, double *upperbound,
+            CCtsp_lpcuts *pool, CCtsp_branchobj **b, int usecliques,
+            int *foundtour, int *besttour),
+    CCtsp_check_integral (CCtsp_lp *lp, double *val, int **cyc, int *yesno),
+    CCtsp_find_branch_edge (CCtsp_lp *lp, int *n0, int *n1, double *val,
+            int **cyc, int branchtype),
+    CCtsp_find_branch_cliques (CCtsp_lp *lp, int nwant, int *ngot,
+            CCtsp_lpclique **bcliques, double **bval),
+    CCtsp_execute_branch (CCtsp_lp *lp, CCtsp_branchobj *b),
+    CCtsp_execute_unbranch (CCtsp_lp *lp, CClpbasis *basis),
+    CCtsp_splitprob (CCtsp_lp *lp, CCtsp_branchobj *b, int child0, int child1),
+    CCtsp_bb_splitprob (char *probname, int probnum, int ncount,
+            CCdatagroup *dat, int *ptour, double initial_ub, CCtsp_lpcuts *pool,
+            CCtsp_branchobj *b, int child0, int child1, double *val0,
+            double *val1, int *prune0, int *prune1),
+    CCtsp_dumptour (int ncount, CCdatagroup *dat, int *perm, char *probname,
+            int *tour),
+    CCtsp_add_branchhistory_to_lp (CCtsp_lp *lp),
+    CCtsp_easy_dfs_brancher (CCtsp_lp *lp, CCtsp_cutselect *sel, int depth,
+            double *upbound, int *bbcount, int usecliques, int *besttour),
+    CCtsp_bfs_brancher (char *probname, int id, double lowerbound,
+            CCtsp_cutselect *sel, double *upbound, int *bbcount, int usecliques,
+            CCdatagroup *mydat, int *ptour, CCtsp_lpcuts *pool, int ncount,
+            int *besttour),
+    CCtsp_do_interactive_branch (CCtsp_lp *lp),
+    CCtsp_inspect_full_edges (CCtsp_lp *lp),
+    CCtsp_read_probfile (CCtsp_lp *lp, char *fname, int ncount),
+    CCtsp_read_probfile_id (CCtsp_lp *lp, char *fname, int id, int ncount),
+    CCtsp_write_probfile_sav (CCtsp_lp *lp),
+    CCtsp_write_probfile_id (CCtsp_lp *lp),
+    CCtsp_dump_x (CCtsp_lp *lp, char *fname),
+    CCtsp_exact_price (CCtsp_lp *lp, CCbigguy *bound, int phase1),
+    CCtsp_edge_elimination (CCtsp_lp *lp),
+    CCtsp_exact_dual (CCtsp_lp *lp),
+    CCtsp_verify_infeasible_lp (CCtsp_lp *lp, int *yesno),
+    CCtsp_verify_lp_prune (CCtsp_lp *lp, int *yesno),
+    CCtsp_tighten_lpcut_in (CCtsp_lpgraph *g, CCtsp_lpcut_in *c,
+            double *x, CCtsp_lpcut_in *d, CCtsp_tighten_info *stats,
+            double *pimprove),
+    CCtsp_tighten_lpcut (CCtsp_lpgraph *g, CCtsp_lpclique *cliques,
+            CCtsp_lpcut *c, double *x, CCtsp_lpcut_in *d,
+            CCtsp_tighten_info *stats, double *pimprove),
+    CCtsp_test_pure_comb (int ncount, CCtsp_lpcut_in *c, int *yes_no,
+            int *handle),
+    CCtsp_test_pseudocomb (int ncount, CCtsp_lpcut_in *c, int handle,
+            int *yes_no),
+    CCtsp_test_teeth_disjoint (int ncount, CCtsp_lpcut_in *c, int handle,
+            int *yes_no),
+    CCtsp_find_pure_handle (int ncount, CCtsp_lpcut_in *c, int *handle),
+    CCtsp_comb_to_double_decker (CCtsp_lpgraph *g, double *x,
+            CCtsp_lpcut_in *c, CCtsp_lpcut_in **d),
+    CCtsp_teething (CCtsp_lpgraph *g, double *x, CCtsp_lpcut_in *cut,
+            CCtsp_lpcut_in **newcut),
+    CCtsp_init_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts **pool),
+    CCtsp_write_cutpool (int ncount, char *poolfilename, CCtsp_lpcuts  *pool),
+    CCtsp_search_cutpool (CCtsp_lpcuts *pool, CCtsp_lpcut_in **cuts,
+            int *cutcount, int ncount, int ecount, int *elist, double *x),
+    CCtsp_search_cutpool_cliques (CCtsp_lpcuts *pool, CCtsp_lpclique **cliques,
+            int *cliquecount, int ncount, int ecount, int *elist, double *x,
+            double maxdelta, int maxcliques, double **cliquevals),
+    CCtsp_branch_cutpool_cliques (CCtsp_lpcuts *pool, CCtsp_lpclique **cliques,
+            int *cliquecount, int ncount, int ecount, int *elist, double *x,
+            int nwant, double **cliquevals),
+    CCtsp_add_to_cutpool (CCtsp_lpcuts *pool, CCtsp_lpcuts *cuts,
+            CCtsp_lpcut *c),
+    CCtsp_add_to_cutpool_lpcut_in (CCtsp_lpcuts *pool, CCtsp_lpcut_in *cut),
+    CCtsp_display_cutpool (CCtsp_lpcuts *pool),
+    CCtsp_price_cuts (CCtsp_lpcuts *pool, int ncount, int ecount, int *elist,
+            double *x, double *cutval),
+    CCtsp_clique_to_array (CCtsp_lpclique *c, int **ar, int *count),
+    CCtsp_clique_delta (CCtsp_lpgraph *g, double *x, CCtsp_lpclique *c,
+            double *delta),
+    CCtsp_x_greedy_tour (CCdatagroup *dat, int ncount, int ecount, int *elist,
+            double *x, int *cyc, double *val),
+    CCtsp_x_greedy_tour_lk (CCdatagroup *dat, int ncount, int ecount,
+            int *elist, double *x, int *cyc, double *val);
+
+void
+    CCtsp_init_tsp_lp_struct (CCtsp_lp *lp),
+    CCtsp_free_tsp_lp_struct (CCtsp_lp **lp),
+    CCtsp_add_cuts_to_queue (CCtsp_lp *lp, CCtsp_lpcut_in **c),
+    CCtsp_delete_cut_from_cutlist (CCtsp_lpcuts *cuts, int ind),
+    CCtsp_init_lprow (CCtsp_lprow *cr),
+    CCtsp_free_lprow (CCtsp_lprow *cr),
+    CCtsp_unregister_cliques (CCtsp_lpcuts *cuts, CCtsp_lpcut *c),
+    CCtsp_free_cutpool (CCtsp_lpcuts **pool),
+    CCtsp_init_lpgraph_struct (CCtsp_lpgraph *g),
+    CCtsp_free_lpgraph (CCtsp_lpgraph *g),
+    CCtsp_free_lpcut_in (CCtsp_lpcut_in *c),
+    CCtsp_free_lpclique (CCtsp_lpclique *c),
+    CCtsp_free_bigdual (CCtsp_bigdual **d),
+    CCtsp_init_branchobj (CCtsp_branchobj *b),
+    CCtsp_free_branchobj (CCtsp_branchobj *b),
+    CCtsp_print_branchhistory (CCtsp_lp *lp),
+    CCtsp_init_tighten_info (CCtsp_tighten_info *stats),
+    CCtsp_print_tighten_info (CCtsp_tighten_info *stats),
+    CCtsp_mark_clique (CCtsp_lpclique *c, int *marks, int marker),
+    CCtsp_mark_clique_and_neighbors (CCtsp_lpgraph *g, CCtsp_lpclique *c,
+           int *marks, int marker),
+    CCtsp_mark_cut (CCtsp_lpcut_in *c, int *marks, int marker),
+    CCtsp_mark_cut_and_neighbors (CCtsp_lpgraph *g, CCtsp_lpcut_in *c,
+           int *marks, int marker),
+    CCtsp_mark_clique_and_neighbors_double (CCtsp_lpgraph *g, CCtsp_lpclique *c,
+           double *marks, double marker),
+    CCtsp_is_clique_marked (CCtsp_lpclique *c, int *marks, int marker,
+           int *yes_no),
+    CCtsp_clique_count (CCtsp_lpclique *c, int *count);
+
+
+double
+    CCtsp_cutprice (CCtsp_lpgraph *g, CCtsp_lpcut_in *c, double *x);
+
+#else
+
+int
+    CCtsp_cutting_loop (),
+    CCtsp_subtour_loop (),
+    CCtsp_pricing_loop (),
+    CCtsp_init_cutselect (),
+    CCtsp_call_x_heuristic (),
+    CCtsp_bb_cutting (),
+    CCtsp_init_lp (),
+    CCtsp_bb_init_lp (),
+    CCtsp_get_lp_result (),
+    CCtsp_process_cuts (),
+    CCtsp_add_cut_to_cutlist (),
+    CCtsp_add_cut (),
+    CCtsp_lpcut_in_nzlist (),
+    CCtsp_add_nzlist_to_lp (),
+    CCtsp_add_vars_to_lp (),
+    CCtsp_update_result (),
+    CCtsp_infeas_recover (),
+    CCtsp_test_cut_branch (),
+    CCtsp_register_cliques (),
+    CCtsp_addbad_variables (),
+    CCtsp_eliminate_variables (),
+    CCtsp_build_lpgraph (),
+    CCtsp_build_lpadj (),
+    CCtsp_add_multiple_rows (),
+    CCtsp_delete_cut (),
+    CCtsp_find_edge (),
+    CCtsp_find_branch (),
+    CCtsp_bb_find_branch (),
+    CCtsp_check_integral (),
+    CCtsp_find_branch_edge (),
+    CCtsp_find_branch_cliques (),
+    CCtsp_execute_branch (),
+    CCtsp_execute_unbranch (),
+    CCtsp_splitprob (),
+    CCtsp_bb_splitprob (),
+    CCtsp_dumptour (),
+    CCtsp_add_branchhistory_to_lp (),
+    CCtsp_easy_dfs_brancher (),
+    CCtsp_bfs_brancher (),
+    CCtsp_do_interactive_branch (),
+    CCtsp_inspect_full_edges (),
+    CCtsp_read_probfile (),
+    CCtsp_read_probfile_id (),
+    CCtsp_write_probfile_sav (),
+    CCtsp_write_probfile_id (),
+    CCtsp_dump_x (),
+    CCtsp_exact_price (),
+    CCtsp_edge_elimination (),
+    CCtsp_exact_dual (),
+    CCtsp_verify_infeasible_lp (),
+    CCtsp_verify_lp_prune (),
+    CCtsp_tighten_lpcut_in (),
+    CCtsp_tighten_lpcut (),
+    CCtsp_test_pure_comb (),
+    CCtsp_test_pseudocomb (),
+    CCtsp_test_teeth_disjoint (),
+    CCtsp_find_pure_handle (),
+    CCtsp_comb_to_double_decker (),
+    CCtsp_teething (),
+    CCtsp_init_cutpool (),
+    CCtsp_write_cutpool (),
+    CCtsp_search_cutpool (),
+    CCtsp_search_cutpool_cliques (),
+    CCtsp_branch_cutpool_cliques (),
+    CCtsp_add_to_cutpool (),
+    CCtsp_add_to_cutpool_lpcut_in (),
+    CCtsp_display_cutpool (),
+    CCtsp_price_cuts (),
+    CCtsp_clique_to_array (),
+    CCtsp_clique_delta (),
+    CCtsp_x_greedy_tour (),
+    CCtsp_x_greedy_tour_lk ();
+
+void
+    CCtsp_init_tsp_lp_struct (),
+    CCtsp_free_tsp_lp_struct (),
+    CCtsp_add_cuts_to_queue (),
+    CCtsp_delete_cut_from_cutlist (),
+    CCtsp_init_lprow (),
+    CCtsp_free_lprow (),
+    CCtsp_unregister_cliques (),
+    CCtsp_free_cutpool (),
+    CCtsp_init_lpgraph_struct (),
+    CCtsp_free_lpgraph (),
+    CCtsp_free_lpcut_in (),
+    CCtsp_free_lpclique (),
+    CCtsp_free_bigdual (),
+    CCtsp_init_branchobj (),
+    CCtsp_free_branchobj (),
+    CCtsp_print_branchhistory (),
+    CCtsp_init_tighten_info (),
+    CCtsp_print_tighten_info (),
+    CCtsp_mark_clique (),
+    CCtsp_mark_clique_and_neighbors (),
+    CCtsp_mark_cut (),
+    CCtsp_mark_cut_and_neighbors (),
+    CCtsp_mark_clique_and_neighbors_double (),
+    CCtsp_is_clique_marked (),
+    CCtsp_clique_count ();
+
+
+double
+    CCtsp_cutprice ();
+
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                             cliqhash.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_init_cliquehash (CCtsp_lpcuts *cuts, int size),
+    CCtsp_register_clique (CCtsp_lpcuts *cuts, CCtsp_lpclique *c);
+
+void
+    CCtsp_free_cliquehash (CCtsp_lpcuts *cuts),
+    CCtsp_unregister_clique (CCtsp_lpcuts *cuts, int c);
+
+#else
+
+int
+    CCtsp_init_cliquehash (),
+    CCtsp_register_clique ();
+
+void
+    CCtsp_free_cliquehash (),
+    CCtsp_unregister_clique ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             cutcall.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct cutinfo {
+    CC_SRKexpinfo expand;
+    CCtsp_lpcut_in **clist;
+    CCtsp_lpcut_in *current;
+    int *cutcount;
+} cutinfo;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_connect_cuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+            int ecount, int *elist, double *x),
+    CCtsp_segment_cuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+            int ecount, int *elist, double *x),
+    CCtsp_exact_subtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount,
+            int ecount, int *elist, double *x),
+    CCtsp_tighten_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+            CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+            int *elist, double *x, double testtol, int maxcuts),
+    CCtsp_double_decker_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+            CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+            int *elist, double *x, double testtol, int maxcuts),
+    CCtsp_teething_lp (CCtsp_lpcuts *cuts, CCtsp_tighten_info *stats,
+            CCtsp_lpcut_in **cutsout, int *cutcount, int ncount, int ecount,
+            int *elist, double *x, double testtol, int maxcuts),
+    CCtsp_copy_lpcut_in (CCtsp_lpcut_in *c, CCtsp_lpcut_in *new),
+    CCtsp_segment_to_subtour (CCtsp_lpcut_in **cut, int a, int b),
+    CCtsp_array_to_subtour (CCtsp_lpcut_in **cut, int *ar, int acount),
+    CCtsp_array_to_lpclique (int *ar, int acount, CCtsp_lpclique *cliq),
+    CCtsp_seglist_to_lpclique (int nseg, int *list, CCtsp_lpclique *cliq),
+    CCtsp_add_node_to_lpclique (CCtsp_lpclique *cin, CCtsp_lpclique *cout,
+            int n),
+    CCtsp_delete_node_from_lpclique (CCtsp_lpclique *cin,
+            CCtsp_lpclique *cout, int n),
+    CCtsp_lpcut_to_lpcut_in (CCtsp_lpcuts *cuts, CCtsp_lpcut *c,
+            CCtsp_lpcut_in *new),
+    CCtsp_copy_lpclique (CCtsp_lpclique *c, CCtsp_lpclique *new),
+    CCtsp_file_cuts (char *cutfile, CCtsp_lpcut_in **cuts, int *cutcount,
+            int ncount, int *tour),
+    CCtsp_file_cuts_write (char *cutfile, CCtsp_lpcuts *cuts, int *tour),
+    CCtsp_buildcut_begin (cutinfo *cuts, int init_cliquecount),
+    CCtsp_buildcut_addclique (cutinfo *cuts, int *arr, int size, int handle);
+
+void
+    CCtsp_init_lpcut_in (CCtsp_lpcut_in *c),
+    CCtsp_init_lpclique (CCtsp_lpclique *c),
+    CCtsp_print_lpcut_in (CCtsp_lpcut_in *c),
+    CCtsp_print_lpclique (CCtsp_lpclique *c),
+    CCtsp_lpclique_compare (CCtsp_lpclique *a, CCtsp_lpclique *b, int *diff),
+    CCtsp_buildcut_abort (cutinfo *cuts),
+    CCtsp_buildcut_finish (cutinfo *cuts, int rhs);
+
+#else
+
+int
+    CCtsp_connect_cuts (),
+    CCtsp_segment_cuts (),
+    CCtsp_exact_subtours (),
+    CCtsp_tighten_lp (),
+    CCtsp_double_decker_lp (),
+    CCtsp_teething_lp (),
+    CCtsp_copy_lpcut_in (),
+    CCtsp_segment_to_subtour (),
+    CCtsp_array_to_subtour (),
+    CCtsp_array_to_lpclique (),
+    CCtsp_seglist_to_lpclique (),
+    CCtsp_add_node_to_lpclique (),
+    CCtsp_delete_node_from_lpclique (),
+    CCtsp_lpcut_to_lpcut_in (),
+    CCtsp_copy_lpclique (),
+    CCtsp_file_cuts (),
+    CCtsp_file_cuts_write (),
+    CCtsp_buildcut_begin (),
+    CCtsp_buildcut_addclique ();
+
+void
+    CCtsp_init_lpcut_in (),
+    CCtsp_init_lpclique (),
+    CCtsp_print_lpcut_in (),
+    CCtsp_print_lpclique (),
+    CCtsp_lpclique_compare (),
+    CCtsp_buildcut_abort (),
+    CCtsp_buildcut_finish ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             edgemap.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCtsp_edgeinf {
+    int ends[2];
+    int val;
+    struct CCtsp_edgeinf *next;
+} CCtsp_edgeinf;
+
+typedef struct CCtsp_edgehash {
+    struct CCtsp_edgeinf **table;
+    unsigned int size;
+    unsigned int mult;
+} CCtsp_edgehash;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCtsp_edgehash_init (CCtsp_edgehash *h, int size),
+    CCtsp_edgehash_add (CCtsp_edgehash *h, int end1, int end2, int val),
+    CCtsp_edgehash_del (CCtsp_edgehash *h, int end1, int end2),
+    CCtsp_edgehash_find (CCtsp_edgehash *h, int end1, int end2);
+
+void
+    CCtsp_edgehash_delall (CCtsp_edgehash *h),
+    CCtsp_edgehash_free (CCtsp_edgehash *h);
+
+#else
+
+int
+    CCtsp_edgehash_init (),
+    CCtsp_edgehash_add (),
+    CCtsp_edgehash_del (),
+    CCtsp_edgehash_find ();
+
+void
+    CCtsp_edgehash_delall (),
+    CCtsp_edgehash_free ();
+
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             generate.c                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#define CCtsp_PRICE_COMPLETE_GRAPH -1
+#define CCtsp_GEN_PRICE_EPSILON 0.0001 /* 0.0000001 */
+#define CCtsp_GEN_USE_ADJ 50           /* Cutoff for using explicit adj list */
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCtsp_free_edgegenerator (CCtsp_edgegenerator *eg);
+
+int
+    CCtsp_init_edgegenerator (CCtsp_edgegenerator *eg, int ncount,
+            CCdatagroup *dg, CCtsp_genadj *adj, int nneighbors),
+    CCtsp_reset_edgegenerator (CCtsp_edgegenerator *eg, double *node_piest),
+    CCtsp_generate_edges (CCtsp_edgegenerator *eg, int nwant, int *pngot,
+            int *elist, int *elen, int *finished),
+    CCtsp_edgelist_to_genadj (int ncount, int ecount, int *elist, int *elen,
+            CCtsp_genadj **adj, CCtsp_genadjobj **adjobjspace);
+
+#else
+
+void
+    CCtsp_free_edgegenerator ();
+
+int
+    CCtsp_init_edgegenerator (),
+    CCtsp_reset_edgegenerator (),
+    CCtsp_generate_edges (),
+    CCtsp_edgelist_to_genadj ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             prob_io.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+#define CCtsp_PROB_IO_VERSION  1
+#define CCtsp_PROB_FILE_NAME_LEN 128
+
+#define CCtsp_PROB_IO_CUTS_VERSION_BASE  -1000
+#define CCtsp_PROB_IO_CUTS_VERSION       -1001   /* Should be <= BASE (-1000) */
+
+typedef struct CCtsp_PROB_FILE {
+    CC_SFILE *f;
+    char name[CCtsp_PROB_FILE_NAME_LEN];
+    int id;
+    int parent;
+    double ub;
+    double lb;
+    CCbigguy exactlb;
+    int nnodes;
+    int child0;
+    int child1;
+    int real;       /* Set to 1 when we know this is a real child */
+    int processed;
+    int infeasible;
+    struct {
+        int dat;
+        int edge;
+        int fulladj;
+        int cut;
+        int tour;
+        int basis;
+        int norms;
+        int fix;
+        int exactdual;
+        int history;
+    } offsets;
+} CCtsp_PROB_FILE;
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+CCtsp_PROB_FILE
+    *CCtsp_prob_read (char *f, int n),
+    *CCtsp_prob_read_name (char *f),
+    *CCtsp_prob_write (char *f, int n),
+    *CCtsp_prob_write_name (char *fname, char *pname);
+
+int
+    CCtsp_prob_file_delete (char *f, int n),
+    CCtsp_prob_getname (CCtsp_PROB_FILE *p, char *name),
+    CCtsp_prob_getid (CCtsp_PROB_FILE *p, int *id),
+    CCtsp_prob_getparent (CCtsp_PROB_FILE *p, int *parent),
+    CCtsp_prob_getub (CCtsp_PROB_FILE *p, double *ub),
+    CCtsp_prob_getlb (CCtsp_PROB_FILE *p, double *lb),
+    CCtsp_prob_getexactlb (CCtsp_PROB_FILE *p, CCbigguy *lb),
+    CCtsp_prob_getnnodes (CCtsp_PROB_FILE *p, int *nnodes),
+    CCtsp_prob_getchildren (CCtsp_PROB_FILE *p, int *child0, int *child1),
+    CCtsp_prob_getreal (CCtsp_PROB_FILE *p, int *real),
+    CCtsp_prob_getprocessed (CCtsp_PROB_FILE *p, int *processed),
+    CCtsp_prob_getinfeasible (CCtsp_PROB_FILE *p, int *infeasible),
+    CCtsp_prob_gettour (CCtsp_PROB_FILE *p, int **tour),
+    CCtsp_prob_getedges (CCtsp_PROB_FILE *p, int *nedges, int **elist,
+        int **elen),
+    CCtsp_prob_getcuts (CCtsp_PROB_FILE *p, CC_SFILE *s, CCtsp_lpcuts *cuts),
+    CCtsp_prob_getbasis (CCtsp_PROB_FILE *p, int *ccount, int *rcount,
+        int **cstat, int **rstat),
+    CCtsp_prob_getnorms (CCtsp_PROB_FILE *p, int *rcount, double **dnorm),
+    CCtsp_prob_getfulladj (CCtsp_PROB_FILE *p, int ncount, int *fullcount,
+        CCtsp_genadj **adj, CCtsp_genadjobj **adjspace),
+    CCtsp_prob_getfixed (CCtsp_PROB_FILE *p, int *ecount, int **elist),
+    CCtsp_prob_getexactdual (CCtsp_PROB_FILE *p, int ncount,
+        CCtsp_bigdual **d),
+    CCtsp_prob_gethistory (CCtsp_PROB_FILE *p, int *depth,
+        CCtsp_branchobj **history),
+    CCtsp_prob_rclose (CCtsp_PROB_FILE *p),
+
+    CCtsp_prob_putname (CCtsp_PROB_FILE *p, char *name),
+    CCtsp_prob_putid (CCtsp_PROB_FILE *p, int id),
+    CCtsp_prob_putparent (CCtsp_PROB_FILE *p, int parent),
+    CCtsp_prob_putub (CCtsp_PROB_FILE *p, double ub),
+    CCtsp_prob_putlb (CCtsp_PROB_FILE *p, double lb),
+    CCtsp_prob_putexactlb (CCtsp_PROB_FILE *p, CCbigguy lb),
+    CCtsp_prob_putnnodes (CCtsp_PROB_FILE *p, int nnodes),
+    CCtsp_prob_putchildren (CCtsp_PROB_FILE *p, int child0, int child1),
+    CCtsp_prob_putreal (CCtsp_PROB_FILE *p, int real),
+    CCtsp_prob_putprocessed (CCtsp_PROB_FILE *p, int processed),
+    CCtsp_prob_putinfeasible (CCtsp_PROB_FILE *p, int infeasible),
+    CCtsp_prob_puttour (CCtsp_PROB_FILE *p, int *tour),
+    CCtsp_prob_putedges (CCtsp_PROB_FILE *p, int nedges, int *elist, int *elen),
+    CCtsp_prob_putcuts (CCtsp_PROB_FILE *p, CC_SFILE *s, CCtsp_lpcuts *cuts),
+    CCtsp_prob_putbasis (CCtsp_PROB_FILE *p, int ccount, int rcount, int *cstat,
+        int *rstat),
+    CCtsp_prob_putnorms (CCtsp_PROB_FILE *p, int rcount, double *dnorm),
+    CCtsp_prob_putfulladj (CCtsp_PROB_FILE *p, int ncount, int fullcount,
+        CCtsp_genadj *adj),
+    CCtsp_prob_putfixed (CCtsp_PROB_FILE *p, int ecount, int *elist),
+    CCtsp_prob_putexactdual (CCtsp_PROB_FILE *p, CCtsp_bigdual *d, int ncount),
+    CCtsp_prob_puthistory (CCtsp_PROB_FILE *p, int depth,
+        CCtsp_branchobj *history),
+    CCtsp_prob_wclose (CCtsp_PROB_FILE *p);
+
+#else
+
+CCtsp_PROB_FILE
+    *CCtsp_prob_read (),
+    *CCtsp_prob_read_name (),
+    *CCtsp_prob_write (),
+    *CCtsp_prob_write_name ();
+
+int
+    CCtsp_prob_file_delete (),
+    CCtsp_prob_getname (),
+    CCtsp_prob_getid (),
+    CCtsp_prob_getparent (),
+    CCtsp_prob_getub (),
+    CCtsp_prob_getlb (),
+    CCtsp_prob_getexactlb (),
+    CCtsp_prob_getnnodes (),
+    CCtsp_prob_getchildren (),
+    CCtsp_prob_getreal (),
+    CCtsp_prob_getprocessed (),
+    CCtsp_prob_getinfeasible (),
+    CCtsp_prob_gettour (),
+    CCtsp_prob_getedges (),
+    CCtsp_prob_getcuts (),
+    CCtsp_prob_getbasis (),
+    CCtsp_prob_getnorms (),
+    CCtsp_prob_getfulladj (),
+    CCtsp_prob_getfixed (),
+    CCtsp_prob_getexactdual (),
+    CCtsp_prob_gethistory (),
+    CCtsp_prob_rclose (),
+
+    CCtsp_prob_putname (),
+    CCtsp_prob_putid (),
+    CCtsp_prob_putparent (),
+    CCtsp_prob_putub (),
+    CCtsp_prob_putlb (),
+    CCtsp_prob_putexactlb (),
+    CCtsp_prob_putnnodes (),
+    CCtsp_prob_putchildren (),
+    CCtsp_prob_putreal (),
+    CCtsp_prob_putprocessed (),
+    CCtsp_prob_putinfeasible (),
+    CCtsp_prob_puttour (),
+    CCtsp_prob_putedges (),
+    CCtsp_prob_putcuts (),
+    CCtsp_prob_putbasis (),
+    CCtsp_prob_putnorms (),
+    CCtsp_prob_putfulladj (),
+    CCtsp_prob_putfixed (),
+    CCtsp_prob_putexactdual (),
+    CCtsp_prob_puthistory (),
+    CCtsp_prob_wclose ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                             qsparse.c                                   */
+/*                                                                         */
+/***************************************************************************/
+
+typedef struct CCtsp_qsparsegroup {
+    CCdheap *add_queue;   /* An empty heap will be maintained */
+    CCdheap *sub_queue;   /* An empty heap will be maintained */
+    int *count_m1;        /* The array will be maintained at 0 */
+    int *count_non0;      /* The array will be maintained at 0 */
+    int *count_1;         /* The array will be maintained at 0 */
+    int *on_add_queue;    /* The array will be maintained at 0 */
+    int *on_sub_queue;    /* The array will be maintained at 0 */
+    int *mults;           /* The array will be maintained at 0 */
+} CCtsp_qsparsegroup;
+
+#ifdef CC_PROTOTYPE_ANSI
+
+void
+    CCtsp_free_qsparsify (CCtsp_qsparsegroup **pqs);
+int
+    CCtsp_qsparsify (CCtsp_qsparsegroup **pqs, struct CCtsp_lpgraph *g,
+            int *pnzlist, int *scount, struct CCtsp_sparser **slist,
+            int *savedcount);
+#else
+
+void
+    CCtsp_free_qsparsify ();
+int
+    CCtsp_qsparsify ();
+
+#endif
+
+#endif  /* __TSP_H */
+#ifndef __XSTUFF_H
+#define __XSTUFF_H
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    Xfastcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xslowcuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xfastsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xexactsubtours (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xcliquetrees (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+               int *elist, double *x),
+    Xconsecutiveones (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+                      int *elist, double *x, CCtsp_lpcuts *pool),
+    Xnecklacecuts (CCtsp_lpcut_in **cuts, int *cutcount, int ncount, int ecount,
+                      int *elist, double *x, CCtsp_lpcuts *pool);
+
+#else
+
+int
+    Xfastcuts (),
+    Xslowcuts (),
+    Xfastsubtours (),
+    Xexactsubtours (),
+    Xcliquetrees (),
+    Xconsecutiveones (),
+    Xnecklacecuts ();
+
+#endif
+
+#endif  /* __XSTUFF_H */
+#ifndef __FMATCH_H
+#define __FMATCH_H
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CCfmatch_fractional_2match (int ncount, int ecount, int *elist, int *elen,
+        CCdatagroup *dat, double *val, int *thematching, int *thedual,
+        int *thebasis, int wantbasic);
+
+#else
+
+int
+    CCfmatch_fractional_2match ();
+
+#endif
+
+#endif  /* __FMATCH_H */
+#ifndef  __LINKERN_H
+#define  __LINKERN_H
+
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CClinkern_tour (int ncount, CCdatagroup *dat, int ecount,
+            int *elist, int stallcount, int repeatcount, int *incycle,
+            int *outcycle, double *val, int run_silently, double time_bound,
+            double length_bound, char *saveit_name);
+
+#else
+
+int
+    CClinkern_tour ();
+
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/* Must define exactly one of:                                             */
+/*                                                                         */
+/*          CC_LINKED_LIST_FLIPPER       (flip_llX)                        */
+/*          CC_ARRAY_FLIPPER             (flip_ary)                        */
+/*          CC_TWO_LEVEL_FLIPPER         (flip_two)                        */
+/*          CC_SEGMENTS_FLIPPER          (flip_sg1)                        */
+/*          CC_NO_UNDO_SEGMENTS_FLIPPER  (flip_sg2)                        */
+/*          CC_FULL_SEGMENTS_FLIPPER     (flip_sg3)                        */
+/*          CC_SPLAY_FLIPPER             (flip_sp2)                        */
+/*          CC_BTREE_FLIPPER             (flip_btr)                        */
+/*                                                                         */
+/* NOTE: If MARK_NEIGHBORS is not defined in linkern.c, then               */
+/*       NO_UNDO_SEGMENTS may follow a different improving sequence then   */
+/*       the other flippers, since the next and prevs in turn () will be   */
+/*       with respect to an out-of-date-tour.                              */
+/*                                                                         */
+/***************************************************************************/
+
+
+#define CC_TWO_LEVEL_FLIPPER
+/* #define BTREE_FLIPPER */
+
+#ifdef CC_LINKED_LIST_FLIPPER
+#define CC_EXTRA_INFO_FLIP
+#endif
+
+#ifdef CC_ARRAY_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#endif
+
+#ifdef CC_TWO_LEVEL_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#endif
+
+#ifdef CC_NO_UNDO_SEGMENTS_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#define CC_USE_QUICK_FLIPS
+#endif
+
+#ifdef CC_FULL_SEGMENTS_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#endif
+
+#ifdef CC_SPLAY_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#define CC_EXTRA_INFO_FLIP
+#endif
+
+#ifdef CC_BTREE_FLIPPER
+#define CC_USE_FLIP_CLEANING
+#define CC_EXTRA_INFO_FLIP
+#endif
+
+#ifdef CC_PROTOTYPE_ANSI
+
+int
+    CClinkern_flipper_init (int ncount, int *cyc),
+    CClinkern_flipper_reset_perm (int ncount),
+    CClinkern_flipper_reset_temp (int ncount),
+    CClinkern_flipper_next (int x),
+    CClinkern_flipper_prev (int x),
+    CClinkern_flipper_cycle (int *x),
+    CClinkern_flipper_sequence_burst (int x, int y, int z),
+    CClinkern_flipper_sequence (int x, int y, int z);
+
+void
+#ifdef CC_EXTRA_INFO_FLIP
+    CClinkern_flipper_flip (int xprev, int x, int y, int ynext),
+#else
+    CClinkern_flipper_flip (int x, int y),
+#endif
+    CClinkern_flipper_flip_quick (int x, int y),
+    CClinkern_flipper_flip_perm (int x, int y),
+    CClinkern_flipper_sequence_burst_init (int x, int z),
+    CClinkern_flipper_finish (void),
+    CClinkern_flipper_free_world (void);
+
+#else
+
+int
+    CClinkern_flipper_init (),
+    CClinkern_flipper_reset_perm (),
+    CClinkern_flipper_reset_temp (),
+    CClinkern_flipper_next (),
+    CClinkern_flipper_prev (),
+    CClinkern_flipper_cycle (),
+    CClinkern_flipper_sequence_burst (),
+    CClinkern_flipper_sequence ();
+
+void
+    CClinkern_flipper_flip (),
+    CClinkern_flipper_flip_quick (),
+    CClinkern_flipper_flip_perm (),
+    CClinkern_flipper_sequence_burst_init (),
+    CClinkern_flipper_finish (),
+    CClinkern_flipper_free_world ();
+
+#endif
+
+#endif  /* __LINKERN_H */
+#ifndef  __MACRORUS_H
+#define  __MACRORUS_H
+
+#define CC_SWAP(a,b,t) (((t)=(a)),((a)=(b)),((b)=(t)))
+
+#define CC_OURABS(a) (((a) >= 0) ? (a) : -(a))
+
+#endif  /* __MACRORUS_H */
diff --git a/demos/homology.geo b/demos/homology.geo
index d8ba7da69b631c9a6a731495b1cfc535c70339eb..aacb943e18e296c2e7d86f1caa62c063ee3d4752 100644
--- a/demos/homology.geo
+++ b/demos/homology.geo
@@ -1,7 +1,7 @@
 /********************************************************************* 
  *
  *  Gmsh tutorial 10
- * 
+ *
  *  Homology computation
  *
  *********************************************************************/
@@ -133,6 +133,7 @@ Physical Surface(74) = {46, 18, 20, 52, 22, 50, 24, 48, 66, 63, 60, 58, 56, 54};
 // Complement of the domain surface respect to the four terminals
 Physical Surface(75) = {46, 63, 66, 52, 50, 48, 54, 60, 58, 56};
 
+/*
 // Create a mesh of the model
 Mesh 3;
 
@@ -156,3 +157,4 @@ HomCut("t10_hom.msh") = {{69}, {70, 71, 72, 73}};
 //  HomGen("t10_hom.msh") = {{}, {}};
 //  HomGen("t10_hom.msh") = {{69}, {74}}; 
 //  HomGen("t10_hom.msh") = {{}, {74}}; 
+*/
diff --git a/doc/CREDITS.txt b/doc/CREDITS.txt
index bc8673ed450445276c7ed58f7548353802e5d807..fae780bdc8902bcb7e3719fb09a008ae9a10f21b 100644
--- a/doc/CREDITS.txt
+++ b/doc/CREDITS.txt
@@ -105,6 +105,27 @@ This version of Gmsh may contain code (in the contrib/Tetgen
 subdirectory) copyright (C) 2002-2007 Hang Si: check the configuration
 options.
 
+This version of Gmsh may contain code (in the contrib/Salome
+subdirectory) copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6,
+CEA/DEN, CEDRAT, EDF R& D, LEG, PRINCIPIA R& D, BUREAU VERITAS: check
+the configuration options.
+
+This version of Gmsh may contain code (in the contrib/bamg
+subdirectory) from Freefem++ copyright (C) Frederic Hecht: check the
+configuration options.
+
+This version of Gmsh may contain code (in the contrib/lbfgs
+subdirectory) (C) Sergey Bochkanov (ALGLIB project): check the
+configuration options.
+
+This version of Gmsh may contain code (in the contrib/mmg3d
+subdirectory) from MMG3D Version 4.0 (C) 2004-2011 Cecile Dobrzynski
+and Pascal Frey (IPB - UPMC - INRIA): check the configuration options.
+
+This version of Gmsh may contain code (in the contrib/Blossom
+subdirectory) copyright (C) 1995-1997 Bill Cook et al.: check the
+configuration options.
+
 Special thanks to Bill Spitzak, Michael Sweet, Matthias Melcher, Greg
 Ercolano and others for the Fast Light Tool Kit on which Gmsh's GUI is
 based. See http://www.fltk.org for more info on this excellent