【BZOJ2132】 圈地计划 最小割

#include <stdio.h>
int main()
{
	puts("转载请注明出处谢谢");
	puts("http://blog.csdn.net/vmurder/article/details/43201521");
}

题解:

水题,经典模型是两个在一块会损失,显然很好做。

这个同样很好做,就是黑白染色,然后某种颜色该连S集的连T,该连T的连S。

代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 10100
#define M 200000
#define P 105
#define inf 0x3f3f3f3f
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
struct KSD
{
	int v,len,next;
}e[M];
int head[N],cnt;
inline void add(int u,int v,int len)
{
	e[++cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int s,t,d[N];
queue<int>q;
bool bfs()
{
	while(!q.empty())q.pop();
	memset(d,0,sizeof d);

	q.push(s),d[s]=1;
	int i,u,v;
	while(!q.empty())
	{
		u=q.front(),q.pop();
		for(i=head[u];i;i=e[i].next)
		{
			v=e[i].v;
			if(!d[v=e[i].v]&&e[i].len)
			{
				d[v]=d[u]+1;
				if(v==t)return true;
				q.push(v);
			}
		}
	}
	return false;
}
int dinic(int x,int flow)
{
	if(x==t)return flow;
	int remain=flow,i,v,k;
	for(i=head[x];i&&remain;i=e[i].next)
	{
		if(d[v=e[i].v]==d[x]+1&&e[i].len)
		{
			k=dinic(v,min(remain,e[i].len));
			if(!k)d[v]=0;
			e[i].len-=k,e[i^1].len+=k;
			remain-=k;
		}
	}
	return flow-remain;
}
int n,m,maxflow;
int map1[P][P],map2[P][P],map3[P][P];
int id[P][P];
void build()
{
	int i,j,k;
	int x,y;

	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&map1[i][j]);
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&map2[i][j]);
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&map3[i][j]);
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)id[i][j]=++cnt;

	s=cnt+1,t=cnt+2,cnt=1;
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)
	{
		if(i+j&1)
		{
			add(s,id[i][j],map1[i][j]);
			add(id[i][j],s,map1[i][j]);
			add(id[i][j],t,map2[i][j]);
			add(t,id[i][j],map2[i][j]);
		}
		else {
			add(s,id[i][j],map2[i][j]);
			add(id[i][j],s,map2[i][j]);
			add(id[i][j],t,map1[i][j]);
			add(t,id[i][j],map1[i][j]);
		}
		maxflow+=map1[i][j]+map2[i][j];
		for(k=0;k<4;k++)
		{
			x=i+dx[k];
			y=j+dy[k];
			if(id[x][y])
			{
				add(id[i][j],id[x][y],map3[i][j]);
				add(id[x][y],id[i][j],map3[i][j]);
				maxflow+=map3[i][j];
			}
		}
	}
}
int main()
{
//	freopen("test.in","r",stdin);
	build();
	while(bfs())maxflow-=dinic(s,inf);
	printf("%d\n",maxflow);
	return 0;
}
时间: 2024-10-18 06:22:56

【BZOJ2132】 圈地计划 最小割的相关文章

【BZOJ2132】圈地计划 最小割

[BZOJ2132]圈地计划 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值.更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益.另外不同的区域连在一起可以得

BZOJ 2132 圈地计划 最小割

题目大意:给定一个m*n的矩阵,每个位置如果作为商业区或者工业区各有一个收益,如果相邻两块是不同的也会有一个收益,求最大收益 吐槽:住宅区呢- - 地理老师骗我们- - 普通的最小割建图会遇到一个问题: 割断两块之间的边收益为正,即代价为负 因此我们如果正常建最小割,那么两块之间的边权就会是负的 那么我们将这个矩阵黑白染色,将白格ST反向 这样割断两块之间的连边相当于两块选择了同一用途,代价为正 就可以正常跑了 #include <cstdio> #include <cstring>

bzoj2132圈地计划

bzoj2132圈地计划 题意: 一块土地可以纵横划分为N×M块小区域.于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益.而如果区域(i,j)相邻(相邻是指两个格子有公共边)有K块(显然K不超过4)类型不同于(i,j)的区域,则这块区域能增加k×Cij收益.已知收益矩阵A,B,C,求收益最大值. 题解: 因为附加收益不是两两之间的,所以不用考虑除以2的问题.由于需要两块土地属性不同,所以对整个棋盘进行黑白染色.如果一块土地A为黑色,则s->A :c[A商] A->T

线性规划与网络流24题第2题 太空飞行计划 最小割

/** 题目: 线性规划与网络流24题第2题 太空飞行计划 最小割 链接:http://www.cogs.pro/cogs/problem/problem.php?pid=727 题意:lv 思路:最大点权独立集(点集中任意两个点没有边相连,且点权和最大)=点权总和-最小点权覆盖集. 将实验和仪器看做节点. 实验放在二分图的左边, s->x, cap = 实验利润. 仪器放在右边, x->t, cap = 仪器费用. 如果实验u的进行需要仪器v,u->v, cap = INF. ans

BZOJ2132 圈地计划 【最小割】

题目 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解, 这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根 据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值.更具体点,对于第i行第j列的区域, 建造商业区将得到Aij收益,建造工业区将得到Bij收益.另外不同的区域连在一起可以得到额外的收益,即如果区 域(I,j)相邻(

[BZOJ2132] 圈地计划

Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 1350  Solved: 637[Submit][Status][Discuss] Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根据不同的地形环境,每块小区域建造商业

关于一类最小割图的建法

具体就是bzoj3894文理文科,bzoj2127happiness,bzoj2132圈地计划. 一个图,每个点可以选择A或者B,然后选A是获得收益ai,选b是获得收益bi. 首先是万能方法,对于很多图都可以:一个集合内的点同时选A(或者B)可以获得某个收益ci,那么再建一个点,那个点连A流量为c的边,连集合内每个点一条maxlongint的边,这样就保证如果集合内有选B的,那么这条边一定蛮流(被割掉). bzoj3894就是这种方法,然后多年前写云的小P(还是小M)的牧场也是这种方法. 然后是

【bzoj2132】圈地计划 网络流最小割

题目描述 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值.更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益.另外不同的区域连在一起可以得到额外的收益,即如果区域(I,j)相邻(相邻

BZOJ 2132 圈地计划(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2132 题意:n*m的格子染色黑白,对于格子(i,j)染黑色则价值为A[i][j],白色为B[i][j].若一个格子四周不同颜色的有x个,则额外的价值为x*C[i][j].求最大价值. 思路:将格子黑白染色分成两个集合X和Y.S集合为X中的A和Y中的B,T为X中的B和Y中的A.相邻的连边为两个格子的C值之和.总权值减去最小割即是答案. struct node { int v,cap,ne