hdu1565+hdu1569(最大点权独立集)
传送门:hdu1565 方格取数(1)
传送门:hdu1569 方格取数(2)
定理:
1. 最小点权覆盖集=最小割=最大流
2. 最大点权独立集=总权-最小点权覆盖集
步骤:
1. 先染色,取一个点染白色,和它相邻的点染黑色
2. 每个白点向它相邻的黑点连一条边,容量为 inf (无穷大)
3. 增加源点S,向每一个白色点连一条边,容量为白点的权
4. 增加汇点T,每个黑点向T连一条边,容量为黑点的权
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <limits.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 100000000
#define inf 0x3f3f3f3f
#define eps 1e-6
#define N 2510
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PII pair<int,int>
using namespace std;
inline int read()
{
char ch=getchar();
int x=,f=;
while(ch>''||ch<''){if(ch=='-')f=-;ch=getchar();}
while(ch<=''&&ch>=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,vs,vt,tot,NV;
int head[N],gap[N],level[N],q[N];
struct edge
{
int v,w,next;
edge(){}
edge(int v,int w,int next):v(v),w(w),next(next){}
}e[N*N];
void addedge(int u,int v,int w)
{
e[tot]=edge(v,w,head[u]);
head[u]=tot++;
e[tot]=edge(u,,head[v]);
head[v]=tot++;
}
void init()
{
memset(head,-,sizeof(head));
tot=;
}
/***************************SAP***********************/
void bfs(int vt)
{
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int>que;
que.push(vt);
while(!que.empty()) {
int u=que.front();
que.pop();
for(int i=head[u]; i!=-; i=e[i].next) {
int v=e[i].v;
if(level[v]!=-)continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v); }
}
}
int pre[N];
int cur[N];
int SAP()
{
bfs(vt);
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=inf;
gap[]=NV;
while(level[vs]<NV) {
bool flag=false;
for(int &i=cur[u]; i!=-; i=e[i].next) {
int v=e[i].v;
if(e[i].w&&level[u]==level[v]+) {
flag=true;
pre[v]=u;
u=v;
aug=min(aug,e[i].w);
if(v==vt) {
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]) {
e[cur[u]].w-=aug;
e[cur[u]^].w+=aug;
}
aug=inf;
}
break;
}
}
if(flag)continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=e[i].next) {
int v=e[i].v;
if(e[i].w&&level[v]<minlevel) {
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==)break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
}
/**************************SAP**********************/
int sum,x,num[][],id[][];
bool judge(int i,int j)
{
return i>=&&i<=n&&j>=&&j<=m;
}
void build()
{
sum=x=;NV=n*m+;
vs=;vt=n*m+;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
x++;
num[i][j]=read();
sum+=num[i][j];
id[i][j]=x;
}
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if((i+j)&)
{
addedge(id[i][j],vt,num[i][j]);
}
else
{
addedge(vs,id[i][j],num[i][j]);
for(int x=-;x<=;x++)
for(int y=-;y<=;y++)
{
if(x+y==||x==y||!judge(x+i,y+j))continue;
addedge(id[i][j],id[i+x][j+y],inf);
}
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)>)
{
init();
build();
printf("%d\n",sum-SAP());
}
}
hdu1565+hdu1569(最大点权独立集)的更多相关文章
- hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...
- 【最大点权独立集】【HDU1565】【方格取数】
题目大意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. 初看: 没想法 ...
- HDU1569 最大流(最大点权独立集)
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- hdu1569 方格取数 求最大点权独立集
题意:一个方格n*m,取出一些点,要求两两不相邻,求最大和.思路:建图,相邻的点有一条边,则建立了一个二分图,求最大点权独立集(所取点两两无公共边,权值和最大),问题转化为求总权和-最小点权覆盖集(点 ...
- 【BZOJ-1952】城市规划 [坑题] 仙人掌DP + 最大点权独立集(改)
1952: [Sdoi2010]城市规划 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 73 Solved: 23[Submit][Status][ ...
- HDU 1565 最大点权独立集
首先要明白图论的几个定义: 点覆盖.最小点覆盖: 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是“点” 覆盖了所有“边”.. 最小点覆盖(minimum vertex covering ...
- SCU3185 Black and white(二分图最大点权独立集)
题目大概说有几个黑色.白色矩阵,问能选出黑白不相交的矩形面积和的最大值. 建二分图,黑色矩阵为X部的点,白色为Y部,XY的点权都为其矩阵面积,如果有个黑白矩阵相交则它们之间有一条边,那样问题就是要从这 ...
- zoj 3165 (最小割,最大点权独立集)
胡伯涛的<最小割模型在信息学竞赛中的应用>写的真牛. 这道题是选择一些男孩和女孩参加party,邀请的男孩女孩之间不能有 8g,图就是个明显的二分图,就是选择一些点之间没有8g关系,就是二 ...
- HDU1569+最大点权集
/* 最大点权独立集=总权值-最小点权覆盖集 最大点权独立集=最大流 最小点权覆盖集=最小割 题意: 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格 ...
随机推荐
- Apache Thrift的简单使用
Apache Thrift的简单使用 ---------------------- 1. 简介 Thrift是Facebook的一个开源项目,主要是一个跨语言的服务开发框架.它有一个代码生成器来对它所 ...
- Delphi中拖动无边框窗口的5种方法
1.MouseMove事件中加入: // ReleaseCapture;// Perform(WM_SYSCOMMAND, $F017 , 0); 2.MouseDown事件中加入: // POSTM ...
- 信号槽所用的参数类型,必须是Qt能认识的元类型,否则就要调用Q_DECLARE_METATYPE和qRegisterMetaType进行注册
虽然上面部分中的声明使类型可以在direct信号槽连接中使用,但是无法用于queued信号槽连接中 http://blog.csdn.net/u011012932/article/details/52 ...
- hbase:应用开发
开发环境: hadoop: hadoop-1.1.2 hbase: hbase-0.94.11-security eclipse:Juno Service Release 2 配置Eclipse 通过 ...
- scrum经验
Scrum是基于过程控制理论的经验方法,倡导自组织团队:其运行框架核心是迭代增量型并行开发,也是“适应性”的软件开发方法.Scrum提供了高度可视化的用于管理软件开发复杂性管理的敏捷项目管理的实践框架 ...
- Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源码
在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现.下面要说的就是上次Scroller ...
- DELPHI XE7 新的并行库
DELPHI XE7 的新功能列表里面增加了并行库System.Threading, System.SyncObjs. 为什么要增加新的并行库? 还是为了跨平台.以前要并行编程只能从TThread类继 ...
- 基于visual Studio2013解决面试题之0204最大子集数组
题目
- hdu 4714 Tree2cycle dp
用树形dp做的,dp[t][i]表示t及其孩子入度都已经小于等于2并且t这个节点的入度等于i的最优解. 那么转移什么的自己想想就能明白了. 关键在于这个题目会暴栈,所以我用了一次bfs搜索出节点的顺序 ...
- 制作openstack用的centos6.5镜像
目的: 在centos6.5操作系统环境下制作一个centos6.5的kvm镜像,安装cloud-init,能自己主动扩展根分区 一.制作环境: 操作环境是在openstack平台开一个实例.装的是c ...