问题 A: 电路维修

时间限制1 Sec  内存限制128 MB
提交16  解决7
[
提交][状态][讨论版][命题人:add_shengjunjie][Edit] [TestData]

题目链接:http://acm.ocrosoft.com/problem.php?cid=1694&pid=0

题目描述

        Ha’nyu是来自异世界的魔女,她在漫无目的的四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上。Rika家里有一辆飞行车。有一天飞行车的电路板突然出现了故障,导致无法正常启动。

        电路板的整体结构是一个RC列的网格,如图所示。每一个格点都是电线的接点。每个格子都包含一个电子元件。电子元件的主要部分是一个可旋转的,连接一条对角线上的两个连接点的短电缆。在旋转之后,它就可以连接另一条对角线的两个接点。电路板左上角的接点接入直流电源,右下角的接点接入飞行车的发动装置。

        Ha‘nyu发现因为某些元件的方向不小心发生了改变,电路板可能处于断路状态。她准备通过计算,旋转最少数量的元件,使电源与发动装置通过若干条短电缆相连。不过电路的规模实在太大了,Ha‘nyu不擅长编程,希望你能够帮她解决这个问题。

输入

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

输出

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

样例输入

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

样例输出

1

 

思路:二维数组不好建地图,所以用邻接表去建图,化二维地图用一维去存,利用权值为0的不可叠加性,用双端队列去BFS。


代码:

#include<bits/stdc++.h>

using namespace std;

#define maxn 1000

#define INF 0x3f3f3f3f

int n, m;

char tt[maxn][maxn];//存地图

int dis[maxn*maxn];

int ans = INF;

struct edge

{

    int e, w;//终点和路程

    edge(int _e, int _w)//构造函数初始化

    {

         e = _e;

         w = _w;

    }

};

vector<edge>Map[maxn*maxn];//建邻接表

void add_edge(int x, int y, int z)

{

    Map[x].push_back(edge(y, z));

}

int bfs(int s, int t)

{

    for (int i = 0; i < maxn*maxn; i++)dis[i] = INF;//双端队列BFS

    deque<int>p;

    p.push_back(s);

    dis[s] = 0;

    while (!p.empty())

    {

         int Now = p.back();

         p.pop_back();

         if (Now == t) return dis[Now];

         for (int i = Map[Now].size() - 1; i >= 0; i--)

         {

             int u = Map[Now][i].e, c = Map[Now][i].w;

             if (dis[u] > dis[Now] + c)

             {

                  dis[u] = dis[Now] + c;

                  if (c == 0)

                      p.push_back(u);//若边权为0放在后面

                  else

                      p.push_front(u);//若边权为1放在前面

             }

         }

    }

    return dis[t];



}

int main()

{

    int T;

    cin >> T;

    while (T--)

    {

         ans = INF;

         for (int i = 0; i <= maxn * maxn; i++)Map[i].clear();//邻接表清空

         cin >> n >> m;

         for (int i = 1; i <= n; i++)

         {

             for (int j = 1; j <= m; j++)

             {

                  cin >> tt[i][j];

             }

         }

         //zuo

         for (int i = 1; i <= n; i++)

         {

             for (int j = 1; j <= m; j++)

             {



                  add_edge((i - 1)*(m + 1) + j, i*(m + 1) + j - 1, tt[i][j] != '/');//将二维图转化为一维图

                  add_edge(i*(m + 1) + j - 1, (i - 1)*(m + 1) + j, tt[i][j] != '/');

                  add_edge((i - 1)*(m + 1) + j - 1, i*(m + 1) + j, tt[i][j] == '/');

                  add_edge(i*(m + 1) + j, (i - 1)*(m + 1) + j - 1, tt[i][j] == '/');



             }

         }

         ans = bfs(0, n*(m + 1) + m);

         if (ans == INF)cout << "NO SOLUTION" << endl;

         else cout << ans << endl;

    }

}