这题没什么难度,按列从后往前递推就行了。刚开始老是WA,原来是没注意到“lexicographically smallest ”,英文不好的童鞋桑不起啊!这个按最小字典序输出还真是头疼,我用的是记录路径,而不是递归打印,只好略加改动了。
1 #include<stdio.h>
2 int m,n,route[12][105],f[12][105];
3 int main()
4 {
5 int i,j,t,min,flag;
6 while(scanf("%d%d",&m,&n)==2)
7 {
8 for(i = 0; i < m; i++)
9 for(j = 0; j < n; j++)
10 scanf("%d",&f[i][j]);
11 for(j = n-2; j >= 0; j--)
12 for(i = 0; i < m; i++)
13 {
14 min = f[i][j+1];
15 flag = i;
16 t = (i-1)>-1 ?i-1 :m-1;
17 if(f[(i+1)%m][j+1] < min)
18 min = f[(i+1)%m][j+1],
19 flag = (i+1)%m;
20 else if(f[(i+1)%m][j+1] == min && (i+1)%m < flag)
21 flag = (i+1)%m;
22 if(f[t][j+1] < min)
23 min = f[t][j+1],
24 flag = t;
25 else if(f[t][j+1] == min && t < flag)
26 flag = t;
27 f[i][j] += min;
28 route[i][j] = flag;
29 }
30 min = f[0][0];
31 flag = 0;
32 for(i = 1; i < m; i++)
33 if(f[i][0] < min)
34 min = f[i][0],
35 flag = i;
36 else if(f[i][0] == min && i < flag)
37 flag = i;
38 printf("%d",flag+1);
39 for(j = 0; j < n-1; j++)
40 flag = route[flag][j],
41 printf(" %d",flag+1);
42 printf("\n%d\n",min);
43 }
44 return 0;
45 }