传送门:http://poj.org/problem?id=3133
Manhattan Wiring
Time Limit: 5000MS   Memory Limit: 65536K
     

Description

There is a rectangular area containing n × m cells. Two cells are marked with “2”, and another two with “3”. Some cells are occupied by obstacles. You should connect the two “2”s and also the two “3”s with non-intersecting lines. Lines can run only vertically or horizontally connecting centers of cells without obstacles.

Lines cannot run on a cell with an obstacle. Only one line can run on a cell at most once. Hence, a line cannot intersect with the other line, nor with itself. Under these constraints, the total length of the two lines should be minimized. The length of a line is defined as the number of cell borders it passes. In particular, a line connecting cells sharing their border has length 1.

Fig. 1(a) shows an example setting. Fig. 1(b) shows two lines satisfying the constraints above with minimum total length 18.

Figure 1: An example of setting and its solution

Input

The input consists of multiple datasets, each in the following format.

n m
row1
rown

n is the number of rows which satisfies 2 ≤ n ≤ 9. m is the number of columns which satisfies 2 ≤ m ≤ 9. Each rowi is a sequence of m digits separated by a space. The digits mean the following.

0: Empty

1: Occupied by an obstacle

2: Marked with “2”

3: Marked with “3”

The end of the input is indicated with a line containing two zeros separated by a space.

Output

For each dataset, one line containing the minimum total length of the two lines should be output. If there is no pair of lines satisfying the requirement, answer “0” instead. No other characters should be contained in the output.

Sample Input

5 5
0 0 0 0 0
0 0 0 3 0
2 0 2 0 0
1 0 1 1 1
0 0 0 0 3
2 3
2 2 0
0 3 3
6 5
2 0 0 0 0
0 3 0 0 0
0 0 0 0 0
1 1 1 0 0
0 0 0 0 0
0 0 2 3 0
5 9
0 0 0 0 0 0 0 0 0
0 0 0 0 3 0 0 0 0
0 2 0 0 0 0 0 2 0
0 0 0 0 3 0 0 0 0
0 0 0 0 0 0 0 0 0
9 9
3 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 3
9 9
0 0 0 1 0 0 0 0 0
0 2 0 1 0 0 0 0 3
0 0 0 1 0 0 0 0 2
0 0 0 1 0 0 0 0 3
0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
9 9
0 0 0 0 0 0 0 0 0
0 3 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 2 3 2
0 0

Sample Output

18
2
17
12
0
52
43

Source

Japan 2006
花了两天时间 把代码风格变成正规插头dp了。
代码是orz别人的:
#include<set>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int STATE = 59049+1000;
const int Mod = 10007;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,l,r) for(int i=l;i<=r;i++)
#define Down(i,r,l) for(int i=r;i>=l;i--)struct statedp{int head[Mod],next[STATE],f[STATE],state[STATE];int size;void clear(){memset(head,-1,sizeof(head));size = 0;}void push(int st,int ans){int Key = st % Mod;for(int p = head[Key];p!=-1;p=next[p])if(st==state[p]){f[p] = min(f[p],ans);return;}state[size] = st;f[size] = ans;next[size] = head[Key];head[Key] = size++;}
}dp[2];int n,m,maze[12][12],code[12];void init(){For(i,n)For(j,m)scanf("%d",&maze[i][j]);
}void dpblock(int i,int j,int cur){int Lim = (j==m) ? (2) : (0);Rep(i,0,dp[cur].size-1)dp[cur^1].push(dp[cur].state[i] >> Lim , dp[cur].f[i]);
}void shift(){Down(i,m,1) code[i] = code[i-1];code[0] = 0;
}int encode(){int ret = 0;Rep(i,0,m) ret = ret << 2 | code[i];return ret;
}void decode(int st){Down(i,m,0) code[i] = st & 3 , st >>= 2;
}void dpblank(int i,int j,int cur){Rep(k,0,dp[cur].size-1){decode(dp[cur].state[k]);int Left = code[j-1] , Up = code[j];if(maze[i][j]>=2){if(Left&&Up) continue;int CODE = (maze[i][j]==2)?(1):2;if(Left||Up){if(Left+Up!=CODE) continue;code[j-1] = code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]);}else{if(i<n && maze[i+1][j] != 1){code[j-1] = CODE; code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]);}if(j<m && maze[i][j+1] != 1){code[j-1] = 0; code[j] = CODE;dp[cur^1].push(encode(),dp[cur].f[k]);}}        continue;}if(Left && Up){if(Left!=Up) continue;code[j-1] = code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]+1);}else if(Left || Up){int CODE = Left | Up;if(i<n && maze[i+1][j]!=1){code[j-1] = CODE; code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]+1);}if(j<m && maze[i][j+1]!=1){code[j-1] = 0; code[j] = CODE;dp[cur^1].push(encode(),dp[cur].f[k]+1);}}else{if(!maze[i][j]){if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]);}if(i<n && j<m && maze[i+1][j]!=1 && maze[i][j+1]!=1){code[j-1] = code[j] = 1;dp[cur^1].push(encode(),dp[cur].f[k]+1);code[j-1] = code[j] = 2;dp[cur^1].push(encode(),dp[cur].f[k]+1);} }}
}void DP(){int cur = 0;dp[0].clear();dp[0].push(0,0);For(i,n)For(j,m){dp[cur^1].clear();if(maze[i][j]==1) dpblock(i,j,cur);else              dpblank(i,j,cur);cur^=1;}int ans = 2147483647;Rep(i,0,dp[cur].size-1) ans = min(ans,dp[cur].f[i]);if(ans==2147483647) ans = -2;printf("%d\n",ans+2);
}int main(){while(scanf("%d%d",&n,&m),m+n){init();DP();}return 0;
}

转载于:https://www.cnblogs.com/zjdx1998/p/3915598.html

POJ3133(插头dp)相关推荐

  1. [POJ3133]Manhattan Wiring 插头dp

    [POJ3133]Manhattan Wiring 插头dp 原题POJ3133 题意:N*M有障碍矩阵,0可通过,1为障碍,两个2,两个3,求连接两个2和连接两个3的两条不相交路径长度和的最小值(1 ...

  2. [Poj3133]Manhattan Wiring (插头DP)

    Description 题目大意:给你个N x M(1≤N, M≤9)的矩阵,0表示空地,1表示墙壁,2和3表示两对关键点.现在要求在两对关键点之间建立两条路径,其中两条路径不可相交或者自交(就是重复 ...

  3. bzoj1814 Ural 1519 Formula 1(插头dp模板题)

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 924  Solved: 351 [Submit][S ...

  4. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...

  5. HDU4084 插头dp

    题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...

  6. P3272 [SCOI2011]地板(插头DP)

    [题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...

  7. POJ 3133 Manhattan Wiring (插头DP)

    Manhattan Wiring Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 1110   Accepted: 634 D ...

  8. URAL1519 Formula 1 —— 插头DP

    题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB ...

  9. [集训队作业2018]小Z的礼物(min-max容斥,插头dp)

    传送门 这种求 "取到所有物品的期望时间" 的题一般都用 min−maxmin-maxmin−max容斥 解决: 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j ...

最新文章

  1. Centos查找命令清单
  2. GCJ 2015-Qualification-B Infinite House of Pancakes 枚举,思路,误区 难度:3
  3. ubuntu16.4下用jexus部署asp.net core rtm
  4. 将Jersey与Spring整合
  5. java applet 访问文件_使用JavaApplet访问数据库
  6. JAVA minaio模型_分布式系统之Java IO模型
  7. flinkCdc的mysql配置及java测试代码
  8. java面向对象的理解_面向对象及其核心的概念:抽象、继承与多态、封装
  9. 使用Redis存取数据+数据库存取(spring+java)
  10. 推荐这5款Windows软件,一款比一款惊喜
  11. 批量将txt文件转为csv文件
  12. property follows cocoa naming convention for returning ‘owned‘ objects
  13. Spring源码剖析 循环注入
  14. 换个方式认识一下——微信公众号搜索公众号列表 API
  15. VSCode常用插件和字体设置
  16. rand和srand怎么用?
  17. 专家纵论智能机器社会的风险与解决方案
  18. java计算机毕业设计网上购物商城源代码+数据库+系统+lw文档
  19. it Ebook 免费
  20. 数学知识整理:不定积分

热门文章

  1. 一张脑图说清 Nginx 的主流程
  2. 从事数据科学前必须知道的五件事儿
  3. Resource interpreted as Stylesheet but transferred with MIME type application/x-css
  4. Exchange2010 初始化失败
  5. DOM操作之属性和样式操作
  6. 如何实现蓝牙空中升级BLE OTA
  7. 【IT笔试面试题整理】连续子数组的最大和
  8. 跨域请求设置withCredentials
  9. IIS 支持 ajax 跨域
  10. ios开发之UIView的frame、bounds跟center属性的区别(附图)