zoukankan      html  css  js  c++  java
  • [BZOJ2132]圈地计划

    题面戳我

    Description

    最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地。据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域。GDOI要求将这些区域分为商业区和工业区来开发。根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值。更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益。另外不同的区域连在一起可以得到额外的收益,即如果区域(I,j)相邻(相邻是指两个格子有公共边)有K块(显然K不超过4)类型不同于(I,j)的区域,则这块区域能增加k×Cij收益。经过Tiger.S教授的勘察,收益矩阵A,B,C都已经知道了。你能帮GDOI求出一个收益最大的方案么?

    Input

    输入第一行为两个整数,分别为正整数N和M,分别表示区域的行数和列数;第2到N+1列,每行M个整数,表示商业区收益矩阵A;第N+2到2N+1列,每行M个整数,表示工业区收益矩阵B;第2N+2到3N+1行,每行M个整数,表示相邻额外收益矩阵C。第一行,两个整数,分别是n和m(1≤n,m≤100);
    任何数字不超过1000”的限制

    Output

    输出只有一行,包含一个整数,为最大收益值。

    Sample Input

    3 3
    1 2 3
    4 5 6
    7 8 9
    9 8 7
    6 5 4
    3 2 1
    1 1 1
    1 3 1
    1 1 1
    

    Sample Output

    81
    

    【数据规模】

    对于100%的数据有N,M≤100

    sol

    最小割模型都看得出来吧。把所有收益先加上(注意(C)的收益要加上若干次)
    对于(A)(B)的连边应该都很好解决,但(C)怎么办?
    最小割在同一边的时候产生代价,在两侧时不产生代价?
    这可做?
    那么我们就要适当转化模型,把在同一边产生代价的条件转化为在两侧产生代价
    那么我们就要认为相邻两个点同类型时是在不同侧的,不同类型时反倒是在同一侧。
    这是啥?
    注意这是个矩形哟,是个啥。。。二分图?
    我们就对二分图两侧的点(下文称为黑白两个点,注意这是自然形成的而非答案计算得到的)分别定义在最小割的左右两边的含义。比如说:
    我们定义最小割中在(S)这一边的是黑点中选商业的点和白点中选工业的点;
    同理,与(T)在同一边的是黑点中选工业的点和白点中选商业的点。
    这样一来,最小割就成立了。
    要注意意义不同以后,每个点直接与(S)(T)连的那条边的容量就取决于它是黑点还是白点。黑点与(S)(A)(商业),与(T)(B)(工业),白点恰好反之。

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int inf = 1e9;
    const int N = 110;
    struct edge{int to,next,w;}a[N*N<<5];
    int n,m,P[N][N],tot,A[N][N],B[N][N],C[N][N],sum,S,T,head[N*N],cnt=1,dep[N*N],cur[N*N];
    queue<int>Q;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    void link(int u,int v,int w,bool b)
    {
    	a[++cnt]=(edge){v,head[u],w};
    	head[u]=cnt;
    	a[++cnt]=(edge){u,head[v],b?w:0};
    	head[v]=cnt;
    }
    bool bfs()
    {
    	memset(dep,0,sizeof(dep));
    	dep[S]=1;Q.push(S);
    	while (!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for (int e=head[u];e;e=a[e].next)
    			if (a[e].w&&!dep[a[e].to])
    				dep[a[e].to]=dep[u]+1,Q.push(a[e].to);
    	}
    	return dep[T];
    }
    int dfs(int u,int flow)
    {
    	if (u==T)
    		return flow;
    	for (int &e=cur[u];e;e=a[e].next)
    		if (a[e].w&&dep[a[e].to]==dep[u]+1)
    		{
    			int temp=dfs(a[e].to,min(flow,a[e].w));
    			if (temp) {a[e].w-=temp;a[e^1].w+=temp;return temp;}
    		}
    	return 0;
    }
    int Dinic()
    {
    	int res=0;
    	while (bfs())
    	{
    		for (int i=T;i;i--) cur[i]=head[i];
    		while (int temp=dfs(S,inf)) res+=temp;
    	}
    	return res;
    }
    int main()
    {
    	n=gi();m=gi();S=n*m+1;T=n*m+2;
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			P[i][j]=++tot,A[i][j]=gi(),sum+=A[i][j];
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			B[i][j]=gi(),sum+=B[i][j];
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    		{
    			C[i][j]=gi();
    			if (i>1) sum+=C[i][j];
    			if (j>1) sum+=C[i][j];
    			if (i<n) sum+=C[i][j];
    			if (j<m) sum+=C[i][j];
    		}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if ((i+j)&1)
    			{
    				link(S,P[i][j],A[i][j],0);
    				link(P[i][j],T,B[i][j],0);
    				if (i>1) link(P[i][j],P[i-1][j],C[i][j]+C[i-1][j],1);
    				if (j>1) link(P[i][j],P[i][j-1],C[i][j]+C[i][j-1],1);
    				if (i<n) link(P[i][j],P[i+1][j],C[i][j]+C[i+1][j],1);
    				if (j<m) link(P[i][j],P[i][j+1],C[i][j]+C[i][j+1],1);
    			}
    			else
    			{
    				link(S,P[i][j],B[i][j],0);
    				link(P[i][j],T,A[i][j],0);
    			}
    	printf("%d
    ",sum-Dinic());
    	return 0;
    }
    
  • 相关阅读:
    bzoj2733 永无乡 平衡树按秩合并
    bzoj2752 高速公路 线段树
    bzoj1052 覆盖问题 二分答案 dfs
    bzoj1584 打扫卫生 dp
    bzoj1854 游戏 二分图
    bzoj3316 JC loves Mkk 二分答案 单调队列
    bzoj3643 Phi的反函数 数学 搜索
    有一种恐怖,叫大爆搜
    BZOJ3566 概率充电器 概率dp
    一些奇奇怪怪的过题思路
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8213616.html
Copyright © 2011-2022 走看看