poj3133 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的更多相关文章
- [Poj3133]Manhattan Wiring (插头DP)
Description 题目大意:给你个N x M(1≤N, M≤9)的矩阵,0表示空地,1表示墙壁,2和3表示两对关键点.现在要求在两对关键点之间建立两条路径,其中两条路径不可相交或者自交(就是重复 ...
- [LA3620]Manhattan Wiring
[LA3620]Manhattan Wiring 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入” 题解 我们把“连线”的过程改为“铺地砖”的过程,总共有 11 种地砖,每种地砖上 ...
- 【poj3133】 Manhattan Wiring
http://poj.org/problem?id=3133 (题目链接) 题意 $n*m$的网格里有空格和障碍,还有两个$2$和两个$3$.要求把这两个$2$和两个$3$各用一条折线连起来.障碍里不 ...
- 【POJ】3133 Manhattan Wiring
http://poj.org/problem?id=3133 题意:n×m的网格,有2个2,2个3,他们不会重合.还有障碍1.现在求2到2的路径和3到3的路径互不相交的最短长度-2.(2<=n, ...
- poj 3133 Manhattan Wiring
http://poj.org/problem?id=3133 考虑插头 dp 用四进制表示一个插头的状态,0 表示没有插头,2 表示这个插头是连接两个 2 的,3 同理 然后就是大力分类讨论了 这题还 ...
- uva1214 Manhattan Wiring 插头DP
There is a rectangular area containing n × m cells. Two cells are marked with “2”, and another two w ...
- POJ 3133 Manhattan Wiring (插头DP,轮廓线,经典)
题意:给一个n*m的矩阵,每个格子中有1个数,可能是0或2或3,出现2的格子数为2个,出现3的格子数为2个,要求将两个2相连,两个3相连,求不交叉的最短路(起终点只算0.5长,其他算1). 思路: 这 ...
- caioj1496: [视频]基于连通性状态压缩的动态规划问题:Manhattan Wiring
%%%%orz苏大佬 虽然苏大佬的baff吸不得,苏大佬的梦信不得,但是膜苏大佬是少不得的囧 这题还是比较有收获的 哼居然有我不会做的插头DP 自己yy了下,2表示属于2的插头,3表示3的插头 假如当 ...
- 别人整理的DP大全(转)
动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...
随机推荐
- STL 一些常用的STL函数(持续更新
先说一下 一边要用到算法的东西一般要加#include<algorithm>头文件 一.栈和队列 1 栈 :一种线性表 特点 后进先出 头文件 #include<stack&g ...
- poj1050 dp动态规划
Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any ...
- 台湾ML笔记--1.1什么时候适合使用ML
适用情况: 1 exists some 'underlying pattern' to be learned --so 'performance measure' can be imporoved 例 ...
- valgrind检查still reachable情况
valgrind --leak-check=yes检查bufr编解码程序运行时提示still reachable: 568 bytes in 1 blocks,如下图示: 于是怀疑有内存泄漏,难道是m ...
- What to do when Enterprise Manager is not able to connect to the database instance (ORA-28001)
摘自:http://dbtricks.com/?p=34 If you are trying to connect to the Oracle enterprise Manger and you ge ...
- VSCode 前端必备插件
VSCode 前端必备插件 Debugger for Chrome 让 vscode 映射 chrome 的 debug功能,静态页面都可以用 vscode 来打断点调试 { "versio ...
- Wordpress 从 MySQL 获取文章链接 permalinks
SELECT wpp.post_title, wpp.guid, wpp.post_date, REPLACE( REPLACE( REPLACE( REPLACE( wpo.option_value ...
- 《python机器学习—预测分析核心算法》:构建预测模型的一般流程
参见原书1.5节 构建预测模型的一般流程 问题的日常语言表述->问题的数学语言重述重述问题.提取特征.训练算法.评估算法 熟悉不同算法的输入数据结构:1.提取或组合预测所需的特征2.设定训练目标 ...
- AMR无限增发代币至任意以太坊地址的漏洞利用及修复过程
AMR无限增发代币至任意以太坊地址的漏洞利用及修复过程 0x00 项目简述 Ammbr主要目标是打造具有高度弹性且易于连接的分布式宽带接入平台,同时降低上网相关成本.Ammbr打算创建具有人工智能和智 ...
- 完整Android开发基础入门博客专栏
博客地址:http://www.runoob.com/w3cnote/android-tutorial-contents.html