【线性规划与网络流24题 9】方格取数问题

Description

在一个有m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。

编程任务:
对于给定的方格棋盘,按照取数要求编程找出总和最大的数。

Input

第1 行有2 个正整数m和n,分别表示棋盘的行数和列数。
接下来的m行,每行有n个正整数,表示棋盘方格中的数。

Output

程序运行结束时,将取数的最大总和输出

Sample Input

3 3
1 2 3
3 2 3
2 3 1

Sample Output

11


题目链接:

方格取数问题


这个题是一个很经典的问题:最大点权问题

二分图最大点权独立集问题,就是找出图中一些点,使得这些点之间没有边相连,这些点的权值之和最大。
独立集与覆盖集是互补的,求最大点权独立集可以转化为求最小点权覆盖集(最小点权支配集)。最小点权覆盖集问题可以转化为最小割问题解决。
结论:最大点权独立集 = 所有点权 - 最小点权覆盖集 = 所有点权 - 最小割集 = 所有点权 - 网络最大流。

二分图最大点权独立集问题,更多讨论见《最小割模型在信息学竞赛中的应用》作者胡伯涛


这里不会证明

说说思路:把这个图黑白染色,使得任意一个黑点的相邻四个点是白点,任意一个白点的相邻四个点是黑点

添加源S和汇T

S向所有的黑点连接一条容量为黑点格子中数值的有向边(很经典的思路,化格子中的点权为S的边权)

所有的黑点向T连接一条容量为白点格子中数值的有向边

然后,对于相邻的两个点,从黑点向白点连接一条容量为INF的有向边


这里,就只贴出来黑白染色的代码和连边的代码了

int main(){
	//freopen("input.txt","r",stdin);
	int m,n,s,t,tot,ans=0,x,y;
	init();
	scanf("%d%d",&n,&m);
	s=n*m;t=n*m+1;tot=n*m+2;x=0;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			if (i%2==0)
				num[i][j]=x++;
			else
				num[i][m-j-1]=x++;
	//for(int i=0;i<n;i++)
	//	for(int j=0;j<m;j++)
	//		printf("%d%c",num[i][j],j==m-1?'\n':' ');
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			scanf("%d",&mp[i][j]);
	//for(int i=0;i<n;i++)
	//	for(int j=0;j<m;j++)
	//		printf("%d%c",mp[i][j],j==m-1?'\n':' ');
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++){
			ans+=mp[i][j];
			if (num[i][j]%2==0){
				if (i<n-1) addedge(num[i][j],num[i+1][j],INF);
				if (j<m-1) addedge(num[i][j],num[i][j+1],INF);
				if (i>0) addedge(num[i][j],num[i-1][j],INF);
				if (j>0) addedge(num[i][j],num[i][j-1],INF);
				addedge(s,num[i][j],mp[i][j]);
			}
			else{
				addedge(num[i][j],t,mp[i][j]);
			}
		}
	//printf("%d\n",ans);
	int maxflow=dinic(s,t,tot);
	//printf("%d\n",maxflow);
	printf("%d\n",ans-maxflow);
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值