HDU1565 方格取数1(构图+网络流最大独立集合)
题目大意:给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
解题思路:最大点权独立集,关键是怎么建图了,我们可以采用染色的思想对这张图进行染色,然后分成两个点集
假设将第一个格子染成白色,然后将它相邻的格子染成相反的颜色黑色,以此类推,这样就可以将一张图分成染成黑白两种颜色的点集了
然后就是连边了,连边的话,我们只考虑白色格子的连向黑色格子的,因为两者之间是相对的,所以只需要取一条就好了
这样图就建好了
最大独立集就是:总权值-最小割了(最小割就是最小点权覆盖了)
最小割即最大流
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
using namespace std;
int n,a[][];
#define MAXN 500
#define MAXE 1100000
#define INF 0x7fffffff
int ne,nv,s,t;
int size,net[MAXN];
struct EDGE{
int v,next;
int cap;
int flow;
}edge[MAXE]; void init(){
size=;
memset(net,-,sizeof(net));
}
void add(int u,int v,int cap){
//cout<<u<<" "<<v<<" "<<cap<<endl;
ne++;
edge[size].v = v;
edge[size].cap = cap;
edge[size].flow = ;
edge[size].next = net[u];
net[u] = size;
++size; edge[size].v = u;
edge[size].cap = ;
edge[size].flow = ;
edge[size].next = net[v];
net[v] = size;
++size;
} int gap[MAXN];//gap优化
int dist[MAXN];//距离标号
int pre[MAXN];//前驱
int curedge[MAXN];//当前弧 int ISAP(){
int cur_flow,u,temp,neck,i;
int max_flow;
memset(gap,,sizeof(gap));
memset(pre,-,sizeof(pre));
memset(dist,,sizeof(dist));
for(i=;i<=nv;i++) curedge[i]=net[i];//将当前弧初始话成邻接表的第一条边
gap[nv]=nv;
max_flow=;
u=s;
while(dist[s]<nv){
if(u==t){//找到一条增广路
cur_flow=INF;
for(i=s;i!=t;i=edge[curedge[i]].v){//沿着增广路找到最小增广流量
if(cur_flow>edge[curedge[i]].cap){
neck=i;
cur_flow=edge[curedge[i]].cap;
}
}
for(i=s;i!=t;i=edge[curedge[i]].v){//更新
temp=curedge[i];
edge[temp].cap-=cur_flow;
edge[temp].flow+=cur_flow;
temp^=;
edge[temp].cap+=cur_flow;
edge[temp].flow-=cur_flow;
}
max_flow+=cur_flow;
u=neck;//下次直接从关键边的u开始新一轮的增广
}
for(i=curedge[u];i!=-;i=edge[i].next)//找到一条允许弧
if(edge[i].cap>&&dist[u]==dist[edge[i].v]+)
break;
if(i!=-){//如果找到 将u指向v
curedge[u]=i;
pre[edge[i].v]=u;
u=edge[i].v;
}
else{//找不到
if(==--gap[dist[u]]) break;//出现断层
curedge[u] = net[u];//把当前弧重新设为邻接表中满足要求的第一条弧
for(temp=nv,i=net[u];i!=-;i=edge[i].next)
if(edge[i].cap > )
temp=temp<dist[edge[i].v]?temp:dist[edge[i].v];
dist[u]=temp+;//将这个点的距离标号设为由它出发的所有弧的终点的距离标号的最小值加1
++gap[dist[u]];
if(u!=s)u=pre[u];
}
}
//cout<<max_flow<<endl;
return max_flow;
}
int main()
{
while (~scanf("%d",&n))
{
init();
int i,j,sum=;
for (i=;i<=n;i++)
for (j=;j<=n;j++) scanf("%d",&a[i][j]),sum+=a[i][j];
ne=;
nv=n*n+;
s=;
t=n*n+;
for (i=;i<=n;i++)
for (j=;j<=n;j++)
if ((i+j)&) add(n*(i-)+j+,n*n+,a[i][j]); else
{
add(,n*(i-)+j+,a[i][j]);
if (i>) add(n*(i-)+j+,n*(i-)+j+,(<<)-);
if (i<n) add(n*(i-)+j+,n*i+j+,(<<)-);
if (j>) add(n*(i-)+j+,n*(i-)+j,(<<)-);
if (j<n) add(n*(i-)+j+,n*(i-)+j+,(<<)-);
}
//cout<<nv<<" "<<ne<<endl;
printf("%d\n",sum-ISAP());
}
return ;
}
HDU1565 方格取数1(构图+网络流最大独立集合)的更多相关文章
- HDU1565 方格取数(1) —— 状压DP or 插头DP(轮廓线更新) or 二分图点带权最大独立集(最小割最大流)
题目链接:https://vjudge.net/problem/HDU-1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)
Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流) Description 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从 ...
- HDU-1565 方格取数(1)
http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Me ...
- P2774 方格取数问题(网络流)
P2774 方格取数问题 emm........仔细一看,这不是最大权闭合子图的题吗! 取一个点$(x,y)$,限制条件是同时取$(x,y+1),(x,y-1),(x+1,y),(x-1,y)$,只不 ...
- HDU1565 方格取数 &&uva 11270 轮廓线DP
方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- Hdu-1565 方格取数(1) (状态压缩dp入门题
方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HLG 2163 方格取数 (最大网络流)
题目链接: m=ProblemSet&a=showProblem&problem_id=2163">点击打开链接 Description : 给你一个n*n的格子的棋 ...
- HDU1565 方格取数(1)
Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数 ...
- HDU1565 方格取数(1)(状态压缩dp)
题目链接. 分析: 说这题是状态压缩dp,其实不是,怎么说呢,题目数据太水了,所以就过了.手动输入n=20的情况,超时.正解是网络流,不太会. A这题时有个细节错了,是dp[i][j]还是dp[i][ ...
随机推荐
- deepin 安装maven
1.在官网 http://maven.apache.org/download.cgi 下载mvn包 2.新建mvn目录 mkdir /usr/local/mvn 把压缩包解压到mvn目录下面 修 ...
- MVC、MVP和MVVM的图示
一.MVC MVC模式的意思是,软件可以分成三个部分. 视图(View):用户界面. 控制器(Controller):业务逻辑 模型(Model):数据保存 各部分之间的通信方式如下. View 传送 ...
- Node“getTextContent() is undefined for the type Node”处理办法
最近一个项目在MyEclipse导入后总是报getTextContent() is undefined for the type Node错误. 经过查找原来是因为Node类为JDK中自带的(org. ...
- 【IIS7.5】Asp文件上传限制,加载页面大小限制
运行环境 window server 2008 R2 X64.IIS7.5.应用程序池.Net4.0 经典模式 分析 IIS7.5默认有两处上传限制: 第一处在,选择左侧的站点,然后找到后侧的管理—— ...
- 在struct 中使用string,赋值会报错
struct中最好使用char来代替string,因为string的大小不是固定的
- 联想 P70-t 免解锁BL 免rec Magisk Xposed 救砖 ROOT
>>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...
- Pro ASP.NET Core MVC 第6版翻译 目录页
Pro ASP.NET Core MVC 第6版 目录 第一部分 第一章 ASP.NET Core MVC 的前世今生 第二章 第一个MVC应用程序(上) 第二章 第一个MVC应用程序(下) 第三章 ...
- solr深分页,游标操作分页,解决性能问题
solr深分页,游标操作分页,解决性能问题 @Test public void pageByCursor() { try { solrServer.connect(); String query = ...
- 【译】x86程序员手册24-第7章 多任务
Chapter 7 Multitasking 多任务 To provide efficient, protected multitasking, the 80386 employs several s ...
- SDK_列表控件的使用
列表控件的使用 列表控件是通用控件,响应WM_NOTIFY 消息 主要包含了 4 种风格,我们学的是 report 风格 如何设置列表的扩展风格 LVS_EX_GRIDLINES: 列表拥有表格线 L ...