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;
    }
    
     
  • 相关阅读:
    Html页面渲染
    神思SS628(100)型第二代身份证验证阅读机B/S二次开发
    ASP.NET面试问题一天5问(四)
    ASP.NET面试问题一天5问(三)
    asp.net 面试问题一天5问(二)
    ASP.NET面试问题一天5问(一)
    ASP.NET MVC 3 第一天笔记
    2019 END → 2020 BEGIN
    vs中自己常用的快捷方式
    Dapper使用入门Demo
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9101178.html
Copyright © 2011-2022 走看看