poj 3311 (状态压缩dp)

点击打开链接


题意:给你n个点(1~n),起点在0,给出任意两点的距离,求从0出发,走过所有的点然后回到0的最短距离。。


状态压缩每个状态,枚举每个点,如果走过就求最小距离。。。


#include"stdio.h"
#include"string.h"
#define inf 100000000
int min(int x,int y)
{
	return x<y?x:y;
}
int main()
{
	int n;
	int i,j,k;
	int dis[11][11];
	int dp[1<<11][11];
	while(scanf("%d",&n)!=-1&&n)
	{
		for(i=0;i<=n;i++)
		{
			for(j=0;j<=n;j++)
				scanf("%d",&dis[i][j]);
		}
		
		for(i=0;i<=n;i++)
		{
			for(j=0;j<=n;j++)
			{
				for(k=0;k<=n;k++)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
			}
		}
		
		memset(dp,0,sizeof(dp));
		for(i=0;i<(1<<n);i++)
		{
			for(j=1;j<=n;j++)
			{
				if(i&(1<<(j-1)))
				{
					if(i==(1<<(j-1)))
						dp[i][j]=dis[0][j];//之前这写成dis[j][0],WA了一次
					else
					{
						dp[i][j]=inf;
						for(k=1;k<=n;k++)
						{
							if((i&(1<<(k-1)))&&j!=k)
								dp[i][j]=min(dp[i][j],dp[i^(1<<(j-1))][k]+dis[k][j]);
						}
					}
				}
			}
		}
		
		int ans=dp[(1<<n)-1][1]+dis[1][0];
		for(i=2;i<=n;i++)
			ans=min(ans,dp[(1<<n)-1][i]+dis[i][0]);
		printf("%d\n",ans);
	}
	return 0;
}


你可能感兴趣的:(poj,状态压缩dp)