标签:uva116 unidirectional tsp dp 路径打印
题意:找最短路,知道三种行走方式,给出图,求出一条从左边到右边的最短路,且字典序最小。
思路:用dp记忆化搜索的思想来考虑是思路很清晰的,状态方程:max{ dp[i+1,j+1], dp[i,j+1], dp[i-1,j+1]},
但是困难在如何求出字典序最小的路。
因为左边到右边的字典序最小就必须从左边开始找,于是我们可以换个思路,dp时从右边走到左边,这样寻找路径就可以从左向右了。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<algorithm> #include<cstdlib> #include<set> #include<queue> #include<stack> #include<vector> #include<map> #define N 100010 #define Mod 10000007 #define lson l,mid,idx<<1 #define rson mid+1,r,idx<<1|1 #define lc idx<<1 #define rc idx<<1|1 const double EPS = 1e-11; const double PI = acos(-1.0); const double E=2.718281828; typedef long long ll; const int INF=2147483647; using namespace std; int a[11][110]; int d[12][120],next[120][110]; int main() { //freopen("in.txt","r",stdin); int n,m; while(cin>>m>>n) { for(int i=0; i<m; i++) for(int j=0; j<n; j++) scanf("%d",&a[i][j]); int ans=INF,first=0; //cout<<ans<<endl; 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 row[3]= {i,i-1,i+1}; if(i==0) row[1]=m-1; if(i==m-1) row[2]=0; sort(row,row+3); d[i][j]=INF; for(int k=0; k<3; k++) { int v=d[row[k]][j+1]+a[i][j]; if(v<d[i][j]) d[i][j]=v,next[i][j]=row[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("\n%d\n",ans); } return 0; }
UVa 116 - Unidirectional TSP(dp)
标签:uva116 unidirectional tsp dp 路径打印
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/40402539