UVa116 Unidirectional TSP

来源:互联网 发布:mac无法删除app 编辑:程序博客网 时间:2024/06/04 18:13

一个求最短路的题目,算不上是TSP吧,只是普通的dp,不过要打印字典序最小的路径,一开始是由后向前递推,结果悲剧了。。。原来打印字典序最小要从前向后递推的,结果后面还是WA了,然后人品爆发,发现一开始打印路径的起始条件为最小权和,终止条件是print_path(int row,int col,int sum)中的sum==0,但其实在中途就有可能会sum==0的,因为节点可以是负数,改成col==n-1就AC了,嘿嘿

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>using namespace std;long g[12][102],d[12][102];const long inf=1<<30;int m,n;void print_path(int row,int col,long sum){    printf("%d",row+1);    sum-=g[row][col];    if(col==n-1) return;    printf(" ");    if(row==0)    {        if(d[row][col+1]==sum)//向右走            {                print_path(row,col+1,sum);                return;            }        if(d[row+1][col+1]==sum)//向右下方走            {                print_path(row+1,col+1,sum);                return;            }            print_path(m-1,col+1,sum);//循环转到第m-1行            return;    }    if(row==m-1)    {        if(d[0][col+1]==sum)//循环转到第0行        {            print_path(0,col+1,sum);            return;        }        if(d[row-1][col+1]==sum)//向右上方走            {                print_path(row-1,col+1,sum);                return;            }                print_path(row,col+1,sum);//向右走                return;    }    if(d[row-1][col+1]==sum)//向右上方走        {            print_path(row-1,col+1,sum);            return;        }    if(d[row][col+1]==sum)//向右走        {            print_path(row,col+1,sum);            return;        }        print_path(row+1,col+1,sum);}int main(){    //以下注释为生成随机数测试样例代码,可无视/*    freopen("in.txt","w",stdout);//    srand((unsigned)time(NULL));//    int t=rand()%10+1;//    printf("%d\n",t);//    while(t--)//    {//        m=rand()%10+1,n=rand()%100+1;//        printf("%d %d\n",m,n);//        for(int i=0;i<m;i++)//            {//                for(int j=0;j<n;j++)//                {//                    if(rand()%2)//                    {//                        g[i][j]=rand();//                    }//                    else//                    {//                        g[i][j]=-rand();//                    }//                    printf("%ld ",g[i][j]);//                }//                printf("\n");//            }//    }//    return 0;*/    //freopen("in.txt","r",stdin);    //freopen("myout.txt","w",stdout);    while(scanf("%d%d",&m,&n)!=EOF)    {        memset(g,0,sizeof(g));        for(int i=0;i<m;i++)            for(int j=0;j<n;j++)                scanf("%ld",&g[i][j]);            for(int j=0;j<m;j++)                {                    for(int k=0;k<n;k++)                    {                        d[j][k]=inf;                    }                }            for(int k=0;k<m;k++)                d[k][n-1]=g[k][n-1];            for(int j=n-2;j>=0;j--)                for(int k=0;k<m;k++)                    {                        long temp=d[(k-1+m)%m][j+1]+g[k][j];//去右上方                        if(temp<d[k][j])//站在k行,j列,到第n-1列的和最小值                        {                            d[k][j]=temp;                        }                        temp=d[k][j+1]+g[k][j];//去右边                        if(temp<d[k][j])                        {//                            d[j][k]=min(d[j][k],d[j-1][k]+g[k][j]);                            d[k][j]=temp;                        }                        temp=d[(k+1)%m][j+1]+g[k][j];//去右下方                        if(temp<d[k][j])                        {//                            d[j][k]=min(d[j][k],d[j-1][(k+1)%m]+g[k][j]);                            d[k][j]=temp;                        }                    }            long minnum=inf;            int row;            for(int k=0;k<m;k++)                {                    if(d[k][0]<minnum)                    {                        row=k;                        minnum=d[k][0];                    }                    //printf("%ld ",d[n-1][k]);                }                print_path(row,0,minnum);                printf("\n%ld\n",minnum);    }    return 0;}


原创粉丝点击