AtCoder Regular Contest 074 F Lotus Leaves

来源:互联网 发布:蚌埠市农村金融数据 编辑:程序博客网 时间:2024/06/03 14:03

F - Lotus Leaves


Time limit : 2sec /Memory limit : 256MB

Score : 800 points

Problem Statement

There is a pond with a rectangular shape. The pond is divided into a grid withH rows andW columns of squares. We will denote the square at thei-th row from the top andj-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 leafT. 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 leafT. Determine whether this objective is achievable. If it is achievable, find the minimum necessary number of leaves to remove.

Constraints

  • 2H,W100
  • 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 Wa11  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

Copy
3 3S.o.o.o.T

Sample Output 1

Copy
2

Remove the upper-right and lower-left leaves.


Sample Input 2

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

Sample Output 2

Copy
0

Sample Input 3

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

Sample Output 3

Copy
-1

Sample Input 4

Copy
10 10.o...o..o.....o.........oo.oo...oooo..o.....oo......o..o....o..o....Soo....T........o.............oo

Sample Output 4

Copy
5

题解:

考虑最小割模型。把每行、每列建成点,加上源点和汇点,一共H+W+2个点。源点向字符S所在的行和列连流量为无穷大的边,T所在的行和列向汇点连流量为无穷大的边,字符o所在的行列之间连流量为1的双向边,割掉其中的一条边表示去掉这个o。最后如果流量为无穷大则输出-1。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int inf=30000;int edge[30000],nxt[30000],flow[30000],first[300];int g[300],h[300];char c[300][300];int i,j,m,n,s,head,tail,sum_edge;inline void addedge(int x,int y,int f){sum_edge++,edge[sum_edge]=y,flow[sum_edge]=f,nxt[sum_edge]=first[x],first[x]=sum_edge;return;}inline int oppedge(int x){return ((x-1)^1)+1;}inline void buildgraph(){scanf("%d%d",&n,&m);for (i=1;i<=n;i++)scanf("%s",c[i]+1);for (i=1;i<=n;i++)for (j=1;j<=m;j++)switch (c[i][j]){case 'S':addedge(0,i,inf),addedge(i,0,0);addedge(0,n+j,inf),addedge(n+j,0,0);break;case 'T':addedge(i,n+m+1,inf),addedge(n+m+1,i,0);addedge(n+j,n+m+1,inf),addedge(n+m+1,n+j,0);break;case 'o':addedge(i,n+j,1),addedge(n+j,i,1);break;}return;}inline int dinic_bfs(){memset(h,0,sizeof(h));tail=1,g[tail]=0,h[g[tail]]=1;for (head=1;head<=tail;head++)for (i=first[g[head]];i!=0;i=nxt[i])if ((flow[i]) && (! h[edge[i]]))tail++,g[tail]=edge[i],h[g[tail]]=h[g[head]]+1;return h[n+m+1];}inline int dinic_dfs(int now,int cap){if (now==n+m+1)return cap;int s=0,t=0;for (int i=first[now];i!=0;i=nxt[i])if ((flow[i]) && (h[edge[i]]==h[now]+1)){t=dinic_dfs(edge[i],min(cap,flow[i]));s=s+t,cap=cap-t;flow[i]=flow[i]-t,flow[oppedge(i)]=flow[oppedge(i)]+t;if (! cap)break;}if (cap)h[now]=0;return s;}inline void maxflow(){while (dinic_bfs())s=s+dinic_dfs(0,inf);if (s>n*m)printf("-1");elseprintf("%d",s);return;}int main(){buildgraph();maxflow();return 0;}