There is a rectangular grid of size n×m. Each cell of the grid is colored black (‘0’) or white (‘1’). The color of the cell (i,j) is ci,j. You are also given a map of directions: for each cell, there is a direction si,j which is one of the four characters ‘U’, ‘R’, ‘D’ and ‘L’.

If si,j is ‘U’ then there is a transition from the cell (i,j) to the cell (i−1,j);
if si,j is ‘R’ then there is a transition from the cell (i,j) to the cell (i,j+1);
if si,j is ‘D’ then there is a transition from the cell (i,j) to the cell (i+1,j);
if si,j is ‘L’ then there is a transition from the cell (i,j) to the cell (i,j−1).
It is guaranteed that the top row doesn’t contain characters ‘U’, the bottom row doesn’t contain characters ‘D’, the leftmost column doesn’t contain characters ‘L’ and the rightmost column doesn’t contain characters ‘R’.

You want to place some robots in this field (at most one robot in a cell). The following conditions should be satisfied.

Firstly, each robot should move every time (i.e. it cannot skip the move). During one move each robot goes to the adjacent cell depending on the current direction.
Secondly, you have to place robots in such a way that there is no move before which two different robots occupy the same cell (it also means that you cannot place two robots in the same cell). I.e. if the grid is “RL” (one row, two columns, colors does not matter there) then you can place two robots in cells (1,1) and (1,2), but if the grid is “RLL” then you cannot place robots in cells (1,1) and (1,3) because during the first second both robots will occupy the cell (1,2).
The robots make an infinite number of moves.

Your task is to place the maximum number of robots to satisfy all the conditions described above and among all such ways, you have to choose one where the number of black cells occupied by robots before all movements is the maximum possible. Note that you can place robots only before all movements.

You have to answer t independent test cases.

Input
The first line of the input contains one integer t (1≤t≤5⋅104) — the number of test cases. Then t test cases follow.

The first line of the test case contains two integers n and m (1<nm≤106) — the number of rows and the number of columns correspondingly.

The next n lines contain m characters each, where the j-th character of the i-th line is ci,j (ci,j is either ‘0’ if the cell (i,j) is black or ‘1’ if the cell (i,j) is white).

The next n lines also contain m characters each, where the j-th character of the i-th line is si,j (si,j is ‘U’, ‘R’, ‘D’ or ‘L’ and describes the direction of the cell (i,j)).

It is guaranteed that the sum of the sizes of fields does not exceed 106 (∑nm≤106).

Output
For each test case, print two integers — the maximum number of robots you can place to satisfy all the conditions described in the problem statement and the maximum number of black cells occupied by robots before all movements if the number of robots placed is maximized. Note that you can place robots only before all movements.

Example
Input
3
1 2
01
RL
3 3
001
101
110
RLL
DLD
ULL
3 3
000
000
000
RRD
RLD
ULL
Output
2 1
4 3
2 2
题意:有一个包含n*m个格子的图形,每一个格子被染成黑色(0)或者白色(1)。每一个格子都有指定的指向,或上或下或左或右。每一个格子最多只能放置一个机器人,所有的机器人一起移动,不允许多个机器人处在同一个格子,时间是无限长的。问最多可以放置多少个机器人。在这一前提下,最多有多少机器人一开始可以放置在黑色的格子里。
思路:因为时间是无限长的,所以若想满足条件,只能无限循环,这就要求我们去找这个有向图中的所有的环,求环之前需要拓扑排序一下,将不在环中的点都给处理掉。第一个答案就是所有环的长度加起来了。那么第二个答案怎么弄呢?如图所示:

假如1的颜色是白色,2的颜色是白色,3的颜色是黑色的话,我们一开始在2,3放置机器人,那么第二个答案就是1,这样的话是最大的。因此,我们在dfs找环的时候,就把这个环延伸出去的单链也处理一下,找出这些单链以及环上面的黑色的点。但是我们怎么判断能不能在这个点上放置机器人呢?如图所示:

dis数组就是dfs的过程中处理出来的,类似于树中的深度。这个图,我们可以看到第二个答案是2,在2或者4或者6,5放置的时候,这样是最大的,我们可以发现,2和4和6对环的长度2取余都是0,他们不能同时放置机器人,而5对环的长度2取余是1,可以和2,4,6同时放置,也就是dis[i]%len这个数所代表的的点上只能放置一个(len代表环的长度)。上面那个图怎样处理出dis数组呢?我们肯定是从环上面的某一点出发,这样的话,我们反向建图,然后就可以处理出来了。
总结一下:一开始正反建图,正向建图是为了拓扑排序,处理出环;反向建图是为了从环上某一点出发,处理出dis数组,从而求出答案2.
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;const int maxx=1e6+100;
string s1[maxx];
string s2[maxx];
vector<int> in[maxx],out[maxx],bck[maxx];
int vis[maxx],deg[maxx],dis[maxx],vis1[maxx];
int n,m;inline void init()
{for(int i=0;i<=n*m+1;i++) deg[i]=0,vis[i]=0,in[i].clear(),out[i].clear(),dis[i]=0,vis1[i]=0,bck[i].clear();
}
inline int get_pos(int x,int y)
{return x*m+y;
}
inline void Topo()
{queue<int> q;for(int i=0;i<n*m;i++) if(deg[i]==1) q.push(i);while(q.size()){int u=q.front();q.pop();deg[u]--;for(int i=0;i<in[u].size();i++){deg[in[u][i]]--;if(deg[in[u][i]]==1) q.push(in[u][i]);}}
}
inline void dfs(int u,int f,int step,int &num)
{dis[u]=step;vis[u]=1;if(s1[u/m][u%m]=='0') bck[f].push_back(u);for(int i=0;i<out[u].size();i++){if(vis[out[u][i]])//这个点之前处理过,因为是有向图,所以遇到之前处理过的点,说明在环上循环。那么当前的步数,就是环的长度了。{num=step;continue;}dfs(out[u][i],f,step+1,num);}
}
int main()
{int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);init();for(int i=0;i<n;i++) cin>>s1[i];for(int i=0;i<n;i++) cin>>s2[i];int tx,cx;for(int i=0;i<n;i++){for(int j=0;j<m;j++){cx=get_pos(i,j);if(s2[i][j]=='R') tx=get_pos(i,j+1);if(s2[i][j]=='L') tx=get_pos(i,j-1);if(s2[i][j]=='U') tx=get_pos(i-1,j);if(s2[i][j]=='D') tx=get_pos(i+1,j);in[cx].push_back(tx);out[tx].push_back(cx);deg[cx]++,deg[tx]++;}}Topo();int ans1=0,ans2=0,num=0;for(int i=0;i<n*m;i++){if(deg[i]&&!vis[i]){dfs(i,i,1,num=0);ans1+=num;for(int j=0;j<bck[i].size();j++){if(vis1[dis[bck[i][j]]%num]==0){vis1[dis[bck[i][j]]%num]=1;ans2++;}}for(int j=0;j<bck[i].size();j++) vis1[dis[bck[i][j]]%num]=0;//在这里还要都归零,不要影响下次使用}}printf("%d %d\n",ans1,ans2);}return 0;
}

努力加油a啊,(o)/~

Robots on a Grid CodeForces - 1335F(拓扑排序+正反建图+判环)相关推荐

  1. HDU 4857 逃生 【拓扑排序+反向建图+优先队列】

    逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  2. 【算法】图(一)拓扑排序的实现 图的邻接表算法 判断是否图G中存在环

    文章目录 用list来表示图,判断是否存在环 邻接表实现拓扑排序 用DFS(邻接矩阵) 来实现拓扑排序. 判断无向图顶点是否全部连通 判断图G中从顶点u到v是否存在简单路径 输出图G中从顶点u到v的所 ...

  3. 图论--拓扑排序--判断一个图能否被拓扑排序

    拓扑排序的实现条件,以及结合应用场景,我们都能得到拓扑排序适用于DAG图(Directed Acyclic Graph简称DAG)有向无环图, 根据关系我们能得到一个线性序列,实现的方式是DFS,具体 ...

  4. 【ZOJ - 3780】Paint the Grid Again(拓扑排序,图论,证明性质)

    题干: Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black ...

  5. CF思维联系--CodeForces -214C (拓扑排序+思维+贪心)

    ACM思维题训练集合 Furik and Rubik love playing computer games. Furik has recently found a new game that gre ...

  6. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图

    https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...

  7. python 拓扑排序 dfs bfs_图遍历算法之DFS/BFS

    在计算机科学, 图遍历(Tree Traversal,也称图搜索)是一系列图搜索的算法, 是单次访问树结构类型数据(tree data structure)中每个节点以便检查或更新的一系列机制.图遍历 ...

  8. 猫猫向前冲【排名】【拓扑排序】【图】

    问题描述 众所周知, TT 是一位重度爱猫人士,他有一只神奇的魔法猫. 有一天,TT 在 B 站上观看猫猫的比赛.一共有 N 只猫猫,编号依次为1,2,3,-,N进行比赛.比赛结束后,Up 主会为所有 ...

  9. CodeForces - 1255B Fridge Lockers 思维+建图)

    题目链接:https://vjudge.net/contest/344327#problem/C 翻译: 输入两个数n和m.表示人的数量和铁链的数量. 接下来n个数,表示每一点的权值. 每个人有一个冰 ...

最新文章

  1. YOLOv3和YOLOv4长篇核心综述(下)
  2. mysql-cluster集群原理介绍和搭建步骤(四个data/sql节点) (转)
  3. android 课程——样式
  4. BYTE,WORD,DWORD的大小及一些特殊的高低位宏(取高位 取低位)
  5. Confluence 6 使用一个页面为站点的默认页面
  6. oracle 存储过程字符替换,Oracle存储过程常用字符串处理函数整理
  7. static in c language
  8. 前端学习(684):循环导读
  9. 原创|我以为我对Mysql索引很了解,直到我遇到了阿里的面试官
  10. PyFlink 在聚美优品的应用实践
  11. 游戏开发3D基础知识
  12. palapaweb的mysql无法运行_Mysql 服务无法启动 服务没有报告任何错误
  13. Matlab里面如何实现多行注释
  14. 基于深度学习的长江干线水位数据回归预测
  15. 计算机无法复制大文件格式,U盘复制文件电脑提示文件过大无法复制怎么解决?...
  16. android 3dtouch插件,标注点支持3DTouch效果
  17. 词嵌入来龙去脉 word embedding、word2vec
  18. java xml最火的的工具_几种高效的Java工具类推荐
  19. PS CC 2018 切片复制问题解决方法
  20. C# wpf 实现简单的颜色板

热门文章

  1. XSS跨站脚本(web应用)——XSS跨站脚本防御(三)
  2. python包怎么用_python的包怎么应用
  3. c语言必背数据结构_数据结构(C语言)考试重点必背
  4. matlab中nlfilter函数,matlab的一些关于块分类的函数~~~
  5. springboot扫描组件_springboot多模块包扫描问题的解决方法
  6. Spring_Bean的作用域---和使用外部属性文件
  7. 从一道面试题说起—js隐式转换踩坑合集
  8. 多线程之死锁就是这么简单
  9. Promise 基础用法
  10. 网站前端性能优化之javascript和css