旅行商问题就是每个点都要走到,一般用DP解决。

避免调太久存个模板。

点的编号为1~m。

memset(dp,INF,sizeof(dp));
for(int i=1;i<=m;i++)
{
    dp[1<<(i-1)][i]=0;
    //printf("(%d,%d)\n",1<<(i-1),i);
}
for(int i=0;i<(1<<m);i++)    //两个循环的次序不能交换
{
    for(int j=1;j<=m;j++)
    {
        if((1<<(j-1))&i)
        {
            /*printf("i=%d j=%d|",i,j);
            for(int l=m-1;l>=0;l--)
                printf("%d",i>>l&1);
            printf("\n");*/
            for(int k=1;k<=m;k++)
            {
                if(((1<<(k-1))&i)&&k!=j&&dis[k][j]!=-1)
                {
                    int temp=i-(1<<(j-1));
                    //printf("k=%d|",k);
                    /*for(int l=m-1;l>=0;l--)
                        printf("%d",temp>>l&1);
                    printf("\n");*/
                    dp[i][j]=min(dp[i][j],dp[temp][k]+dis[k][j]);
                    //printf("dp[%d][%d]=%d\n",i,j,dp[i][j]);
                }
            }
        }
    }
}
int ans=INF;
for(int i=1;i<=m;i++)
    ans=min(ans,dp[(1<<m)-1][i]);
if(ans==INF)printf("-1\n");
else printf("%d\n",ans);

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

GCPC2015D 贪心+DFS Previous
BAPC2014FinalA 按时间拆点+最大流 Next