对于经典的TSP问题,不想再多说什么了,大致意思就是一个人从某城市出发经过n个城市且只经过一次最后回到出发点走过的最短路程。
这个题目大意就是这样,和经典TSP问题差不多。 大白书上有很详细解释。page63
设f(i,s)表示当前在城市i,访问s中的城市各一次回到起始城市的最短距离,方程为:
f(i,s)=min(f(j,s-{j}+distance(i,j)|j属于s};
这个题目大意就是这样,和经典TSP问题差不多。 大白书上有很详细解释。page63
设f(i,s)表示当前在城市i,访问s中的城市各一次回到起始城市的最短距离,方程为:
f(i,s)=min(f(j,s-{j}+distance(i,j)|j属于s};
边界条件是他经过某个城市时直接到达那个城市,就是从起点直接到那个城市。可以在O(n^2*2^n)内实现。
本题的话,可以floyd预处理出距离,然后根据上面讲的状压dp即可。
/****************************
* author:crazy_石头
* date:2014/01/18
* time:0 ms
* algorithm:状压dp+floyd
* Pro:POJ 3311
***************************/
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 1<<29
#define eps 1e-8
#define A system("pause")
#define rep(i,h,n) for(int i=(h);i<=(n);i++)
#define ms(a,b) memset((a),(b),sizeof(a))
const int maxn=12;
const int maxm=150000+10;
int map[maxn][maxn],dp[1<<11][maxn],n;//总共只有11种状态;
inline void floyd()
{
rep(k,0,n) rep(i,0,n) rep(j,0,n)
map[i][j]=std::min(map[i][k]+map[k][j],map[i][j]);
}
int main()
{
while(~scanf("%d",&n)&&n)
{
rep(i,0,n) rep(j,0,n) scanf("%d",&map[i][j]);
floyd();
for(int s=0;s<(1<