zoukankan      html  css  js  c++  java
  • hdu--4856--状压dp

    我都不想将bfs这3个字写在标题里...bfs没那么简单

    就是求出任意两个管子之间的最短距离  但这边不能直接用spfa dij啊什么的   但感觉现在的bfs就有点相当于退化版的最短路。。

    这题的重点还是在完成上面的Precompute后 接下去的求tsp操作

    这边应该是最简单的 没有多余的难度增加的求tsp

    我这提供了2种 我分别加上注释

    tot 就是总的状态

     1     for( int i = 2 ; i<=tot ; i++ )//枚举状态
     2     {
     3         for( int j = 1 ; j<=m ; j++ )//枚举管子
     4         {
     5             if( i&(1<<j) ) //在该状态下已经走过
     6                 continue;
     7             for( int k = 1 ; k<=m ; k++ )
     8             {
     9                 if( i&(1<<k) ) //在该状态下已经走过 去 未达到的管子
    10                     dp[ i|(1<<j) ][j] = min( dp[ i|(1<<j) ][j] , dp[i][k]+dist[k][j] );
    11             }    
    12         }
    13     }
     1     for( int i = 2 ; i<=tot ; i++ )//枚举状态
     2     {
     3         for( int j = 1 ; j<=m ; j++ )//枚举管子
     4         {
     5             if( i&(1<<j) )//从该状态下已经到达的管子出发
     6             {
     7                 for( int k = 1 ; k<=m ; k++ )
     8                 {
     9                     if( !( i&(1<<k) ) )//从该状态下已经到达的管子出发 去 还没有到达的管子
    10                         dp[ i|(1<<k) ][k] = min( dp[ i|(1<<k) ][k] , dp[i][j] + dist[j][k] );
    11                 }
    12             }
    13         }
    14     }

    其实2者没什么差 就是写法上有点区别 我觉得第二种写法更好.

      1 #include <iostream>
      2 #include <cstring>
      3 #include <queue>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 int n , m , tot;
      8 const int size = 20;
      9 const int inf = 0x3f3f3f3f;
     10 int dir[4][2] = {1,0,-1,0,0,1,0,-1};
     11 int dp[1<<16][size];
     12 bool vis[size][size];
     13 int dist[size][size];
     14 char mp[size][size];
     15 
     16 struct data
     17 {
     18     int sx , sy , endx , endy;
     19     int step;
     20     data(){};
     21     data( int u , int v , int w ):endx(u),endy(v),step(w){};
     22 }pipe[size];
     23 
     24 void init( )
     25 {
     26     memset( dp , inf , sizeof(dp) );
     27     for( int i = 1 ; i<=m ; i++ )
     28         dp[1<<i][i] = 0;
     29 }
     30 
     31 int bfs( int from , int to )
     32 {
     33     queue<data> q;
     34     data now;
     35     now.endx = pipe[from].sx;
     36     now.endy = pipe[from].sy;
     37     now.step = 0;
     38     q.push( now );
     39     memset( vis , false , sizeof(vis) );
     40     vis[ now.endx ][ now.endy ] = true;
     41     while( !q.empty( ) )
     42     {
     43         now = q.front();
     44         q.pop();
     45         if( now.endx == pipe[to].endx && now.endy == pipe[to].endy )
     46         {
     47             return now.step;
     48         }
     49         for( int i = 0 ; i<4 ; i++ )
     50         {
     51             int xx = now.endx + dir[i][0];
     52             int yy = now.endy + dir[i][1];
     53             if( xx >=1 && xx<=n && yy>=1 && yy<=n && mp[xx][yy]!='#' && !vis[xx][yy] )
     54             {
     55                 vis[xx][yy] = true;
     56                 q.push( data(xx,yy,now.step+1) );
     57             }
     58         }
     59     }
     60     return inf;
     61 }
     62 
     63 void solve( )
     64 {
     65     for( int i = 1 ; i<=m ; i++ )
     66     {
     67         for( int j = 1 ; j<=m ; j++ )
     68         {
     69             if( i==j )
     70                 dist[i][j] = 0;
     71             else
     72                 dist[i][j] = bfs( i , j );
     73         }
     74     }
     75     for( int i = 2 ; i<=tot ; i++ )
     76     {
     77         for( int j = 1 ; j<=m ; j++ )
     78         {
     79             if( i&(1<<j) ) 
     80                 continue;
     81             for( int k = 1 ; k<=m ; k++ )
     82             {
     83                 if( i&(1<<k) ) 
     84                     dp[ i|(1<<j) ][j] = min( dp[ i|(1<<j) ][j] , dp[i][k]+dist[k][j] );
     85             }    
     86         }
     87     }
     88 }
     89     
     90 int main()
     91 {
     92     cin.sync_with_stdio(false);
     93     int ans;
     94     while( cin >> n >> m )
     95     {
     96         init( );
     97         for( int i = 1 ; i<=n ; i++ )
     98         {
     99             for( int j = 1 ; j<=n ; j++ )
    100             {
    101                 cin >> mp[i][j];
    102             }
    103         }
    104         for( int i = 1 ; i<=m ; i++ )
    105         {
    106             cin >> pipe[i].sx >> pipe[i].sy >> pipe[i].endx >> pipe[i].endy; 
    107         }
    108         tot = ( 1<<(m+1) ) - 2;
    109         init( );
    110         solve( );
    111         ans = inf;
    112         for( int i = 1 ; i<=m ; i++ )
    113         {
    114             ans = min( ans , dp[ tot ][i] );
    115         }
    116         if( ans==inf )
    117             cout << -1 << endl;
    118         else
    119             cout << ans << endl;
    120     }
    121     return 0;
    122 }
    View Code

    today:

      first love 

  • 相关阅读:
    Socket异步通信
    以读取博客园随笔备份为例 将xml 序列化成json,再序列化成对象
    NhibernateProfiler写个自动破解工具
    关于下载GAE High Replication Datastore数据
    .text 0.958 数据添加
    C#实现RTP数据包传输参照RFC3550
    在线商城表结构
    相似字符串
    .net 4.0 的Socket写的支持跨平台双工的轻量级通讯组件
    写一个迷你版Smarty模板引擎,对认识模板引擎原理非常好(附代码)
  • 原文地址:https://www.cnblogs.com/radical/p/4140908.html
Copyright © 2011-2022 走看看