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 }

 

posted @ 2015-07-31 22:00  miao_a_miao  阅读(139)  评论(0编辑  收藏  举报