hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)
转载:http://blog.csdn.net/cold__v__moon/article/details/7924269
/*
这道题和方格取数2相似,是在方格取数2的基础上的变形。 方格取数2解法:
由题意知对于每一个方格,有选与不选,显然是二分的最大独立集,先求最小点权覆盖(它的补集恰好
是最大点权独立集),对于任何一条可行流 s->u->v->t, 在求最大流或最小割的时候,在这3条边中
至少选一条,将u->v设为inf,u->v就不可能存在于最小割中,就只是2选1,如果s->u或v->t选为最小割
则表示u或v(u和v可同时被选)属于最小点权覆盖,所以最小割=最小点权覆盖,再求补集就是最大点权独立集。 这道题的变形:
先考虑的答案的补集(类似最小点权覆盖,但不是),和方格取数不同的是可以去相邻的格子但是要减去2*(G[i][j]&G[a][b]);
所以对于答案的补集就是加上2*(G[i][j]&G[a][b]),对于任何一条可行流 s->u->v->t, 当u->v为2*(G[i][j]&G[a][b]),就可以
表示同时选取u,v的情况,对于答案的必选点s->u就是不存在割的s->u为inf;
推荐学习胡伯涛《最小割模型在信息学竞赛中的应用》,其中对最小割的模型应用讲的很清楚
*/
#include <iostream>
#include <memory.h>
#include <stdio.h>
using namespace std;
const int maxn=55;
const int maxm=maxn*maxn;
const int inf=0x3fffffff;
int G[maxn][maxn];
bool f[maxn][maxn];
int head[maxm],dis[maxm],gap[maxm],cur[maxm],e,pre[maxm];
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int source,sink;
struct
{
int t,next,w;
}edge[maxm*6];
void add(int a,int b,int c)
{
//printf("%d->%d %d\n",a,b,c);
edge[e].t=b;
edge[e].w=c;
edge[e].next=head[a];
head[a]=e++;
edge[e].t=a;
edge[e].w=0;
edge[e].next=head[b];
head[b]=e++;
}
int sap(int ncnt)
{
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
for(int i=0;i<=ncnt;i++)
cur[i]=head[i];
int u=pre[source]=source,maxflow=0,aug=inf;
gap[0]=ncnt;
//P();
while(dis[source]<ncnt)
{
loop: for(int &i=cur[u];i!=-1;i=edge[i].next)
{
//P();
int v=edge[i].t;
if(edge[i].w&&dis[u]==dis[v]+1)
{
aug=min(aug,edge[i].w);
pre[v]=u;
//printf("%d-> %d\n",u,v);
u=v;
if(v==sink)
{
maxflow+=aug;
for(u=pre[u];v!=source;v=u,u=pre[u])
{
edge[cur[u]].w-=aug;
edge[cur[u]^1].w+=aug;
//printf("d");
}
aug=inf;
}
goto loop;
}
}
int mindis=ncnt;
//P();
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].t;
if(edge[i].w&&mindis>dis[v])
{
//printf("s");
cur[u]=i;
mindis=dis[v];
}
} if(--gap[dis[u]]==0)
break;
gap[dis[u]=mindis+1]++;
u=pre[u]; } return maxflow;
}
int main()
{
int n,m,a,b,sum,k;
while(~scanf("%d%d%d",&n,&m,&k))
{
sum=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
scanf("%d",&G[i][j]);
sum+=G[i][j];
}
memset(f,false,sizeof(f));
for(int i=0;i<k;i++)
{
scanf("%d%d",&a,&b);
a--;
b--;
f[a][b]=true;
}
memset(head,-1,sizeof(head));
e=0;
source=n*m;
sink=n*m+1;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if((i+j)%2==1)
{
add(source,i*m+j,f[i][j]?inf:G[i][j]);
for(int k=0;k<4;k++)
{
a=i+dir[k][0];
b=j+dir[k][1];
if(a>=0&&a<n&&b>=0&&b<m)
add(i*m+j,a*m+b,(G[i][j]&G[a][b])<<1);
}
}
else add(i*m+j,sink,f[i][j]?inf:G[i][j]);
printf("%d\n",sum-sap(n*m+2)); } return 0;
}
hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)的更多相关文章
- hdu 3657最大点权独立集变形(方格取数变形)
/* 分奇偶为二部图,s与奇建图,t与偶建图,权值为当前数的值,如果遇到必取的权值置为inf. 奇偶建边为相邻的权值为2*(x&y):所有数的值-最小点全覆盖. 置为inf意为不能割掉.奇偶边 ...
- hdu 4859 最大点权独立集的变形(方格取数的变形)
/*刚开始不会写,最大点权独立集神马都不知道,在潘神的指导下终于做出来,灰常感谢ps: 和方格取数差不多奇偶建图,对于D必割点权为0,对于.必然不割点权为inf.然后和方格取数差不多的建图 .--.| ...
- HDU 1565 最大点权独立集
首先要明白图论的几个定义: 点覆盖.最小点覆盖: 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是“点” 覆盖了所有“边”.. 最小点覆盖(minimum vertex covering ...
- hdu 1565&&hdu 1569 (最大点权独立集)
题目意思很明确就是选一些没有相连的数字,使和最大,建成二分图后求最大点权独立集,, #include<stdio.h> #include<string.h> const int ...
- 洛谷 - P2774 - 方格取数问题 - 二分图最大独立点集 - 最小割
https://www.luogu.org/problemnew/show/P2774 把两个相邻的节点连边,这些边就是要方便最小割割断其他边存在的,容量无穷. 这种类似的问题的话,把二分图的一部分( ...
- HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]
嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1569 Time Limi ...
- hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...
- hdu1569 方格取数 求最大点权独立集
题意:一个方格n*m,取出一些点,要求两两不相邻,求最大和.思路:建图,相邻的点有一条边,则建立了一个二分图,求最大点权独立集(所取点两两无公共边,权值和最大),问题转化为求总权和-最小点权覆盖集(点 ...
- HDU 1565 1569 方格取数(最大点权独立集)
HDU 1565 1569 方格取数(最大点权独立集) 题目链接 题意:中文题 思路:最大点权独立集 = 总权值 - 最小割 = 总权值 - 最大流 那么原图周围不能连边,那么就能够分成黑白棋盘.源点 ...
随机推荐
- 洛谷P2340 奶牛会展
题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览.由于负的智商或情商会造成 ...
- django入门与实践 3-1 环境搭建
Python 2.7 .Django对2.7.3.5.3.4都是支持的. https://www.djangoproject.com/download/ django对python的兼容情况 pip安 ...
- JavaScript 中String和int互相转换
在javascript里怎么样才能把int型转换成string型 (1) var num = 0; a = x.toString(); (2) var x = 0; a = x + ...
- E20171016-mk
chaos n. 混乱,紊乱; (天地未出现的) 浑沌世界; 〈古〉无底深渊; 一团糟;
- [Swift通天遁地]二、表格表单-(2)创建右侧带有索引的UITableView(表单视图)
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- [Swift通天遁地]六、智能布局-(1)给视图添加尺寸和中心点的约束
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- 虚拟机下安装VM
Linux(CentOS 7)命令行模式安装VMware Tools 详解 [日期:2017-05-02] 来源:Linux社区 作者:Linux [字体:大 中 小] 本篇文章主要介绍了如何在Li ...
- S2深入.NET编程总结
不知从几何时,我也开始变得懒了,以往为了学习的那股子斗劲也早已不在,是时候反思反思了.失败的检测成绩希望可以把我唤醒. 经过总结,在本书中大概学到了这些知识: 1.如果一个类可序列化,则它的子类和包含 ...
- sql server 无法创建数据库,错误代码:1807
SQL Server 不能创建数据库,发生错误:1807 :未能获得数据库 'model' 上的排它锁.请稍后重试操作. declare @sql varchar(100) while ...
- [Android]异常6-TextView setText延迟显示
背景:Thread和Handler显示数据到界面 解决办法有: 解决一>界面使用了ListView.GridView等,把高度和宽度调整为固定值或者match_parent 解决二>某处U ...