题意:方格取数,如果取了相邻的数,那么要付出一定代价。(代价为2*(X&Y))(开始用费用流,敲升级版3820,跪。。。)

建图:  对于相邻问题,经典方法:奇偶建立二分图。对于相邻两点连边2*(X&Y),源->X连边,Y->汇连边,权值w为点权。

ans=总点权-最小割:如果割边是源->X,表示x不要选(是割边,必然价值在路径上最小),若割边是Y-汇点,同理;若割边是X->Y,则表示选Y点且选X点, 割为w( 2*(X&Y) )。

自己的确还没有理解其本质精妙所在。不知何以然也。(开始多敲多了几个else一直跪!)

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=2550,maxe=20000;
int nume=0;int head[maxv];int e[maxe][3];
void inline adde(int i,int j,int c)
{
e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
e[nume++][2]=c;
e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
e[nume++][2]=0;
}
int ss,tt,n,m,k;
int vis[maxv];int lev[maxv];
bool bfs()
{
for(int i=0;i<maxv;i++)
vis[i]=lev[i]=0;
queue<int>q;
q.push(ss);
vis[ss]=1;
while(!q.empty())
{
int cur=q.front();
q.pop();
for(int i=head[cur];i!=-1;i=e[i][1])
{
int v=e[i][0];
if(!vis[v]&&e[i][2]>0)
{
lev[v]=lev[cur]+1;
vis[v]=1;
q.push(v);
}
}
}
return vis[tt];
}
int dfs(int u,int minf)
{
if(u==tt||minf==0)return minf;
int sumf=0,f;
for(int i=head[u];i!=-1&&minf;i=e[i][1])
{
int v=e[i][0];
if(lev[v]==lev[u]+1&&e[i][2]>0)
{
f=dfs(v,minf<e[i][2]?minf:e[i][2]);
e[i][2]-=f;e[i^1][2]+=f;
sumf+=f;minf-=f;
}
}
if(!sumf) lev[u]=-1;
return sumf;
}
int dinic()
{
int sum=0;
while(bfs())sum+=dfs(ss,inf);
return sum;
};
int mapp[52][52];int must[maxv];int sums=0;
void read_build()
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
scanf("%d",&mapp[i][j]);
sums+=mapp[i][j];
}
int aa,bb;
for(int i=0;i<k;i++)
{
scanf("%d%d",&aa,&bb);
must[(aa-1)*m+bb-1]=1;
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if((i+j)%2==0)
{
if(must[i*m+j])
adde(ss,i*m+j,inf);
else
adde(ss,i*m+j,mapp[i][j]);
if(i-1>=0)
adde(i*m+j,(i-1)*m+j,2*(mapp[i][j]&mapp[i-1][j]));
if(i+1<n)
adde(i*m+j,(i+1)*m+j,2*(mapp[i][j]&mapp[i+1][j]));
if(j-1>=0)
adde(i*m+j,i*m+j-1,2*(mapp[i][j]&mapp[i][j-1]));
if(j+1<m)
adde(i*m+j,i*m+j+1,2*(mapp[i][j]&mapp[i][j+1]));
}
else
{
if(must[i*m+j])
adde(i*m+j,tt,inf);
else
adde(i*m+j,tt,mapp[i][j]);
}
}
/* for(int i=0;i<=tt;i++)
for(int j=head[i];j!=-1;j=e[j][1])
{
if(j%2==0)
printf("%d->%d:%d\n",i,e[j][0],e[j][2]);
}*/
}
void init()
{
nume=0;sums=0;
ss=n*m+2;tt=ss+1;
for(int i=0;i<=tt;i++)
{
head[i]=-1;
must[i]=0;
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
init();
read_build();
int ans;
ans=sums-dinic();
printf("%d\n",ans);
}
return 0;
}

hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割的更多相关文章

  1. hdu 4859 最大点权独立集的变形(方格取数的变形)

    /*刚开始不会写,最大点权独立集神马都不知道,在潘神的指导下终于做出来,灰常感谢ps: 和方格取数差不多奇偶建图,对于D必割点权为0,对于.必然不割点权为inf.然后和方格取数差不多的建图 .--.| ...

  2. P2774 方格取数问题 网络最大流 割

    P2774 方格取数问题:https://www.luogu.org/problemnew/show/P2774 题意: 给定一个矩阵,取出不相邻的数字,使得数字的和最大. 思路: 可以把方格分成两个 ...

  3. HDU 3861 The King’s Problem(tarjan缩点+最小路径覆盖:sig-最大二分匹配数,经典题)

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)

    转载:http://blog.csdn.net/cold__v__moon/article/details/7924269 /* 这道题和方格取数2相似,是在方格取数2的基础上的变形. 方格取数2解法 ...

  5. HDU 1569 方格取数(2) (最小割)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  6. 【BZOJ1475】方格取数 [最小割]

    方格取数 Time Limit: 5 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description 在一个n*n的方格里,每个格子里都有一 ...

  7. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  8. hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)

    /** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...

  9. [BZOJ1475]方格取数 网络流 最小割

    1475: 方格取数 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 512[Submit][Status][Discuss] ...

随机推荐

  1. Python入门必学:递归函数正确的操作使用方法,案例详解

    递归函数,在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以 ...

  2. UVA - 753 A Plug for UNIX(网络流)

    题意 给定一些插头设备和插座,有一些方法可以把其中一些插头变成另一种插头.求无法匹配插座的插头设备个数. 题解 用\(map\)给每个字符串标号为\(a_i\)和\(b_i\). 读入每种改变插头的方 ...

  3. 笔记-python-standard library-12.1 pickle

    笔记-python-standard library-12.1 pickle 1.      pickle简介 source code: Lib/pickle.py pickle模块实质上是一个实现p ...

  4. Android拨打电话不弹出系统拨号界面总结

    我在网上搜了一下,解决这个问题,有两种方式: 1.反射调用系统底层方法,并获取系统权限 反射调用的代码如下: Class phoneFactoryClass = Class.forName(" ...

  5. Eclipse 读取config目录下文件

    最近在一个项目,在项目下新建了一个config配置文件夹,添加一个配置文件config.properties. 使用classpath:config.properties方式加载配置文件, 具体实现代 ...

  6. Jquery查询分析器

    find() 方法获得当前元素集合中每个元素的后代,通过选择器.jQuery 对象或元素来筛选.$(this).find("ul[index=1] div input:radio:check ...

  7. Linux之匿名FTP服务器搭建

    FTP(File Transfer Protocol)是在服务器与客户端进行文件传输的一种传输协议.本次介绍的是vsftpd的软件体验ftp服务. FTP服务器默认情况下依据用户登录情况分为三种不同的 ...

  8. Hive jdbc连接出现java.sql.SQLException: enabling autocommit is not supported

    1.代码如下 String url = "jdbc:hive2://master135:10000/default"; String user = "root" ...

  9. centos 7 配置ip

    1.动态获取ip(前提是你的路由器已经开启了DHCP) 修改网卡配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens32    (最后一个为网卡名称) 动态 ...

  10. TOJ 4689: Sawtooth

    4689: Sawtooth Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal Submit: 26     ...