#define MAX_CITY 100    /* 最大市の数 */

int tsp(int *spath, int *xcity, int *ycity, int ncity)
{
    int slen = -1;                /* 最短パスの距離 */
    int tpath[MAX_CITY];          /* あるパス */
    static int guess();
    static void evaluate();

    while (1) {
        if (guess(tpath, slen, xcity, ycity, ncity) == 1) /* パスを作り出す */
            break;
        evaluate(&slen, spath, tpath, xcity, ycity,
                 ncity);           /* そのパスの距離を計算する */
    }
    return slen;
}

/* 巡回パスを作り出す。あらゆる組合せを考える必要がある */
static int guess(int *tpath, int slen, int *xcity, int *ycity, int ncity)
{
    int i, j, k;
    int	tmp[MAX_CITY];

    if (slen < 0) {
        for (i = 0; i < ncity; i++) tpath[i] = i;
        return 0;
    }

    for (i = ncity - 2; i >= 1; i--) {
        for (j = 0; j < ncity; j++) tmp[j] = j;
        for (j = 0; j <= i; j++) tmp[tpath[j]] = MAX_CITY;
        for (j = 0; j < ncity; j++)
            if (tmp[j] != MAX_CITY)
                if (tmp[j] > tpath[i]) {
                    tpath[i] = tmp[j];
                    goto NEXT;
                }
    }
    return 1;		/* 終了 */

NEXT:
    for (j = i+1; j < ncity; j++) {
        for (k = 0; k < ncity; k++) tmp[k] = k;
        for (k = 0; k < j; k++) tmp[tpath[k]] = MAX_CITY;
        for (k = 0; k < ncity; k++)
            if (tmp[k] != MAX_CITY) {
                tpath[j] = tmp[k];
                break;
            }
    }
    return 0;
}

/* 巡回パスの距離を算出する */
static void evaluate(int *slen, int *spath, int *tpath,
    int *xcity, int *ycity, int ncity)
{
    int i;
    int dx, dy;
    int tlen;

    /* パスの距離の計算 */
    dx = xcity[tpath[0]] - xcity[tpath[ncity-1]];
    dy = ycity[tpath[0]] - ycity[tpath[ncity-1]];
    if (dx < 0) dx = -dx;
    if (dy < 0) dy = -dy;
    tlen = dx + dy;
    for (i = 1; i < ncity; i++) {
        dx = xcity[tpath[i]] - xcity[tpath[i-1]];
        dy = ycity[tpath[i]] - ycity[tpath[i-1]];
        if (dx < 0) dx = -dx;
        if (dy < 0) dy = -dy;
        tlen += dx + dy;
    }

    if (*slen < 0 || tlen < *slen) {    /* 最短ならば... */
        for (i = 0; i < ncity; i++) spath[i] = tpath[i];
        *slen = tlen;
    }
}