题目链接:https://codeforces.com/contest/1335/problem/F
题目大意:
机器人按轨道运行,在运行中机器人间不能发生冲撞。
问最多能摆放多少机器人,和在最大摆放的前提下能占据多少黑块。
个人思路:
找到每个连通块,在每个回路(根据题意所有回路一定是简单回路)上选一个点逆向进行BFS搜索,在同一层上被搜到的点中只要有一个黑块就说明机器人可以通过这个黑块无拥挤的进入回路,占据黑块的总量加一。
#include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
#define pr pair<int,int>
using namespace std;
typedef long long ll;
const int N=2e6+5;
char ch;
int ans_a,ans_b,idx,n,m;
int vis[N],b[N],a[N],dfn[N],inque[N];
vector<int> c[N];
//b数组表示连出,c表示连入
void fill_(int p) {
if(vis[p]) return ;
vis[p]=1;
fill_(b[p]);
for(int v:c[p]) fill_(v);
}
//每次访问过一个连通块后标记
void bfs(int p,int mx) {
queue<pr> que;
que.push(pr(0,p));
inque[p]=1;
vector<int> ans(mx);
while(!que.empty()) {
pr t=que.front();que.pop();
int u=t.second,cnt=t.first;
if(!a[u]) ans[cnt%mx]=1;
for(int v:c[u]) {
if(!inque[v]) que.push(pr(cnt+1,v));
inque[v]=1;
}
}
ans_a+=mx;
rep(i,mx) if(ans[i]) ans_b++;
}
void dfs(int p) {
if(dfn[p]) {
bfs(p,idx+1-dfn[p]);
return ;
}
dfn[p]=++idx,dfs(b[p]);
}
//建立dfn序,idx+1-dfn即为环的大小
void solve() {
cin>>n>>m;
idx=ans_a=ans_b=0;
rep(i,n*m) vis[i]=dfn[i]=inque[i]=0,c[i].clear();
rep(i,n) rep(j,m) {
int p=i*m+j;
cin>>ch;
a[p]=ch-'0';
}
rep(i,n) rep(j,m) {
int p=i*m+j;
cin>>ch;
switch(ch) {
case 'L':b[p]=p-1;c[p-1].push_back(p);break;
case 'R':b[p]=p+1;c[p+1].push_back(p);break;
case 'U':b[p]=p-m;c[p-m].push_back(p);break;
case 'D':b[p]=p+m;c[p+m].push_back(p);
}
}
rep(i,n) rep(j,m) {
int p=i*m+j;
if(!vis[p]) dfs(p);
fill_(p);
}
cout<<ans_a<<' '<<ans_b<<'\n';
}
int main() {
ios::sync_with_stdio(false);
int T;cin>>T;
while(T--) solve();
}