AtCoder Regular Contest 074 F Lotus Leaves

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 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

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

Sample Output 1

Copy
2

Remove the upper-right and lower-left leaves.


Sample Input 2

Copy
3 4
S...
.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....So
o....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");
	else
		printf("%d",s);
	return;
}

int main()
{
	buildgraph();
	maxflow();
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值