private double spfH(InfoTree it1, InfoTree it2, int[] heavyPath) {

		int fSize = it1.info[POST2_SIZE][it1.getCurrentNode()];
		int gSize = it2.info[POST2_SIZE][it2.getCurrentNode()];

		int gRevPre = it2.getSize() - 1 - it2.getCurrentNode();
		int gPre = it2.info[POST2_PRE][it2.getCurrentNode()];

		int gTreeSize = it2.getSize();

		int strategy;

		int jOfi;

		// Initialize arrays to their maximal possible size for current pairs of
		// subtrees.
		t = new double[gSize][gSize];
		tCOPY = new double[gSize][gSize];
		s = new double[fSize][gSize];
		q = new double[fSize];

		int vp = -1;
		int nextVp = -1;

		for (int it = heavyPath.length - 1; it >= 0; it--) {
			vp = heavyPath[it];
			strategy = it1.info[POST2_STRATEGY][vp];
			if (strategy != BOTH) {
				if (it1.info[POST2_SIZE][vp] == 1) {
					for (int i = gSize - 1; i >= 0; i--) {
						jOfi = jOfI(it2, i, gSize, gRevPre, gPre, strategy,
								gTreeSize);
						for (int j = jOfi; j >= 0; j--) {
							t[i][j] = (gSize - (i + j)) * costIns;
						}
					}
					previousStrategy = strategy;
				}
				computePeriod(it1, vp, nextVp, it2, strategy);
			} else {
				if (it1.info[POST2_SIZE][vp] == 1) {
					for (int i = gSize - 1; i >= 0; i--) {
						jOfi = jOfI(it2, i, gSize, gRevPre, gPre, LEFT,
								gTreeSize);
						for (int j = jOfi; j >= 0; j--) {
							t[i][j] = (gSize - (i + j)) * costIns;
						}
					}
					previousStrategy = LEFT;
				}
				computePeriod(it1, vp, nextVp, it2, LEFT);
				if (it1.info[POST2_SIZE][vp] == 1) {
					for (int i = gSize - 1; i >= 0; i--) {
						jOfi = jOfI(it2, i, gSize, gRevPre, gPre, RIGHT,
								gTreeSize);
						for (int j = jOfi; j >= 0; j--) {
							t[i][j] = (gSize - (i + j)) * costIns;
						}
					}
					previousStrategy = RIGHT;
				}
				computePeriod(it1, vp, nextVp, it2, RIGHT);
			}
			nextVp = vp;
		}
		return t[0][0];
	}
private double spfH ( InfoTree it1 , InfoTree it2 , int [ ] heavyPath ) { int fSize = it1 . info [ POST2_SIZE ] [ it1 . getCurrentNode ( ) ] ; int gSize = it2 . info [ POST2_SIZE ] [ it2 . getCurrentNode ( ) ] ; int gRevPre = it2 . getSize ( ) - 1 - it2 . getCurrentNode ( ) ; int gPre = it2 . info [ POST2_PRE ] [ it2 . getCurrentNode ( ) ] ; int gTreeSize = it2 . getSize ( ) ; int strategy ; int jOfi ; t = new double [ gSize ] [ gSize ] ; tCOPY = new double [ gSize ] [ gSize ] ; s = new double [ fSize ] [ gSize ] ; q = new double [ fSize ] ; int vp = - 1 ; int nextVp = - 1 ; for ( int it = heavyPath . length - 1 ; it >= 0 ; it -- ) { vp = heavyPath [ it ] ; strategy = it1 . info [ POST2_STRATEGY ] [ vp ] ; if ( strategy != BOTH ) { if ( it1 . info [ POST2_SIZE ] [ vp ] == 1 ) { for ( int i = gSize - 1 ; i >= 0 ; i -- ) { jOfi = jOfI ( it2 , i , gSize , gRevPre , gPre , strategy , gTreeSize ) ; for ( int j = jOfi ; j >= 0 ; j -- ) { t [ i ] [ j ] = ( gSize - ( i + j ) ) * costIns ; } } previousStrategy = strategy ; } computePeriod ( it1 , vp , nextVp , it2 , strategy ) ; } else { if ( it1 . info [ POST2_SIZE ] [ vp ] == 1 ) { for ( int i = gSize - 1 ; i >= 0 ; i -- ) { jOfi = jOfI ( it2 , i , gSize , gRevPre , gPre , LEFT , gTreeSize ) ; for ( int j = jOfi ; j >= 0 ; j -- ) { t [ i ] [ j ] = ( gSize - ( i + j ) ) * costIns ; } } previousStrategy = LEFT ; } computePeriod ( it1 , vp , nextVp , it2 , LEFT ) ; if ( it1 . info [ POST2_SIZE ] [ vp ] == 1 ) { for ( int i = gSize - 1 ; i >= 0 ; i -- ) { jOfi = jOfI ( it2 , i , gSize , gRevPre , gPre , RIGHT , gTreeSize ) ; for ( int j = jOfi ; j >= 0 ; j -- ) { t [ i ] [ j ] = ( gSize - ( i + j ) ) * costIns ; } } previousStrategy = RIGHT ; } computePeriod ( it1 , vp , nextVp , it2 , RIGHT ) ; } nextVp = vp ; } return t [ 0 ] [ 0 ] ; }
Single-path function for heavy path based on Klein/Demaine algorithm.

@param it1
@param it2
@param heavyPath
@return distance between subtrees it1 and it2