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:

  1. H W
  2. a11 a1W
  3. :
  4. aH1 aHW

Output

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

Sample Input 1

  1. 3 3
  2. S.o
  3. .o.
  4. o.T

Sample Output 1

  1. 2

Remove the upper-right and lower-left leaves.

Sample Input 2

  1. 3 4
  2. S...
  3. .oo.
  4. ...T

Sample Output 2

  1. 0

Sample Input 3

  1. 4 3
  2. .S.
  3. .o.
  4. .o.
  5. .T.

Sample Output 3

  1. -1

Sample Input 4

  1. 10 10
  2. .o...o..o.
  3. ....o.....
  4. ....oo.oo.
  5. ..oooo..o.
  6. ....oo....
  7. ..o..o....
  8. o..o....So
  9. o....T....
  10. ....o.....
  11. ........oo

Sample Output 4

  1. 5

  2. 有意思的网络流题目;
    刚开始我想的很直接:按题目建边,但是你会发现这样建边之后复杂度会很高,而且也不现实;
    我们考虑将行和列分开;
    对于源点,我们将其和该行建边,与该列建边;
    同理对于汇点;
    对于O这种情况,我们将行和列建边,容量为1
    由于我们要使得ST分开,所以要求的是最小割,那么就是dinic求一下最大流即可;
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<string>
  7. #include<cmath>
  8. #include<map>
  9. #include<set>
  10. #include<vector>
  11. #include<queue>
  12. #include<bitset>
  13. #include<ctime>
  14. #include<deque>
  15. #include<stack>
  16. #include<functional>
  17. #include<sstream>
  18. //#include<cctype>
  19. //#pragma GCC optimize(2)
  20. using namespace std;
  21. #define maxn 2000005
  22. #define inf 0x7fffffff
  23. //#define INF 1e18
  24. #define rdint(x) scanf("%d",&x)
  25. #define rdllt(x) scanf("%lld",&x)
  26. #define rdult(x) scanf("%lu",&x)
  27. #define rdlf(x) scanf("%lf",&x)
  28. #define rdstr(x) scanf("%s",x)
  29. typedef long long ll;
  30. typedef unsigned long long ull;
  31. typedef unsigned int U;
  32. #define ms(x) memset((x),0,sizeof(x))
  33. const long long int mod = 1e9 + 7;
  34. #define Mod 1000000000
  35. #define sq(x) (x)*(x)
  36. #define eps 1e-4
  37. typedef pair<int, int> pii;
  38. #define pi acos(-1.0)
  39. //const int N = 1005;
  40. #define REP(i,n) for(int i=0;i<(n);i++)
  41. typedef pair<int, int> pii;
  42. inline ll rd() {
  43. ll x = 0;
  44. char c = getchar();
  45. bool f = false;
  46. while (!isdigit(c)) {
  47. if (c == '-') f = true;
  48. c = getchar();
  49. }
  50. while (isdigit(c)) {
  51. x = (x << 1) + (x << 3) + (c ^ 48);
  52. c = getchar();
  53. }
  54. return f ? -x : x;
  55. }
  56.  
  57. ll gcd(ll a, ll b) {
  58. return b == 0 ? a : gcd(b, a%b);
  59. }
  60. int sqr(int x) { return x * x; }
  61.  
  62. /*ll ans;
  63. ll exgcd(ll a, ll b, ll &x, ll &y) {
  64. if (!b) {
  65. x = 1; y = 0; return a;
  66. }
  67. ans = exgcd(b, a%b, x, y);
  68. ll t = x; x = y; y = t - a / b * y;
  69. return ans;
  70. }
  71. */
  72.  
  73. int n, m;
  74. int st, ed;
  75. struct node {
  76. int u, v, nxt, w;
  77. }edge[maxn << 1];
  78.  
  79. int head[maxn], cnt;
  80.  
  81. void addedge(int u, int v, int w) {
  82. edge[cnt].u = u; edge[cnt].v = v; edge[cnt].nxt = head[u];
  83. edge[cnt].w = w; head[u] = cnt++;
  84. }
  85.  
  86. int rk[maxn];
  87.  
  88. int bfs() {
  89. queue<int>q;
  90. ms(rk);
  91. rk[st] = 1;
  92. q.push(st);
  93. while (!q.empty()) {
  94. int tmp = q.front(); q.pop();
  95. for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
  96. int to = edge[i].v;
  97. if (rk[to] || edge[i].w <= 0)continue;
  98. rk[to] = rk[tmp] + 1; q.push(to);
  99. }
  100. }
  101. return rk[ed];
  102. }
  103.  
  104. int dfs(int u, int flow) {
  105. if (u == ed)return flow;
  106. int add = 0;
  107. for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
  108. int v = edge[i].v;
  109. if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
  110. int tmpadd = dfs(v, min(edge[i].w, flow - add));
  111. if (!tmpadd) { rk[v] = -1; continue; }
  112. edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd;
  113. add += tmpadd;
  114. }
  115. return add;
  116. }
  117.  
  118. int ans;
  119. void dinic() {
  120. while (bfs())ans += dfs(st, inf);
  121. }
  122. int H, W;
  123. char ch[103][103];
  124.  
  125. int getpos(int x, int y) {
  126. return (x - 1)*W + y;
  127. }
  128. int main() {
  129. // ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  130. cin >> H >> W; memset(head, -1, sizeof(head));
  131. for (int i = 1; i <= H; i++)scanf("%s", ch[i] + 1);
  132. int hx = 0, hy = 0, wx = 0, wy = 0;
  133. for (int i = 1; i <= H; i++) {
  134. for (int j = 1; j <= W; j++) {
  135. if (ch[i][j] == 'S') {
  136. hx = i; hy = j;
  137. }
  138. else if (ch[i][j] == 'T') {
  139. wx = i; wy = j;
  140. }
  141. }
  142. }
  143. if (wx == hx || wy == hy) {
  144. cout << -1 << endl; return 0;
  145. }
  146. st = 0; ed = H * W + 1;
  147. for (int i = 1; i <= H; i++) {
  148. for (int j = 1; j <= W; j++) {
  149. if (ch[i][j] == 'S')addedge(st, i, inf), addedge(i, st, 0), addedge(st, j + H, inf), addedge(j + H, st, 0);
  150. if (ch[i][j] == 'T')addedge(i, ed, inf), addedge(ed, i, 0), addedge(j + H, ed, inf), addedge(ed, j + H, 0);
  151. if (ch[i][j] != '.')addedge(i, j + H, 1), addedge(j + H, i, 0), addedge(j + H, i, 1), addedge(i, j + H, 0);
  152.  
  153. }
  154. }
  155. dinic();
  156. if (ans != inf) {
  157. cout << ans << endl; return 0;
  158. }
  159. else cout << -1 << endl;
  160. return 0;
  161. }
  1.  

AtCoder - 2568 最小割的更多相关文章

  1. Atcoder Grand Contest 038 F - Two Permutations(集合划分模型+最小割)

    洛谷题面传送门 & Atcoder 题面传送门 好久前做的题了--今天偶然想起来要补个题解 首先考虑排列 \(A_i\) 要么等于 \(i\),要么等于 \(P_i\) 这个条件有什么用.我们 ...

  2. Atcoder Regular Contest 125 E - Snack(最小割转化+贪心)

    Preface: 这是生平第一道现场 AC 的 arc E,也生平第一次经历了 performance \(\ge 2800\)​,甚至还生平第一次被 hb 拉到会议里讲题,讲的就是这个题,然鹅比较尬 ...

  3. [题解] Atcoder ARC 142 E Pairing Wizards 最小割

    题目 建图很妙,不会. 考虑每一对要求合法的巫师(x,y),他们两个的\(a\)必须都大于\(min(b_x,b_y)\).所以在输入的时候,如果\(a_x\)或者\(a_y\)小于\(min(b_x ...

  4. BZOJ 1391: [Ceoi2008]order [最小割]

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Statu ...

  5. BZOJ-2127-happiness(最小割)

    2127: happiness(题解) Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1806  Solved: 875 Description 高一 ...

  6. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  7. BZOJ3438 小M的作物(最小割)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=3438 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为 ...

  8. 最大流-最小割 MAXFLOW-MINCUT ISAP

    简单的叙述就不必了. 对于一个图,我们要找最大流,对于基于增广路径的算法,首先必须要建立反向边. 反向边的正确性: 我努力查找了许多资料,都没有找到理论上关于反向边正确性的证明. 但事实上,我们不难理 ...

  9. bzoj1412最小割

    太羞耻了,m n写反了(主要是样例n m相等) 建图方法比较高(ji)端(chu),对于可以加栅栏的地方连上1的边,然后求最小割即可 为了让代码优(suo)美(duan),我写了一个check,避免多 ...

随机推荐

  1. 【284】◀▶ arcpy.da & arcpy 数据访问模块

    使用游标访问数据 数据访问模块 (arcpy.da) 参考: ArcGIS Python编程案例(9)-ArcPy数据访问模块 读取几何 写入几何 使用 Python 指定查询 01   da.Sea ...

  2. 让IE10等支持classList2.0

    chrome24+, firesfox26+起支持classList2.0,即让它同时添加或删除多个类名, toggle方法支持第2个参数,用于强制添加或删除 var div = document.c ...

  3. Windows下查询指定端口进程,并杀死

    1. 找到指定端口的进程号 c:\devworks\lib\httpd-2.4.10-win32-VC9\Apache24\bin>netstat -ano|findstr "9000 ...

  4. 设置VMware Player中的虚拟机和宿主机共享文件

    设置VMware Player中的虚拟机和宿主机共享文件 试验环境: 虚拟机软件:VMware Player 6.0.3 宿主机os:windows7 虚拟机os:centos6.6(32位)   完 ...

  5. Android剖析和运行机制

    Android剖析和运行机制 大纲: 1. Android剖析 Linux内核本地库(Native Libraries)Android运行时(Android Runtime)应用框架 2. Andro ...

  6. window - BOM对象

    Window 对象 Window 对象表示浏览器中打开的窗口. 如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 window 对象,并为每个框架创建一个额外 ...

  7. java基础之匿名内部类

    内部类: 概述: 类里边还有一个类, 里边那个类叫内部类, 外边那个类叫外部类. 分类: 成员内部类: 定义在成员位置的内部类. 局部内部类: 定义在局部位置的内部类. 格式: new 类名或者接口名 ...

  8. day63-webservice 02.cxf环境搭建

    指定bin目录的目的是在docs窗口可以直接来执行这里面的命令. ANT这里面

  9. 带你剖析WebGis的世界奥秘----点和线的世界(转)

    带你剖析WebGis的世界奥秘----点和线的世界 转:https://zxhtom.oschina.io/zxh/20160813.html  编程  java  2016/08/13 0留言, 0 ...

  10. Marr的视觉计算理论

            Marr的视觉计算理论立足于计算机科学,系统地概括了心理物理学.神经生理学.临床神经病理学等方面已取得的所有重要成果,是迄今为止最为系统的视觉理论.Marr 的视觉计算理论虽然在细节甚 ...