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;
    }
    
     
  • 相关阅读:
    ODBC SQLSetConnectAttr
    Red Hat Enterprise Linux 8配置YUM源的两种方式
    red hat register
    下载和安装Red Hat Enterprise Linux 8.1(RHEL 8.1)
    SQL Server doc infomation
    SQL Server ODBC Download
    Linux install ODBC
    ODBC [Microsoft][ODBC Sql Server Driver][TCP/IP Sockets]SQL Server 不存在或访问被拒绝。
    想看的小说
    (转载) Navicat for MySQL 15注册与激活
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9101178.html
Copyright © 2011-2022 走看看