Manhattan Wiring
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 2016   Accepted: 1162

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题目大意:找两条不相交的路径将矩阵中的2连起来并将3连起来,求最小路径长度和-2.分析:挺神的一道题.   用插头表示左括号右括号肯定是不够的.那表示什么呢?和bzoj2331类似,他要求什么就表示什么嘛. 令状态0表示不存在插头,状态2表示这个插头是连接2的插头,状态3表示这个插头是连接3的插头.   这样会有一个问题:如何确保一条路径2个2,2个3都经过呢?   可以在转移的时候强行规定:如果不存在插头,那么空地只能建一对状态相同的插头,标记2或者3的地方只能建一个状态与之对应的插头. 这一对和一个有啥区别? 一对表示这个点会经过两次2或3,一个表示这个点已经经过2或3了,只需要再经过一次即可.     转移要分很多类,参看:传送门.   总得来说就是讨论. 看当前所在格子是哪一类格子,由此可以得出转移到的格子有什么限制,再来讨论看看是否符合这些限制来进行转移.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int maxn = 60010,inf = 0x7ffffff;
int n,m,a[20][20],pow[110],ans = inf,now,pre;struct node
{int head[maxn],nextt[maxn],sum[maxn],sta[maxn],tot;void clear(){memset(head,-1,sizeof(head));tot = 0;memset(sum,127 / 3,sizeof(sum));}void push(int x,int v){int hashh = x % maxn;for (int i = head[hashh]; i >= 0; i = nextt[i]){if (sta[i] == x){sum[i] = min(sum[i],v);return;}}sum[tot] = v;sta[tot] = x;nextt[tot] = head[hashh];head[hashh] = tot++;}
}f[2];int turnleft(int x,int pos)
{return x << pow[pos];
}int get(int x,int pos)
{return (x >> pow[pos]) & 3;
}int del(int x,int i,int j)
{return x & (~(3 << pow[i])) & (~(3 << pow[j]));
}void solve2(int x,int y,int k)
{int p = get(f[pre].sta[k],y - 1);int q = get(f[pre].sta[k],y);int staa = del(f[pre].sta[k],y - 1,y);int v = f[pre].sum[k];if (staa > (1 << pow[m + 1]))return;if (a[x][y] == 1){if (p + q == 0){f[now].push(staa,v);return;}}else if (!p && !q){if (a[x][y] == 0){f[now].push(staa,v);if (a[x + 1][y] + a[x][y + 1] == 5 || a[x + 1][y] == 1 || a[x][y + 1] == 1)return;if (a[x + 1][y] == 2 || a[x][y + 1] == 2)f[now].push(staa | turnleft(2,y - 1) | turnleft(2,y),v + 1);else if (a[x + 1][y] == 3 || a[x][y + 1] == 3)f[now].push(staa | turnleft(3,y - 1) | turnleft(3,y),v + 1);else{f[now].push(staa | turnleft(2,y - 1) | turnleft(2,y),v + 1);f[now].push(staa | turnleft(3,y - 1) | turnleft(3,y),v + 1);}}else{if (a[x + 1][y] != 5 - a[x][y] && a[x + 1][y] != 1)f[now].push(staa | turnleft(a[x][y],y - 1),v + 1);if (a[x][y + 1] != 5 - a[x][y] && a[x][y + 1] != 1)f[now].push(staa | turnleft(a[x][y],y),v + 1);}}else if (p && q){if (p + q == 5 || a[x][y] != 0)return;f[now].push(staa,v + 1);}else if (p && !q){if (a[x][y] == 0){if (a[x][y + 1] == 0 || a[x][y + 1] == p)f[now].push(staa | turnleft(p,y),v + 1);if (a[x + 1][y] == 0 || a[x + 1][y] == p)f[now].push(staa | turnleft(p,y - 1),v + 1);}else if (a[x][y] == p)f[now].push(staa,v + 1);}else if (!p && q){if (a[x][y] == 0){if (a[x][y + 1] == 0 || a[x][y + 1] == q)f[now].push(staa | turnleft(q,y),v + 1);if (a[x + 1][y] == 0 || a[x + 1][y] == q)f[now].push(staa | turnleft(q,y - 1),v + 1);}else if (a[x][y] == q)f[now].push(staa,v + 1);}
}void solve()
{now = 0,pre = 1;f[0].clear();f[0].push(0,0);for (int i = 1; i <= n; i++){pre = now;now ^= 1;f[now].clear();for (int k = 0; k < f[pre].tot; k++)f[now].push(turnleft(f[pre].sta[k],1),f[pre].sum[k]);for (int j = 1; j <= m; j++){pre = now;now ^= 1;f[now].clear();for (int k = 0; k < f[pre].tot; k++)solve2(i,j,k);}}for (int i = 0; i < f[now].tot; i++)if (f[now].sta[i] == 0)ans = min(ans,f[now].sum[i]);
}int main()
{for (int i = 1; i <= 100; i++)pow[i] = i * 2;while (scanf("%d%d",&n,&m) == 2 && (n + m)){ans = inf;for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)scanf("%d",&a[i][j]);solve();if (ans == inf)puts("0");elseprintf("%d\n",ans - 2);}return 0;
}


转载于:https://www.cnblogs.com/zbtrs/p/8460609.html

poj3133 Manhattan Wiring相关推荐

  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. POJ 3133 Manhattan Wiring (插头DP)

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

  4. POJ 3133 Manhattan Wiring(限制匹配的插头DP)

    Manhattan Wiring Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 1921   Accepted: 1130 ...

  5. [LA3620]Manhattan Wiring

    [LA3620]Manhattan Wiring 试题描述 输入 输出 输入示例 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 ...

  6. 【POJ3133】Manhattan Wiring 插头DP

    原题走这里 看起来就很难的一道题 本题存在一个小陷阱,它看起来像是单回路模型(毕竟是求路径),然而它其实是多回路模型,或者说可以用多回路模型做. 这道题求的是最短距离,那么这就意味着如果出现了多出来的 ...

  7. POJ 3133 Manhattan Wiring(插头DP)

    题目链接:http://poj.org/problem?id=3133 题意:n*m的格子中有两个2和两个3,其余是空白或障碍.找出两条路径分别连接2和3,不经过障碍且不相交.使得两条路径长度和最短? ...

  8. POJ 3133 Manhattan Wiring

    辣鸡题目,毁我青春,费我时间,害我性命. 白书上的题目,轮廓线状压DP真是无爱了. 思考半小时,代码两小时TAT,我又回忆起了NOIP上写的那个脑残状压DP了,坑爹的优化...... 不过好歹1A了是 ...

  9. POJ 3133 Manhattan Wiring 笔记

    n*m矩阵,1 代表障碍物,如图,要求连线 2 与连线 3 不能有交点.求两个连线和的最小长度.

最新文章

  1. 底盘智能化的关键技术探讨
  2. Python 列表(List) 取区间元素 [:] 用法
  3. JPA学习---第五节:日期和枚举等字段类型的JPA映射
  4. felzenszwalb算法_学习图像场景解析的理论和应用(二)场景解析的经典算法分析之SLIC...
  5. protobuf扫盲
  6. 利用FPGA实现外设通信接口之:利用FPGA实现USB 2.0通信接口
  7. javaweb简单的登录增删改查系统_利用python操作小程序云数据库实现简单的增删改查!
  8. [转载] python radians函数_Python numpy.radians() 使用实例
  9. 经典视觉SLAM框架
  10. mysql多条件顺序_mysql顺序由多个条件
  11. 计算机三角符号,word标尺倒三角 word倒三角符号
  12. 幕布笔记按字母顺序导出(Python+Opml)
  13. office起动缓慢_如何解决Microsoft Outlook启动缓慢的问题
  14. 《纽约客》:还原真实的扎克伯格
  15. net start命令发生系统错误5和错误1058的解决方法
  16. 平安京s9服务器维护,决战平安京S9赛季段位怎么继承_决战平安京S9赛季段位继承详情_素材吧...
  17. VGA带音频转HDMI转换芯片|VGA转HDMI 转换器方案|VGA转HDMI1.4转换器芯片介绍
  18. 西安三本计算机专业可报院校,西安三本大学前十名, 西北大学现代学院仅第四...
  19. 职业高一计算机试题,信息技术教师考试题库
  20. python pie函数_matplotlib 知识点11:绘制饼图(pie 函数精讲)

热门文章

  1. win10 系统的blos界面打开方法
  2. 谷粒商城最全报错笔记
  3. java 动画 很少人_java – 这个我正在制作动画的正方形背后有一条小道,任何人都可以找出原因吗?...
  4. 9. Fabric2.2 区块链农产品溯源系统 - 多组织集群部署
  5. RFID第二版答案-第一章
  6. Go语言channel的底层
  7. 微信8.0状态视频无水印素材+个人设置技巧(最全小白教程)
  8. 移动端GIS功能开发
  9. 根据身份证获取信息(性别,生日,年龄,是否正确,生肖,星座)
  10. 怎么学习短视频剪辑?怎样快速上手?