zoukankan      html  css  js  c++  java
  • 「BalticOI 2011」Switch the Lamp On

    Casper is designing an electronic circuit on a (N imes M) rectangular grid plate. There are (N imes 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 imes 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
    "); 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
    ", d[id(n+1, m+1)]);
    	return 0;
    }
    
  • 相关阅读:
    简单工厂设计模式-模拟磁盘打开文件
    使用GDI绘制验证码
    nginx笔记.
    git 笔记
    ubuntu错误解决。
    测试那些事儿—简述CPU的工作原理
    田螺便利店—win10专业版激活码
    田螺便利店—PyCharm安装第三方库
    田螺便利店—命令提示符总是提示不是内部外部命令
    田螺便利店—ipconfig命令不是内部命令或外部命令怎么解决?
  • 原文地址:https://www.cnblogs.com/greyqz/p/11862967.html
Copyright © 2011-2022 走看看