Problem Statement

There is a pond with a rectangular shape. The pond is divided into a grid with H rows and W columns of squares. We will denote the square at the i-th row from the top and j-th column from the left by (ij).

Some of the squares in the pond contains a lotus leaf floating on the water. On one of those leaves, S, there is a frog trying to get to another leaf T. The state of square (ij) is given to you by a character aij, as follows:

  • . : A square without a leaf.
  • o : A square with a leaf floating on the water.
  • S : A square with the leaf S.
  • T : A square with the leaf T.

The frog will repeatedly perform the following action to get to the leaf T: "jump to a leaf that is in the same row or the same column as the leaf where the frog is currently located."

Snuke is trying to remove some of the leaves, other than S and T, so that the frog cannot get to the leaf T. Determine whether this objective is achievable. If it is achievable, find the minimum necessary number of leaves to remove.

Constraints

  • 2≤H,W≤100
  • aij is ., o, S or T.
  • There is exactly one S among aij.
  • There is exactly one T among aij.

Input

Input is given from Standard Input in the following format:

H W
a11 a1W
:
aH1 aHW

Output

If the objective is achievable, print the minimum necessary number of leaves to remove. Otherwise, print -1 instead.

Sample Input 1

3 3
S.o
.o.
o.T

Sample Output 1

2

Remove the upper-right and lower-left leaves.

Sample Input 2

3 4
S...
.oo.
...T

Sample Output 2

0

Sample Input 3

4 3
.S.
.o.
.o.
.T.

Sample Output 3

-1

Sample Input 4

10 10
.o...o..o.
....o.....
....oo.oo.
..oooo..o.
....oo....
..o..o....
o..o....So
o....T....
....o.....
........oo

Sample Output 4

5


    非常神奇的二分图建模!
我们把行和列分别看成二分图两边的一排节点,那么我们的任务其实就是找到一个最小割,使得从S 的行或列 走不到 T的行或列。
所以对于原图中的一片荷叶(i,j) ,我们就在二分图中添加 无向边 行i to 列j,再连 S 到 S行,S列 ; T行,T列到T。容量都是inf。 这样原图中的最小割就是答案了,如果答案>=inf那么无解,说明S,T在同一行或者同一列。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=305,inf=1e8;
#define pb push_back
struct lines{
int to,flow,cap;
}l[maxn*maxn*5];
vector<int> g[maxn];
int cur[maxn],d[maxn],t=-1,S,T;
bool v[maxn]; inline void add(int from,int to,int cap){
l[++t]=(lines){to,0,cap},g[from].pb(t);
l[++t]=(lines){from,0,0},g[to].pb(t);
} inline bool BFS(){
memset(v,0,sizeof(v)),v[S]=1,d[S]=0;
queue<int> q; q.push(S);
int x; lines e; while(!q.empty()){
x=q.front(),q.pop();
for(int i=g[x].size()-1;i>=0;i--){
e=l[g[x][i]];
if(e.flow<e.cap&&!v[e.to]) v[e.to]=1,d[e.to]=d[x]+1,q.push(e.to);
}
} return v[T];
} int dfs(int x,int A){
if(x==T||!A) return A;
int flow=0,f,sz=g[x].size();
for(int &i=cur[x];i<sz;i++){
lines &e=l[g[x][i]];
if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(e.cap-e.flow,A)))){
A-=f,flow+=f;
e.flow+=f,l[g[x][i]^1].flow-=f;
if(!A) break;
}
} return flow;
} inline int max_flow(){
int an=0;
while(BFS()){
memset(cur,0,sizeof(cur));
an+=dfs(S,inf);
}
return an;
} int n,m;
char ch; int main(){
scanf("%d%d",&n,&m),S=0,T=n+m+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
ch=getchar();
while(ch!='.'&&ch!='o'&&ch!='S'&&ch!='T') ch=getchar();
if(ch!='.') add(i,j+n,1),add(j+n,i,1);
if(ch=='S') add(S,i,inf),add(S,j+n,inf);
else if(ch=='T') add(i,T,inf),add(j+n,T,inf);
} int ans=max_flow();
if(ans>=inf) puts("-1");
else printf("%d\n",ans); return 0;
}
 

AtCoder - 2568 Lotus Leaves的更多相关文章

  1. AtCoder Regular Contest 074 F - Lotus Leaves

    题目传送门:https://arc074.contest.atcoder.jp/tasks/arc074_d 题目大意: 给定一个\(H×W\)的网格图,o是可以踩踏的点,.是不可踩踏的点. 现有一人 ...

  2. AtCoder Regular Contest 074F - Lotus Leaves

    $n \leq 300,m \leq 300$,$n*m$的格子里有起点有终点有空地有障碍,人会从起点选一个同行或同列空地跳过去,然后一直这样跳到终点.求至少删掉多少格子使得人跳不到终点. 首先S和T ...

  3. 【arc077f】AtCoder Regular Contest 074 F - Lotus Leaves

    题意 给定一个n*m的池塘,每个格子上可能有叶子. 从一个叶子出发,可以跳到相同行或相同列的叶子. 问至少去掉多少叶子,使得起点不能到达终点. \(n,m<=100\) 解法 很显然的最小割模型 ...

  4. AtCoder - 2568 最小割

    There is a pond with a rectangular shape. The pond is divided into a grid with H rows and W columns ...

  5. 【ARC074F】Lotus Leaves 最小割

    Description 给你一个n*m网格图,有起点荷叶和终点荷叶,有中转荷叶,其他的格子没东西,一个荷叶可以跳到同一行或者列的另一个荷叶.问最多删掉几个中转荷叶能让起点终点不连通.如果不行输出-1. ...

  6. agc026F Lotus Leaves

    题目链接 题目大意 一个n*m的网格上有一些点,一个点可以跳到与其同一行或同一列的点上.给定起点和终点. 求要使起点不能跳到终点,最少撤走几个点. \(n,m\leq 100\) 解题思路 考虑将能够 ...

  7. Atcoder Regular-074 Writeup

    C - Chocolate Bar 题面 There is a bar of chocolate with a height of H blocks and a width of W blocks. ...

  8. AtCoder刷题记录

    构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...

  9. 【AtCoder】ARC074

    ARC 074 C - Chocolate Bar 直接枚举第一刀横切竖切,然后另一块要求如果横切分成\(H / 2\)竖切分成\(W/2\)即可 #include <bits/stdc++.h ...

随机推荐

  1. [NOI2002] 银河英雄传说 (带权并查集)

    题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...

  2. 解决mysql的日志文件过大的问题

    https://www.2cto.com/database/201203/122984.html

  3. Install the Active Directory Administration Tools on Windows Server

    安装 Active Directory 管理工具 To manage your directory from an EC2 Windows instance, you need to install ...

  4. Sed basic and practice

    定义:Sed 是针对数据流的非交谈式编辑器,它在命令行下输入编辑命令并指定文件,然后可以在屏幕上看到编辑命令的输出结果. 好处:Sed 在缓冲区内默认逐行处理数据,所以源文件不会被更改和破坏. 格式: ...

  5. cglib

    参考:http://blog.csdn.net/zhoudaxia/article/details/30591941 <!-- https://mvnrepository.com/artifac ...

  6. Java并发(11)- 有关线程池的10个问题

    引言 在日常开发中,线程池是使用非常频繁的一种技术,无论是服务端多线程接收用户请求,还是客户端多线程处理数据,都会用到线程池技术,那么全面的了解线程池的使用.背后的实现原理以及合理的优化线程池的大小等 ...

  7. Bzoj1313 [HAOI2008]下落的圆盘

    有 n 个圆盘从天而降,后面落下的可以盖住前面的.最后按掉下的顺序,在平面上依次测得每个圆盘的圆心和半径,问下落完成后从上往下看,整个图形的周长是多少,即你可以看到的圆盘的轮廓的圆盘的轮廓总长.例如下 ...

  8. C# 文件类的操作---获取

    如何获取指定目录包含的文件和子目录 . DirectoryInfo.GetFiles():获取目录中(不包含子目录)的文件,返回类型为FileInfo[],支持通配符查找: . DirectoryIn ...

  9. 算法题之Leetcode分糖果

    题目: There are N children standing in a line. Each child is assigned a rating value. You are giving c ...

  10. 【反演复习计划】【bzoj2818】gcd

    就是之前的2820的升级版. 把暴力枚举素数改成预处理就随便A了. #include<bits/stdc++.h> #define N 10000005 #define ll long l ...