zoukankan      html  css  js  c++  java
  • 【BZOJ4439】[Swerc2015]Landscaping 最小割

    【BZOJ4439】[Swerc2015]Landscaping

    Description

    FJ有一块N*M的矩形田地,有两种地形高地(用‘#’表示)和低地(用‘.’表示)
    FJ需要对每一行田地从左到右完整开收割机走到头,再对每一列从上到下完整走到头,如下图所示
    对于一个4*4的田地,FJ需要走8次。
    收割机是要油的,每次从高地到低地或从低地到高地需要支付A的费用。
    但是FJ有黑科技,可以高地与低地的互变,都只需要一个支付B的费用。
    询问FJ需要支付最小费用。

    Input

    第一行包含四个整数N,M,A,B,意义如上文所述。
    接下来是一个N*M的字符串矩阵,表示农田的地形,’#’表示高地,’.’表示低地。

    Output

    只包含一个正整数,表示最小费用。
    1<=N,M<=50
    1<=A,B<=100000

    Sample Input

    5 4 1000 2000
    ...#
    #..#
    ...#
    ##..
    ###.

    Sample Output

    11000
    样例解释:
    把(2,1)的高地变成低地花费2000,燃料花费9000

    题解:同【BZOJ2768】[JLOI2010]冠军调查,三倍经验~

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #define P(X,Y) ((X-1)*m+Y)
    using namespace std;
    int n,m,cnt,ans,S,T,A,B;
    int to[300000],next[300000],val[300000],head[3000],d[3000];
    int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
    char str[60];
    queue<int> q;
    int dfs(int x,int mf)
    {
    	if(x==T)	return mf;
    	int i,k,temp=mf;
    	for(i=head[x];i!=-1;i=next[i])
    	{
    		if(d[to[i]]==d[x]+1&&val[i])
    		{
    			k=dfs(to[i],min(temp,val[i]));
    			if(!k)	d[to[i]]=0;
    			val[i]-=k,val[i^1]+=k,temp-=k;
    			if(!temp)	break;
    		}
    	}
    	return mf-temp;
    }
    int bfs()
    {
    	memset(d,0,sizeof(d));
    	while(!q.empty())	q.pop();
    	d[S]=1,q.push(S);
    	int i,u;
    	while(!q.empty())
    	{
    		u=q.front(),q.pop();
    		for(i=head[u];i!=-1;i=next[i])
    		{
    			if(!d[to[i]]&&val[i])
    			{
    				d[to[i]]=d[u]+1;
    				if(to[i]==T)	return 1;
    				q.push(to[i]);
    			}
    		}
    	}
    	return 0;
    }
    void add(int a,int b,int c)
    {
    	to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
    	to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
    }
    int main()
    {
    	scanf("%d%d%d%d",&n,&m,&A,&B);
    	int i,j,k;
    	S=0,T=n*m+1;
    	memset(head,-1,sizeof(head));
    	for(i=1;i<=n;i++)
    	{
    		scanf("%s",str);
    		for(j=1;j<=m;j++)
    		{
    			if(str[j-1]=='#')	add(S,P(i,j),B);
    			else	add(P(i,j),T,B);
    			for(k=0;k<4;k++)
    				if(i+dx[k]&&i+dx[k]<=n&&j+dy[k]&&j+dy[k]<=m)
    					add(P(i,j),P(i+dx[k],j+dy[k]),A);
    		}
    	}
    	while(bfs())	ans+=dfs(S,1<<30);
    	printf("%d",ans);
    	return 0;
    }
  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6862475.html
Copyright © 2011-2022 走看看