HDU 1619 Unidirectional TSP (dp,dfs)
题目大意:要求从左边到右边(注意第1行和最后一行相邻),即:从第1列到最后一列即可,共有三种走法,求最小的代价及打印行号。
三种走法,

Sample Input
5 6 3 4 1 2 8 6 6 1 8 2 7 4 5 9 3 9 9 5 8 4 1 3 2 6 3 7 2 8 6 4 5 6 3 4 1 2 8 6 6 1 8 2 7 4 5 9 3 9 9 5 8 4 1 3 2 6 3 7 2 1 2 3 2 2 9 10 9 10
Sample Output
1 2 3 4 4 5 16 1 2 1 5 4 5 11 1 1 19
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 222
#define inf 1<<30
int map[MAXN][MAXN];
int dp[MAXN][MAXN];
int n,m,len;
int path[MAXN];
int dfs(int x, int y)
{
if(dp[x][y]!=inf)
return dp[x][y];
if(y==m-1)
return dp[x][y]=map[x][y];
int ans=min(min(dfs((x-1+n)%n,y+1),dfs(x,y+1)),dfs((x+1)%n,y+1));
return dp[x][y]=ans+map[x][y];
}
void Solve(int x, int y)
{
path[len++]=x;
if(y==m-1)return ;
int x1=(x-1+n)%n, x2=x, x3=(x+1)%n;
for(int i=0;i<n;i++)
{
if(dp[x][y]==dp[i][y+1]+map[x][y]&&(i==x1||i==x2||i==x3))
{
Solve(i,y+1);
return ;
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(dp,0,sizeof(dp));
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
dp[i][j]=inf;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&map[i][j]);
int ans=inf,pos;
for(int i=0;i<n;i++)
{
if(dfs(i,0)<ans)
{
ans=dp[i][0];
pos=i;
}
}
len=0;
Solve(pos,0);//从第一列的第pos行往后找路径(dp[pos][0]即为最小值)
printf("%d",path[0]+1);
for(int i=1;i<len;i++)
printf(" %d",path[i]+1);
printf("\n%d\n",ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
浙公网安备 33010602011771号