UVA 116_ Unidirectional TSP

题意:

给定整数矩阵,从第一列的任何一个位置出发,每次可以向右、右上、右下走一个格,将最后一行和第一行看成是邻接的,最终到达最后一列,路径长度为所经过格中的整数之和,求最小路径,答案不唯一,输出字典序最小的路径。

分析:

数组dp[i][j]记录从第i行第j列出发,到达最后一列的最小路径长度

  • 每个阶段都有三种决策,向右/右上/右下【注意最后一行和第一行的情况
  • 字典序最小,每次都先选择字典序较小的决策
  • 打印路径,记录下一个位置

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100,  INF=0x3fffffff;
int c[maxn][maxn], dp[maxn][maxn], s[maxn][maxn];
int main (void)
{
    int m ,n;
    while(cin>>n>>m){//n行m列
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin>>c[i][j];
            dp[i][j] = INF;
        }
    }
    for(int i = m -1; i >= 0; i--){//j行i列
        for(int j = 0; j < n; j++){
            if(i == m - 1) {dp[j][i] = c[j][i];continue;}
            int r[3]={j, j + 1, j - 1};
            if(j + 1==n) r[1] = 0;
            if(j - 1==-1) r[2] = n-1;
            sort(r, r+3);
            for(int k = 0; k < 3; k++){
                int d = dp[r[k]][i+1] + c[j][i];
                if(d<dp[j][i]){
                       dp[j][i] = d ;
                        s[j][i] = r[k];
                    }
                }
            }
        }
    int ans = INF, t = 0;
    for(int i = 0 ; i < n; i++){
        if(dp[i][0]<ans){
            ans = dp[i][0];
            t = i;
        }
    }
    cout<<t+1;
    for(int i = 0; i < m - 1; i++){
          t = s[t][i];
         cout<<' '<<t+1;

    }
        cout<<endl<<ans<<endl;
    }
}

你可能感兴趣的:(UVA 116_ Unidirectional TSP)