Casper is designing an electronic circuit on a \(N \times M\) rectangular grid plate. There are \(N \times M\) square tiles that are aligned to the grid on the plate. Two (out of four) opposite corners of each tile are connected by a wire.

A power source is connected to the top left corner of the plate. A lamp is connected to the bottom right corner of the plate. The lamp is on only if there is a path of wires connecting power source to lamp. In order to switch the lamp on, any number of tiles can be turned by 90° (in both directions).

In the picture above the lamp is off. If any one of the tiles in the second column from the right is turned by 90° , power source and lamp get connected, and the lamp is on.

Write a program to find out the minimal number of tiles that have to be turned by 90° to switch the lamp on.

有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会。

有 \(N\times M\) 个这样的元件,你想将其排列成 \(N\) 行 \(M\) 列放在电路板上。电路板的左上角连接电源,右下角连接灯泡。

试求:至少要旋转多少个正方形元件才能让电源与灯泡连通。 \(1 \le N,M \le 500\)。

原电路连边权为 0 的边,反向对角线连边权为 1 的边,求最短路。

暴力解法:Dijkstra 堆优化,堆要用手写堆或 STL 手动堆。

正解:边权仅为 0 或 1 的图,显然用 deque 广搜,边权为 0 的 push_front,边权为 1 的 push_back。

以下是 暴力解法。正解不会写……

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; int n, m, d[260005];
char str[505]; bool v[260005];
int head[260005], nex[260005<<2], to[260005<<2], w[260005<<2];
struct node {
int t, d;
bool operator < (const node& A) const {return d>A.d; }
};
node q[260005<<2]; int qt; inline int id(const int& x, const int& y) {
return (x-1)*(m+1)+y;
}
inline void add(const int& x, const int& y, const int& z) {
nex[++head[0]]=head[x], head[x]=head[0], to[head[0]]=y, w[head[0]]=z;
nex[++head[0]]=head[y], head[y]=head[0], to[head[0]]=x, w[head[0]]=z;
} int main() {
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
scanf("%s", str+1);
for (int j=1; j<=m; ++j) {
if (str[j]=='/') add(id(i, j+1), id(i+1, j), 0), add(id(i, j), id(i+1, j+1), 1);
else add(id(i, j), id(i+1, j+1), 0), add(id(i, j+1), id(i+1, j), 1);
}
}
if ((n+m)&1) {printf("NO SOLUTION\n"); return 0; }
memset(d, 0x3f, sizeof d);
q[++qt]=(node) {id(1,1), d[id(1,1)]=0}; push_heap(q+1, q+qt+1);
while (qt) {
register node now=q[1]; pop_heap(q+1, q+qt+1), --qt;
if (v[now.t]) continue; v[now.t]=true;
for (int i=head[now.t]; i; i=nex[i]) if (d[now.t] + w[i] < d[to[i]]) {
d[to[i]]= d[now.t]+ w[i], q[++qt]=(node) {to[i], d[to[i]]}, push_heap(q+1, q+qt+1);
}
}
printf("%d\n", d[id(n+1, m+1)]);
return 0;
}

「BalticOI 2011」Switch the Lamp On的更多相关文章

  1. 「CTSC 2011」排列

    「CTSC 2011」排列 要求不存在公差为 A 或者公比为 B 的子列,那么实际上可以把该问题转化为求一个图的最优拓朴序. 任意差为 A 或者比为 B 的两个数连一条边. 求一个合法序列的答案可以用 ...

  2. 「CTSC 2011」幸福路径

    [「CTSC 2011」幸福路径 蚂蚁是可以无限走下去的,但是题目对于精度是有限定的,只要满足精度就行了. \({(1-1e-6)}^{2^{25}}=2.6e-15\) 考虑使用倍增的思想. 定义\ ...

  3. LOJ#2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On

    题目描述 译自 BalticOI 2011 Day1 T3「Switch the Lamp On」有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会.有 N×M 个这样 ...

  4. 「BZOJ 2342」「SHOI 2011」双倍回文「Manacher」

    题意 记\(s_R\)为\(s\)翻转后的串,求一个串最长的形如\(ss_Rss_R\)的子串长度 题解 这有一个复杂度明显\(O(n)\)的做法,思路来自网上某篇博客 一个双倍回文串肯定当且仅当本身 ...

  5. 「BZOJ 2434」「NOI 2011」阿狸的打字机「AC自动机」

    题意 有一个打字机,支持三种操作: 字符串末尾加一个小写字母 字符串末尾减一个字符 输出这个字符串 经过不超过\(n\)次操作后有\(m\)组询问:\((x,y)\),表示第\(x\)次输出第字符串在 ...

  6. loj 2778「BalticOI 2018」基因工程

    loj luogu 这题和NOI那道向量内积一个套路 首先考虑求两行的不同元素个数,可以转化成一个行向量\(a\)和列向量\(b\)相乘得到一个值.如果只有\(A,C\)两种字符,那么令对应权值\(A ...

  7. 「BalticOI 2020」病毒

    AC自动机+DP最短路转移 怎么说呢,挺套路的,也不是太难,但是一上手会被大量的信息淹没思路,还是要注意关注主要信息,不要被一些细节卡住 由于抗体是要在基因序里面出现过,那么考虑把抗体的序列检出AC自 ...

  8. Solution -「POI 2011」「洛谷 P3527」MET-Meteors

    \(\mathcal{Description}\)   Link.   给定一个大小为 \(n\) 的环,每个结点有一个所属国家.\(k\) 次事件,每次对 \([l,r]\) 区间上的每个点点权加上 ...

  9. PHP丨PHP基础知识之条件语SWITCH判断「理论篇」

    Switch在一些计算机语言中是保留字,其作用大多情况下是进行判断选择.以PHP来说,switch(开关语句)常和case break default一起使用 典型结构 switch($control ...

随机推荐

  1. Kinect V2入门之数据获取步骤

    在Kinect for windows SDK2.0中,获取并处理数据源接口步骤如下: Sensor -> Source -> Reader -> Frame -> Data ...

  2. Python 入门之常用运算符

    Python 入门之常用运算符 Python中的运算按种类可分为算数运算.比较运算.逻辑运算.赋值运算.成员运算.身份运算.位运算 1.常用运算符: (1)算数运算符: + - * / %(取余(模) ...

  3. 排列perm HYSBZ - 1072(状压dp/暴力)

    Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input ...

  4. jQuery之链式编程

    使用的思想:隐式迭代. <button>快速</button> <button>快速</button> <button>快速</but ...

  5. 00.AutoMapper 之入门指南(Getting Started Guide)

    转载(https://www.jianshu.com/p/29ee5a94c1d9) 入门指南(Getting Started Guide) AutoMapper 是什么? AutoMapper 是一 ...

  6. windows 桌面背景设置实例

    应用SystemParametersInfo函数可以获取和设置数量众多的windows系统参数.这个小程序就是运用了SystemParametersInfo函数来设置桌面的墙纸背景,而且程序可以让我们 ...

  7. 电子邮件协议:SMTP、POP3、IMAP4

    常见的电子邮件协议:SMTP.POP3.IMAP4   邮件发送协议:SMTP协议 邮件读取协议:POP3.IMAP4协议   SMTP协议(simple mail transfer protocol ...

  8. Apache 网站日志分析

    1.获得访问前 10 位的 ip 地址 [root@apache ~]# cat access_log |awk '{print $1}'|sort|uniq -c|sort -nr|head -10 ...

  9. mysql查询每个直播间每个用户最早进入时间和最晚退出时间

    myself_sql = 'select room_id,source_id user_id,min(cast(at as datetime)) joinroom,max(cast(at as dat ...

  10. mybatis返回自增主键问题踩坑

    1 <insert id="insert" keyProperty="id" useGeneratedKeys="true"
 par ...