zoukankan      html  css  js  c++  java
  • AtCoder

    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
    • 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
    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
    ",ans);
    	
    	return 0;
    }
    
     
  • 相关阅读:
    jQuery .css("width")和.width()的区别
    用jquery写一个滑动TAB 例子
    D
    4 Values whose Sum is 0
    Hibernate学习之hql 与sql
    BigDecimal进行精确运算
    Date类与SimpleDateFormat类中parse()方法和format()方法
    单例模式下的懒汉和饿汉模式
    Java中Date类型详解
    Spring @Column的注解详解
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9101178.html
Copyright © 2011-2022 走看看