1.1 TSP商旅问题 coj1133(TSP是NP难问题一般只会到16)
题意:某乡有n个村庄(16>n>1),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(1000>s>0)是已知的,且A村到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。
代码:
#include <stdio.h>
#include <string.h>
#include<iostream>
using namespace std;
const int SIZE= 16;
const int MAX= 1000*SIZE;
int dp[SIZE+2][(1<<SIZE)+10], w[SIZE+3][SIZE+3];
int run(int n, int s)
{
int sta= 1<<(n+1);
for(int i= 0; i<= n; i++)
for(int j= 0; j< sta; j++) dp[i][j]= MAX;
dp[s][1<<s]= 0;
//对于n个点会有2^(n+1)种状态
//代表的状态
for(int i= 0; i< sta; ++i)
for(int j= 0; j<= n; ++j)
{
//1<<j==2^j
//右移位j个单位判断当前状态i城市是否在考虑范围中
if(((1<<j)&i)== 0) continue;
for(int k= 0; k<= n; ++k)
{
//如果点没有访问过且可以更新
if(((1<<k)&i)== 0 )
dp[k][(1<<k)|i]= min(dp[k][(1<<k)|i],dp[j][i]+ w[j][k]);
}
}
return dp[n][sta-1];
}
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i= 0; i< n; i++)
{
for(int j= 0; j< n; j++)
scanf("%d", &w[i][j]);
//拆点,因为最后形成的是环,所以将第一个点加到后面n
//如果跑了一遍最短路就可以不用拆点
w[i][n]= w[i][0];
}
int ans= run(n, 0);
printf("%d\n", ans);
}
return 0;
}
1.2 双调TSPpoj2677
题意:双调