首先,我们要读懂这道题,否则你会和我一开始产生一样的疑问,把所有的数都取走剩下一个最小的不就可以了么???然后我们发现样例完全不是这么回事。题目中所说的使相邻的两个数没有公共边,是指你去走的数,也就是取完之后矩阵里的空白格子。明白了这一点,我们可能会有一个比较基础的贪心思想,没错,就是隔一个取一个,但是这么做并不可行,具体反例很容易找。然后我们通过观察,发现这道题和某最大权闭合子图有些类似,如果我们全取所有点,删去最小割说不准可行。
开始考虑建图,首先所有的奇数格子连源点,偶数格子连汇点,边权为点权。他们之间的边只连奇数到偶数的,边权为inf,这么连是为了避免重复计算。然后直接DINIC最大流就可以了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long
#define inf 50000000
#define re register
#define id m*(i-1)+j
using namespace std;
struct po
{
int from,to,dis,nxt;
}edge[];
int head[],cur[],dep[],n,m,s,t,u,num=-,x,y,l,tot,sum,d;
int nm,a[][];
int dx[]={,,,-,};
int dy[]={,,,,-};
inline int read()
{
int x=,c=;
char ch=' ';
while((ch>''||ch<'')&&ch!='-')ch=getchar();
while(ch=='-')c*=-,ch=getchar();
while(ch<=''&&ch>='')x=x*+ch-'',ch=getchar();
return x*c;
}
inline void add_edge(int from,int to,int dis)
{
edge[++num].nxt=head[from];
edge[num].from=from;
edge[num].to=to;
edge[num].dis=dis;
head[from]=num;
}
inline void add(int from,int to,int dis)
{
add_edge(from,to,dis);
add_edge(to,from,);
}
inline bool bfs()
{
memset(dep,,sizeof(dep));
queue<int> q;
while(!q.empty())
q.pop();
dep[s]=;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
for(re int i=head[now];i!=-;i=edge[i].nxt)
{
int v=edge[i].to;
if(dep[v]==&&edge[i].dis>)
{
dep[v]=dep[now]+;
if(v==t)
return ;
q.push(v);
}
}
}
return ;
}
inline int dfs(int u,int dis)
{
if(u==t)
return dis;
int diss=;
for(re int i=head[u];i!=-;i=edge[i].nxt)
{
int v=edge[i].to;
if(dep[v]==dep[u]+&&edge[i].dis!=)
{
int check=dfs(v,min(dis,edge[i].dis));
if(check>)
{
diss+=check;
dis-=check;
edge[i].dis-=check;
edge[i^].dis+=check;
if(dis==) break;
}
}
}
return diss;
}
inline int dinic()
{
int ans=;
while(bfs())
{
for(re int i=;i<=t;i++)
cur[i]=head[i];
while(int d=dfs(s,inf))
ans+=d;
}
return ans;
}
int main()
{
memset(head,-,sizeof(head));
n=read();m=read();
s=;t=n*m+;
for(re int i=;i<=n;i++)
for(re int j=;j<=m;j++)
a[i][j]=read(),sum+=a[i][j];
for(re int i=;i<=n;i++)
for(re int j=;j<=m;j++)
{
if((i+j)%==)
add(s,id,a[i][j]);
else
add(id,t,a[i][j]);
for(re int h=;h<=;h++)
{
int lx=i+dx[h],ly=j+dy[h];
if(lx>=&&lx<=n&&ly>=&&ly<=m)
if((lx+ly)%!=)
add(id,(lx-)*m+ly,inf);
}
}
cout<<sum-dinic();
}

【P2774】方格取数问题(贪心+最大流,洛谷)的更多相关文章

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

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

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

    题目: P2774 方格取数问题 题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...

  3. P2774 方格取数问题(最小割)

    P2774 方格取数问题 一看题目便知是网络流,但由于无法建图.... 题目直说禁止那些条件,这导致我们直接建图做不到,既然如此,我们这是就要逆向思维,他禁止那些边,我们就连那些边. 我们将棋盘染色, ...

  4. P2774 方格取数问题(网络流)

    P2774 方格取数问题 emm........仔细一看,这不是最大权闭合子图的题吗! 取一个点$(x,y)$,限制条件是同时取$(x,y+1),(x,y-1),(x+1,y),(x-1,y)$,只不 ...

  5. 洛谷 P2774 方格取数问题 解题报告

    P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...

  6. P2774 方格取数问题 网络流重温

    P2774 方格取数问题 这个题目之前写过一次,现在重温还是感觉有点难,可能之前没有理解透彻. 这个题目要求取一定数量的数,并且这些数在方格里面不能相邻,问取完数之后和最大是多少. 这个很好的用了网络 ...

  7. P2774 方格取数(网络流)

    https://www.luogu.com.cn/problem/P2774 在一个有 m×n 个方格的棋盘中,每个方格中有一个正整数. 现要从方格中取数,使任意2个数所在方格没有公共边,且取出的数的 ...

  8. 【wikioi】1907 方格取数3(最大流+最大权闭合子图)

    http://www.wikioi.com/problem/1907/ 这题我一开始想到的是状压,看到n<=30果断放弃. 然后也想到了黑白染色,然后脑残了,没想到怎么连边. 很简单的一题 黑白 ...

  9. 洛谷 P2045 方格取数加强版【费用流】

        题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...

  10. 【Codevs1227】方格取数2(费用流)

    题意:给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000) 现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成 ...

随机推荐

  1. [Spring MVC]学习笔记--@Controller

    在讲解@Controller之前,先说明一下Spring MVC的官方文档在哪. 可能会有人和我一样,在刚接触Spring MVC时,发现在Spring的网站上找不到Spring MVC这个项目. 这 ...

  2. Adjacency List

    w Python Patterns - Implementing Graphs | Python.orghttps://www.python.org/doc/essays/graphs/ Graph ...

  3. CAP theorem

    https://en.wikipedia.org/wiki/CAP_theorem

  4. Django报:builtin_function_or_method' object is not iterable

    def detail(request,hero_id): hero=models.HeroInfo.objects.get(id=hero_id) return render_to_response( ...

  5. Python线程包装器

    import threading import subprocess import time def need_thread(func, *args, **kwargs): def fun(): pr ...

  6. Linux中的history命令

    history -c  清空历史命令 -w 把缓存中的历史命令写入历史命令保存文件说明: a.在用户登录的时候执行的命令会先存在缓存里 b.当用户退出的时候会把缓存里的命令写到文件里 c.用会执行命令 ...

  7. ApexSQL Log 从意外UPDATE和DELETE操作中恢复SQL Server数据

    下载地址:https://www.apexsql.com/download.aspx 如何从意外UPDATE和DELETE操作中恢复SQL Server数据 ApexSQL Log 从意外UPDATE ...

  8. PyQt4测试安装ok的程序

    # -*- coding: utf-8 -*- """ ------------------------------------------------- File Na ...

  9. 'is' in Python

    在Python中应该避免将“is”运算符用于比较 像“数值”和“字符串”这种不可变的值.由于Python内部操作这些对象的方式,使得对这些对象使用“is”运算符的结果将是不可预测的. 下面以两个例子加 ...

  10. HAProxy详解

    HAProxy概述与配置 一.HAProxy概述 HAProxy是由 WillyTarreau开发的一款具备高可用性.负载均及基于 TCP和 HTTP的应用代理开源软件,基于HAProxy的负载均衡架 ...