zoukankan      html  css  js  c++  java
  • 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
    ", 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 
    ",map[i][j]);
    105             }
    106         }
    107         DP();
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    Linux cat
    Linux touch
    Win10 UAP 绑定
    Win10 资源文件
    Win10 启动模拟器
    Win10 安装Vs2015 社区版和企业版各个问题汇总
    Win10 开发者模式开启
    android 入门-本地化语言
    android 入门-基础了解
    wp8 入门到精通 定时更新瓷贴
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4693255.html
Copyright © 2011-2022 走看看