hdu 4026 2011上海赛区网络赛F TSP ****
没看过TSP,先mark
1 //4838039 2011-10-27 23:04:15 Accepted 4026 2343MS 31044K 3143 B C++ Geners 2 //状态压缩DP的TSP问题 3 //优先级位运算小于判等 , 还有各种细节各种出错 4 #include <cstdio> 5 #include <cstring> 6 #include <stdlib.h> 7 #define mabs(a) (a>0?a:-(a)) 8 9 using namespace std; 10 11 typedef long long ll; 12 const int maxn=1<<17; 13 int gcd(int a, int b) 14 { 15 return b?gcd(b, a%b):a; 16 } 17 18 int g[7][7]; 19 int map[7][7], cnt; 20 int n, m; 21 ll dp[maxn][30]; 22 struct Node { 23 int x,y; 24 }node[20]; 25 26 void init () 27 { 28 for (int i=0 ; i<7 ; ++i) 29 for (int j=0 ; j<7 ; ++j) 30 g[i][j]=gcd(i, j); 31 } 32 33 bool valid(int sta, int k, int pre) 34 { 35 int x=node[k].x,xx=node[pre].x; 36 int y=node[k].y,yy=node[pre].y; 37 38 if(map[x][y]>0 || map[xx][yy]>0) 39 return false;//如果2个点不都是0。 40 int d=g[mabs(x-xx)][mabs(y-yy)]; 41 for (int i=1 ; i<=d ; ++i) 42 { 43 int tmpx=xx+i*(x-xx)/d; 44 int tmpy=yy+i*(y-yy)/d; 45 if(map[tmpx][tmpy] == 1) 46 return false;//中间点forbidden 47 if(map[tmpx][tmpy] <= 0) 48 { 49 if((sta&(1<<(-map[tmpx][tmpy]))) == 0) 50 { 51 return false; 52 }//中间有未遍历的0。 53 } 54 } 55 return true; 56 } 57 58 void DP() 59 { 60 memset (dp, 0, sizeof(dp)); 61 int limit=1<<cnt; 62 for (int i=0 ; i<limit ; ++i) 63 { 64 for (int j=0 ; j<cnt ; ++j) 65 { 66 dp[1<<j][j]=1ll;//初始以每个点开始的情况 67 if(i&(1<<j)) 68 for (int k=0 ; k<cnt ; ++k) 69 { 70 if(k==j)continue; 71 if(i^(1<<j)& (1<<k) ) //k是从此时出发的点,j是要去的点 72 if(valid(i,j,k)) 73 { 74 dp[i][j]+=dp[i^(1<<j)][k]; 75 } 76 } 77 } 78 } 79 ll ans=0ll; 80 for (int i=0 ; i<cnt ; ++i) 81 ans+=dp[limit-1][i]; 82 printf("%I64d\n", ans); 83 84 } 85 86 int main () 87 { 88 init (); 89 while (~scanf("%d%d", &n, &m)) 90 { 91 cnt=0; 92 for (int i=0 ; i<n ; ++i) 93 { 94 for (int j=0 ; j<m ; ++j) 95 { 96 scanf("%d",&map[i][j]); 97 if(map[i][j] == 0) 98 { 99 node[cnt].x=i; 100 node[cnt].y=j; 101 map[i][j]=-cnt;//映射到小于等于0 102 cnt++; 103 } 104 //printf(" %d \n",map[i][j]); 105 } 106 } 107 DP(); 108 } 109 return 0; 110 }