首页 > 代码库 > poj3311 Hie with the Pie,状态压缩

poj3311 Hie with the Pie,状态压缩

题目链接:http://poj.org/problem?id=3311


Floyd + 状态压缩DP
题意是有N个城市(1~N)和一个PIZZA店(0),要求一条回路,从0出发,又回到0,而且距离最小。



状态:dp[S][v]表示从v出发访问剩余的所有顶点(集合S),最终回到顶点0的路径的权重总和最小值。


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 12;
const int INF = 0x3f3f3f3f;

int d[maxn][maxn];
int dp[1<<maxn][maxn];

int main()
{
	int n;
	while(~scanf("%d", &n)){	
		if(n==0) break;
		n++;
		for(int i=0; i<n; ++i){
			for(int j=0; j<n; ++j)
				scanf("%d", &d[i][j]);
		}
		for(int k=0; k<n; ++k)
		for(int i=0; i<n; ++i)
		for(int j=0; j<n; ++j)
		{
			d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
		}
		int S = 1<<n;
		for(int i=0; i<S; ++i){
			fill(dp[i], dp[i]+n, INF);
		}
		dp[S-1][0] = 0;
		for(int i=S-2; i>=0; --i){
			for(int v=0; v<n; ++v){
				for(int u=0; u<n; ++u){
					if(!(i>>u&1) ){
						dp[i][v] = min(dp[i][v], dp[i|1<<u][u]+d[v][u]);
					}
				}
			}
		}	
		printf("%d\n", dp[0][0]);
	}
	return 0;
}


poj3311 Hie with the Pie,状态压缩