UVA - 116多段图的最短路

Unidirectional TSP

在这里插入图片描述
本题的最短路与“数字三角形问题”的思路是极其相似的,最后一列为底层状态,从最后一列一列一列的向前更新。
主要是路径记录(尤其要求是字典序),再用一个数组path[][]记录下父节点,最后循环输出。

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int inf = (1<<30)+1000;
int m,n,map[15][105],path[15][105],d[15][105];
int main(){
    while(~scanf("%d%d",&m,&n))
    {
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&map[i][j]);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                d[i][j] = inf;
//        ms0(path);
        for(int j=n;j>=1;j--)
        {
            for(int i=1;i<=m;i++)
            {
                if(j==n) d[i][j]=map[i][j];
                else{
                    int op[] = {i,i-1,i+1};
                    if(i==1) op[1]=m;
                    if(i==m) op[2]=1;
                    sort(op, op+3);//要排序,要求是字典序
                    for(int k=0;k<3;k++)
                    {
                        int cost = map[i][j]+d[op[k]][j+1];
                        if(cost<d[i][j])
                        {
                            d[i][j]=cost;
                            path[i][j]=op[k];
                        }
                    }
                }
            }
        }
        int ans = inf,first=0;
        for(int i=1;i<=m;i++)
        {
            if(d[i][1]<ans)
            {
                ans=d[i][1];
                first = i;
            }
        }
        printf("%d",first);
        for(int j=1,i=path[first][j];j<=n-1;i=path[i][++j])
        {
            printf("% d",i);
        }
        printf("\n%d\n",ans);
    }
    return 0;
}
发布了67 篇原创文章 · 获赞 0 · 访问量 1507

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/104580548