Unidirectional TSP UVA

题目:题目链接

思路:从后往前进行dp,用next数组记录字典序最小的那一条路径

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>

#define INF 0x3f3f3f3f

#define FRER() freopen("in.txt", "r", stdin);
#define FREW() freopen("out.txt", "w", stdout);

using namespace std;

const int maxn = 100 + 5;

int main()
{
    //FRER();
    ios::sync_with_stdio(0);
    cin.tie(0);

    int m, n, a[maxn][maxn], d[maxn][maxn], next[maxn][maxn];
    while(cin >> m >> n) {
        for(int i = 0; i < m; ++i) 
            for(int j = 0; j < n; ++j)
                cin >> a[i][j];
        int ans = INF, first = 0;
        for(int j = n - 1; j >= 0; --j) {
            for(int i = 0; i < m; ++i) {
                if(j == n - 1) d[i][j] = a[i][j];
                else {
                    int rows[3] = {i, i - 1, i + 1};
                    if(i == 0) rows[1] = m - 1;
                    if(i == m - 1) rows[2] = 0;
                    sort(rows, rows + 3);
                    d[i][j] = INF;
                    for(int k = 0; k < 3; ++k) {
                        int v = d[rows[k]][j + 1] + a[i][j];
                        if(v < d[i][j]) {
                            d[i][j] = v;
                            next[i][j] = rows[k];
                        }
                    }
                }
                if(j == 0 && d[i][j] < ans) {
                    ans = d[i][j];
                    first = i;
                }
            }
        }
        printf("%d", first + 1);
        for(int i = next[first][0], j = 1; j < n; i = next[i][j], ++j)
            printf(" %d", i + 1);
        printf("
%d
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fan-jiaming/p/10004130.html