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. 使用C6748和C5509A对nRF24L01驱动进行数据传输

    1. 写在前面 今天下午做了一个C5509A和C6748两个DSP的数据传输,经由RF24L01设备传输,都是模拟SPI协议,对于两个DSP来说,无非是配GPIO引脚,写好时序和延时.C5509A的G ...

  2. django中的ContentType使用

    使用背景 最近设计表的时候遇到一个问题,有两门课程  一门专业课,一门学位课,我们按照时间长度来进行售卖,比如专业课一个月19元,两个月35元,三个月50元. 可以这么做但是领导不让我这么设计.... ...

  3. ruby URI类

    一. URI require 'uri' uri = URI("http://foo.com/posts?id=30&limit=5#time=1305298413") # ...

  4. HDU暑假多校第四场J-Let Sudoku Rotate

    一.题意 Sudoku is a logic-based, combinatorial number-placement puzzle, which is popular around the wor ...

  5. SpringMVC接收前端传值有哪些方式?

    有很多种,比如: 1.通过@RequestParam注解接收请求参数: 2.通过Bean封装,接收多个请求参数 3.通过@ModelAttribute绑定接收前端表单数据 4.通过@PathVaria ...

  6. React获取数据,假如为数组,使用map出现的问题

    在平时做项目的时候,使用到了redux, 如果获取服务器端的数据,例如返回一个  data = [1,2,3,4]data.map(item => item*2) , 这样使用的话如果数据正常获 ...

  7. [CH5302]金字塔

    题面 虽然探索金字塔是极其老套的剧情,但是有一队探险家还是到了某金字塔脚下.经过多年的研究,科学家对这座金字塔的内部结构已经有所了解.首先,金字塔由若干房间组成,房间之间连有通道.如果把房间看作节点, ...

  8. Python图像全屏显示

    需要在嵌入式设备上全屏显示图像,使用pil显示图像时,只能通过系统的图像浏览器显示.所以使用Python自带的tkinter import Tkinter as tk   这句在Python3中已经改 ...

  9. HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)

    Problem Description   Zero and One are good friends who always have fun with each other. This time, ...

  10. Android Studio环境解读

    一.使用IDE开发APP的流程 要熟悉一个新的IDE,可依次完成以下流程: 二.相关术语解析 Dalvik: Android特有的虚拟机,和JVM不同,Dalvik虚拟机非常适合在移动终端上使用! A ...