zoukankan      html  css  js  c++  java
  • 【广搜】电路维修

    题目描述

    Ha'nyu是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上。Rika的家里有一辆飞行车。有一天飞行车的电路板突然出现了故障,导致无法启动。
    电路板的整体结构是一个R行C列的网格(R,C≤500),如右图所示。每个格点都是电线的接点,每个格子都包含一个电子元件。电子元件的主要部分是一个可旋转的、连接一条对角线上的两个接点的短电缆。在旋转之后,它就可以连接另一条对角线的两个接点。电路板左上角的接点接入直流电源,右下角的接点接入飞行车的发动装置。
    Ha'nyu发现因为某些元件的方向不小心发生了改变,电路板可能处于断路的状态。她准备通过计算,旋转最少数量的元件,使电源与发动装置通过若干条短缆相连。不过,电路的规模实在是太大了,Ha'nyu并不擅长编程,希望你能够帮她解决这个问题。

    输入

    输入包含多组测试数据。第一行包含一个整数T 表示测试数据的数目。
    对于每组测试数据,第一行包含正整数R 和C,表示电路板的行数和列数。
    之后R 行,每行C 个字符,字符是"/"和""中的一个,表示标准件的方向。

    输出

    对于每组测试数据,在单独的一行输出一个正整数,表示所需的缩小旋转次数。
    如果无论怎样都不能使得电源和发动机之间连通,输出NO SOLUTION。

    样例输入

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

    样例输出

    1

    提示

    对于40% 的数据,R,C≤5。
    对于100% 的数据,R,C≤500,T≤5。
    样例解释
    样例的输入对应于题目描述中的情况。
    只需要按照下面的方式旋转标准件,就可以使得电源和发动机之间连通。

    【思路】

      这个是一个边权为要么1,要么0的无向图,在这样的图上,我们可以通过双端队列广搜搜索来计算。算法的整体框架与一般的广搜类似,只是在每个结点上沿分支扩展时稍作改变。如果这条分支是边权为0的边,就把沿该分支到达的新结点从队头入队;如果这条分支是边权为1的边,就像一般的广搜搜索一样从队尾入队,这样一来,我们就仍能保证任意时刻广搜搜索队列中的结点对应的距离都具有”两段性“和”单调性“,每个结点从队头出队时,就能得到从左上角到该节点的最短距离。

      因为每个节点只需要访问一次,所以算法的时间复杂度为O(R*C)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N = 505;
     4 int dis[N][N];
     5 char s[N][N];
     6 int n,m;
     7 typedef struct Node {
     8     int x,y;
     9 }Node;
    10 deque <Node> Q ;
    11 void Push ( int x,int y,int s,int k ){
    12     if( s+k < dis[x][y] ){
    13         dis[x][y] = s+k ;
    14         if(!k)    Q.push_front ( Node{x,y} );
    15         else     Q.push_back ( Node{x,y} ) ;
    16     }
    17 }
    18 int dir[4][2] = {
    19     {-1,-1} , {-1,1},
    20     {1,-1}, {1,1}
    21 };
    22 char Str[] = {"\//\"};
    23 void BFS(){
    24     memset(dis,0x7f,sizeof dis);
    25     Q.push_front ( Node{1,1} ) ;
    26     dis[1][1] = 0 ;
    27     while ( !Q.empty() ){
    28         Node cur = Q.front();
    29         Q.pop_front();
    30         int x = cur.x , y = cur.y ;
    31         for(int i=0;i<4;i++){
    32             int tx = x + dir[i][0] ;
    33             int ty = y + dir[i][1] ;
    34             int dx = x + (dir[i][0] == 1 ? 0:-1) ;
    35             int dy = y + (dir[i][1] == 1 ? 0:-1) ;
    36             if( 1 <= tx && tx <= n+1 && 1 <= ty && ty <= m+1 ){
    37                 Push(tx,ty,dis[x][y], ( Str[i] != s[dx][dy] ));
    38             }
    39         }
    40     }
    41     printf("%d
    ",dis[n+1][m+1]);
    42 }
    43 int main()
    44 {
    45     int T;
    46     for(scanf("%d",&T);T;T--){
    47         scanf("%d%d",&n,&m);
    48         for(int i=1;i<=n;i++){
    49             scanf("%s",s[i]+1 );
    50         }
    51         if( (n+m)&1 ){
    52             printf("NO SOLUTION
    ");
    53         }else{
    54             BFS();
    55         }
    56     }
    57     return 0;
    58 }
    电路维修
  • 相关阅读:
    微信小程序学习系列(5) 微信小程序逻辑层
    微信小程序学习系列(4) 微信小程序架构文件
    微信小程序学习系列(3) 如何优雅的使用微信开发者工具
    使用Sqlserver 2012 导出表数据为SQL脚本
    Sqlserver2012 使用sql语句增加(或删除)表一个字段
    微信小程序学习系列(2) 使用AppId创建一个微信小程序
    微信小程序学习系列(1) 如何注册微信小程序
    微信小程序如何使用Vant
    vs2017搭建自己的nuget服务器
    使用swagger实现在线api文档自动生成 在线测试api接口
  • 原文地址:https://www.cnblogs.com/Osea/p/11214534.html
Copyright © 2011-2022 走看看