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


    题目描述

    译自 BalticOI 2011 Day1 T3「Switch the Lamp On」
    有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会。
    有 N×M 个这样的元件,你想将其排列成 N 行 M 列放在电路板上。电路板的左上角连接电源,右下角连接灯泡。

    试求:至少要旋转多少个正方形元件才能让电源与灯泡连通,若无解则输出 NO SOLUTION。

    Casper is designing an electronic circuit on a N×M rectangular grid plate. There are N×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.

    输入格式

    第一行有两个整数 NN和 M。
    在接下来的 N 行中,每行有 M 个字符。每个字符均为  或 /,表示正方形元件上导线的连接方向。

    The first line of input contains two integer numbers NNN and MMM, the dimensions of the plate. In each of the following NNN lines there are MMM symbols – either  or / – which indicate the direction of the wire connecting the opposite vertices of the corresponding tile.

    输出格式

    输出共一行,若有解则输出一个整数,表示至少要旋转多少个正方形元件才能让电源与灯泡连通;若无解则输出 NO SOLUTION

    There must be exactly one line of output. If it is possible to switch the lamp on, this line must contain only one integer number: the minimal number of tiles that have to be turned to switch on the lamp. If it is not possible, output the string: NO SOLUTION

    样例

    样例输入

    3 5
    \/\
    \///
    /\\

    样例输出

    1

    数据范围与提示

    对于 40% 的数据,1N4,1M5。
    对于所有数据,1N,M500。

    题解

    唔...这题$spfa+SLF$跑的飞快

    因为跑bfs要判的东西貌似很多的样子所以我直接连边跑spfa了

    对于能够直接走的那就连一条0边,不能直接走就连1边

    然后注意坐标位置的取值...

    因为边权只有0和1所以SLF在这里很有用

    最后就是空间要乘个8倍

    #include <bits/stdc++.h>
    
    #define ll long long
    #define inf 0x3f3f3f3f 
    #define il inline 
    
    #define in(a) a=read()
    #define out(a) printf( "%d" , a ) 
    #define outn(a) out(a),putchar('
    ')
    
    #define I_int int
    inline I_int read() {
        
        I_int x = 0 , f = 1 ; char c = getchar() ;
        while( c < '0' || c > '9' ) {
            if( c == '-' ) f = -1 ;
            c = getchar() ;
        }
        while( c >= '0' && c <= '9' ) {
            x = (x << 1) + (x << 3) + c - 48 ;
            c = getchar() ;
        }
        return x * f ;
    }
    #undef I_int
    
    using namespace std ;
    
    const int N = 510 ;
    const int M = (500*500+10)*4 ;
    const int dx[] = {0,0,1,-1};
    const int dy[] = {-1,1,0,0};
    
    char a[ N ][ N ] ;
    int n , m ;
    int head[ M ] , d[ M ] , cnt , vis[ M ] ;
    struct node {
        int to , nxt , v ;
    } e[ M << 1 ] ;
    
    void ins( int u , int v , int w ) {
        e[ ++ cnt ].to = v ;
        e[ cnt ].nxt = head[ u ] ;
        e[ cnt ].v = w ;
        head[ u ] = cnt ;
    }
    
    bool check( int x , int y ) {
        if( x < 0 || x > n || y < 0 || y > m ) return 0 ;
        return 1 ;
    }
    
    int zb( int x , int y ) {
        return (x-1)*(m+1)+y ;
    }
    
    deque<int>q;
    
    void spfa() {
        vis[ 1 ] = 1 ;
        for( int i = 1 ; i <= (n+1)*(m+1) ; i ++ ) d[ i ] = inf ;
        d[ 1 ] = 0 ;
        q.push_front(1);
        while( !q.empty() ) {
            int u = q.front() ; q.pop_front() ;
            vis[ u ] = 0 ;
            for( int i = head[ u ] ; i ; i = e[ i ].nxt ) {
                int v = e[ i ].to ;
                if( d[ v ] > d[ u ] + e[ i ].v ) {
                    d[ v ] = d[ u ] + e[ i ].v ;
                    if( !vis[ v ] ) {
                        vis[ v ] = 1 ; 
                        if(!e[i].v) q.push_front(v);
                        else q.push_back(v) ;
                    }
                }
            }
        }
        if( d[zb(n,m)] == inf ) puts("NO SOLUTION") ;
        else outn( d[ zb(n+1,m+1) ] ) ;
    }
    
    int main() {
        in( n ) ; in( m ) ;
        for( int i = 1 ; i <= n ; i ++ ) {
            scanf( "%s" , a[ i ] + 1 ) ;
            for( int j = 1 ; j <= m ; j ++ ) {
                if( a[ i ][ j ] == '\' ) {
                    ins( zb(i,j+1) , zb(i+1,j) , 1 ) , ins( zb(i+1,j) , zb(i,j+1) , 1 ) ;
                    ins( zb(i,j) , zb(i+1,j+1) , 0 ) , ins( zb(i+1,j+1) , zb(i,j) , 0 ) ;
                }
                if( a[ i ][ j ] == '/' ) {
                    ins( zb(i,j+1) , zb(i+1,j) , 0 ) , ins( zb(i+1,j) , zb(i,j+1) , 0 ) ;
                    ins( zb(i,j) , zb(i+1,j+1) , 1 ) , ins( zb(i+1,j+1) , zb(i,j) , 1 ) ;
                }
            }
        }
        spfa() ;
    }
  • 相关阅读:
    react-router JS 控制路由跳转(转载)
    vue 将值存储到vuex 报错问题
    封装GetQueryString()方法来获取URL的value值(转载)
    vue 里面的watch 选项详解
    谷歌地图api 开发 (转载)
    es6 ...展开运算符
    关于localStorage 应用总结
    js 刷新当前页面会弹出提示框怎样将这个提示框去掉
    深入浅析JavaScript的API设计原则(转载)
    jQuery mouseover与mouseenter,mouseout与mouseleave的区别
  • 原文地址:https://www.cnblogs.com/henry-1202/p/9864777.html
Copyright © 2020-2023  润新知