UVa 116 Unidirectional TSP(简单旅行商DP)

题意:

求代价最小的一条路径。

思路:

由于要求路径,并且要求输出字典顺序最小的序列。所以逆向求DP,模仿dfs,将降低解题难度。

#include <cstdio>

#include <cstdlib>

#include <cstring>



#define min(a,b) (((a) < (b)) ? (a) : (b))



int map[15][105];

int dp[15][105], path[15][105];

int n, m;



int main()

{

    while (scanf("%d %d", &n, &m) != EOF)

    {

        for (int i = 0; i < n; ++i)

            for (int j = 0; j < m; ++j)

                scanf("%d", &map[i][j]);



        memset(dp, 0, sizeof(dp));

        memset(path, 0,sizeof(path));



        for (int j = m - 1; j >= 0; --j)

        {

            for (int i = 0; i < n; ++i)

            {

                int a = dp[(i-1+n)%n][j+1];

                int b = dp[i][j+1];

                int c = dp[(i+1)%n][j+1];

                int mm;

                if (a > b)

                    mm = min(b, c);

                else

                    mm = min(a, c);



                dp[i][j] = map[i][j] + mm;

                

                path[i][j] = 1e9;



                if (mm == a)

                    path[i][j] = (i - 1 + n) % n;



                if (mm == b)

                    path[i][j] = min(path[i][j], i);



                if (mm == c)

                    path[i][j] = min(path[i][j], (i + 1) % n);

            }

        }

        int ans = 1e9;

        int id;

        for (int i = 0; i < n; ++i)

            if (ans > dp[i][0])

                ans = dp[i][0], id = i;



        printf("%d", id + 1);

        id = path[id][0];



        for (int j = 1; j < m; ++j)

        {

            printf(" %d", id + 1);

            id = path[id][j];

        }



        printf("\n%d\n", ans);

    }

    return 0;

}

你可能感兴趣的:(uva)