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][ ...
随机推荐
- 反向代理与Real-IP和X-Forwarded-For(转)
如下图所示,客户端通过Nginx Proxy1 和 Nginx Proxy2 两层反向代理才访问到具体服务Nginx Backend(或如Tomcat服务).那Nginx Backend如何才能拿到真 ...
- epoll IO多路复用(异步阻塞AIO)
epoll的异步阻塞(AIO): 用户线程创建epoll后,其实是内核线程负责扫描 fd 列表(在网络服务器上可以是socket,socket在创建后返回的也是文件描述符),并填充事件链表.但是,并不 ...
- win10下spark+Python开发环境配置
Step0:安装好Java ,jdk Step1:下载好: Step2: 将解压后的hadoop和spark设置好环境变量: 在系统path变量里面+: Step3: 使用pip安装 py4j : p ...
- C. Coin Troubles 有依赖的背包 + 完全背包变形
http://codeforces.com/problemset/problem/283/C 一开始的时候,看着样例不懂,为什么5 * a1 + a3不行呢?也是17啊 原来是,题目要求硬币数目a3 ...
- 【转】rpm包和源码包安装的区别
转自:https://blog.csdn.net/junjie_6/article/details/59483785 建议在安装线上的生产服务器软件包时都用源码安装,这是因为源码安装可以自行调整编译参 ...
- Spartan6系列之芯片配置模式详解
1. 配置概述 Spartan6系列FPGA通过把应用程序数据导入芯片内部存储器完成芯片的配置.Spart-6 FPGA可以自己从外部非易失性存储器导入编程数据,或者通过外界的微处理器.DSP等对 ...
- 【sqli-labs】 less65 GET -Challenge -Blind -130 queries allowed -Variation4 (GET型 挑战 盲注 只允许130次查询 变化4)
双引号括号闭合 http://192.168.136.128/sqli-labs-master/Less-65/?id=1")%23
- parsley之验证属性设置
parsley.js添加表单验证功能,直接在html元素中添加对应属性: Name API Description Required #2.0必填 required HTML5 data-parsle ...
- vue组件---插槽
(1)插槽内容 Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 <slot> 元素作为承载分发内容的出口. 在父级组件里可以 ...
- 洛谷——P3003 [USACO10DEC]苹果交货Apple Delivery
P3003 [USACO10DEC]苹果交货Apple Delivery 这题没什么可说的,跑两遍单源最短路就好了 $Spfa$过不了,要使用堆优化的$dijkstra$ 细节:1.必须使用优先队列+ ...