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 = ,inf = 0x7ffffff;
int n,m,a[][],pow[],ans = inf,now,pre; struct node
{
int head[maxn],nextt[maxn],sum[maxn],sta[maxn],tot;
void clear()
{
memset(head,-,sizeof(head));
tot = ;
memset(sum, / ,sizeof(sum));
}
void push(int x,int v)
{
int hashh = x % maxn;
for (int i = head[hashh]; i >= ; 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[]; int turnleft(int x,int pos)
{
return x << pow[pos];
} int get(int x,int pos)
{
return (x >> pow[pos]) & ;
} int del(int x,int i,int j)
{
return x & (~( << pow[i])) & (~( << pow[j]));
} void solve2(int x,int y,int k)
{
int p = get(f[pre].sta[k],y - );
int q = get(f[pre].sta[k],y);
int staa = del(f[pre].sta[k],y - ,y);
int v = f[pre].sum[k];
if (staa > ( << pow[m + ]))
return;
if (a[x][y] == )
{
if (p + q == )
{
f[now].push(staa,v);
return;
}
}
else if (!p && !q)
{
if (a[x][y] == )
{
f[now].push(staa,v);
if (a[x + ][y] + a[x][y + ] == || a[x + ][y] == || a[x][y + ] == )
return;
if (a[x + ][y] == || a[x][y + ] == )
f[now].push(staa | turnleft(,y - ) | turnleft(,y),v + );
else if (a[x + ][y] == || a[x][y + ] == )
f[now].push(staa | turnleft(,y - ) | turnleft(,y),v + );
else
{
f[now].push(staa | turnleft(,y - ) | turnleft(,y),v + );
f[now].push(staa | turnleft(,y - ) | turnleft(,y),v + );
}
}
else
{
if (a[x + ][y] != - a[x][y] && a[x + ][y] != )
f[now].push(staa | turnleft(a[x][y],y - ),v + );
if (a[x][y + ] != - a[x][y] && a[x][y + ] != )
f[now].push(staa | turnleft(a[x][y],y),v + );
}
}
else if (p && q)
{
if (p + q == || a[x][y] != )
return;
f[now].push(staa,v + );
}
else if (p && !q)
{
if (a[x][y] == )
{
if (a[x][y + ] == || a[x][y + ] == p)
f[now].push(staa | turnleft(p,y),v + );
if (a[x + ][y] == || a[x + ][y] == p)
f[now].push(staa | turnleft(p,y - ),v + );
}
else if (a[x][y] == p)
f[now].push(staa,v + );
}
else if (!p && q)
{
if (a[x][y] == )
{
if (a[x][y + ] == || a[x][y + ] == q)
f[now].push(staa | turnleft(q,y),v + );
if (a[x + ][y] == || a[x + ][y] == q)
f[now].push(staa | turnleft(q,y - ),v + );
}
else if (a[x][y] == q)
f[now].push(staa,v + );
}
} void solve()
{
now = ,pre = ;
f[].clear();
f[].push(,);
for (int i = ; i <= n; i++)
{
pre = now;
now ^= ;
f[now].clear();
for (int k = ; k < f[pre].tot; k++)
f[now].push(turnleft(f[pre].sta[k],),f[pre].sum[k]);
for (int j = ; j <= m; j++)
{
pre = now;
now ^= ;
f[now].clear();
for (int k = ; k < f[pre].tot; k++)
solve2(i,j,k);
}
}
for (int i = ; i < f[now].tot; i++)
if (f[now].sta[i] == )
ans = min(ans,f[now].sum[i]);
} int main()
{
for (int i = ; i <= ; i++)
pow[i] = i * ;
while (scanf("%d%d",&n,&m) == && (n + m))
{
ans = inf;
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++)
scanf("%d",&a[i][j]);
solve();
if (ans == inf)
puts("");
else
printf("%d\n",ans - );
} return ;
}
												

poj3133 Manhattan Wiring的更多相关文章

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

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

  2. [LA3620]Manhattan Wiring

    [LA3620]Manhattan Wiring 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入” 题解 我们把“连线”的过程改为“铺地砖”的过程,总共有 11 种地砖,每种地砖上 ...

  3. 【poj3133】 Manhattan Wiring

    http://poj.org/problem?id=3133 (题目链接) 题意 $n*m$的网格里有空格和障碍,还有两个$2$和两个$3$.要求把这两个$2$和两个$3$各用一条折线连起来.障碍里不 ...

  4. 【POJ】3133 Manhattan Wiring

    http://poj.org/problem?id=3133 题意:n×m的网格,有2个2,2个3,他们不会重合.还有障碍1.现在求2到2的路径和3到3的路径互不相交的最短长度-2.(2<=n, ...

  5. poj 3133 Manhattan Wiring

    http://poj.org/problem?id=3133 考虑插头 dp 用四进制表示一个插头的状态,0 表示没有插头,2 表示这个插头是连接两个 2 的,3 同理 然后就是大力分类讨论了 这题还 ...

  6. uva1214 Manhattan Wiring 插头DP

    There is a rectangular area containing n × m cells. Two cells are marked with “2”, and another two w ...

  7. POJ 3133 Manhattan Wiring (插头DP,轮廓线,经典)

    题意:给一个n*m的矩阵,每个格子中有1个数,可能是0或2或3,出现2的格子数为2个,出现3的格子数为2个,要求将两个2相连,两个3相连,求不交叉的最短路(起终点只算0.5长,其他算1). 思路: 这 ...

  8. caioj1496: [视频]基于连通性状态压缩的 动态规划问题:Manhattan Wiring

    %%%%orz苏大佬 虽然苏大佬的baff吸不得,苏大佬的梦信不得,但是膜苏大佬是少不得的囧 这题还是比较有收获的 哼居然有我不会做的插头DP 自己yy了下,2表示属于2的插头,3表示3的插头 假如当 ...

  9. 别人整理的DP大全(转)

    动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...

随机推荐

  1. Vue 服务器端渲染(一)

    什么是服务器端渲染(SSR)? Vue.js 是构建客户端应用程序的框架.默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM.然而,也可以将同一个组件渲染为服务器端的 HT ...

  2. ruby编码说明

    程序编码一般分几种情况: 1.源码文件编码 2.接收外部内容的编码 3.运行环境编码 4.操作系统编码 首先源码文件的编码,可以通过在ruby文件的头部添加一行申明即可,这样所有在源码里面出现的字符都 ...

  3. mysql 筛选重复名称

    CREATE TABLE `blur_article` ( `id` ) NOT NULL, `name` ) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=In ...

  4. 「LibreOJ#516」DP 一般看规律

    首先对于序列上一点,它对答案的贡献只有与它的前驱和后驱(前提颜色相同)构成的点对, 于是想到用set维护每个颜色,修改操作就是将2个set暴力合并(小的向大的合并),每次插入时更新答案即可 颜色数要离 ...

  5. SIMD数据并行(二)——多媒体SIMD扩展指令集

    在计算机体系中,数据并行有两种实现路径:MIMD(Multiple Instruction Multiple Data,多指令流多数据流)和SIMD(Single Instruction Multip ...

  6. 集合--数据结构与算法JavaScript描述(9)

    集合 Set 概念 (跟高中时数学课上学的集合几乎一模一样哦哈哈) 集合是一种包含不同元素的数据结构. 集合中的元素称为成员. 集合的两个最重要的特性: 集合中的成员是无序的. 集合中不允许相同成员存 ...

  7. ionic打包apkFailed to execute shell command "input,keyevent,82"" on device: Error: adb: Command failed with exit code 137

    错误代码如下 BUILD SUCCESSFUL in 12s 46 actionable tasks: 1 executed, 45 up-to-date Built the following ap ...

  8. Jersey2+swagger组建restful风格api及文档管理

    1.jar包引入 <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId& ...

  9. Qt BarChart实践

    按照帮助文档编写 运行截图 上代码 #include "widget.h" #include "ui_widget.h" Widget::Widget(QWid ...

  10. MySql数据库插入或更新报错:Cannot add or update a child row: a foreign key constraint fails

    具体报错信息: Cannot add or update a child row: a foreign key constraint fails (`xxx`.`AAA`, CONSTRAINT `t ...