【P2774】方格取数问题(贪心+最大流,洛谷)

本文针对一道关于矩阵取数的问题进行了解析,介绍了如何通过理解题意并运用最大权闭合子图的思想来解决问题,最终采用DINIC最大流算法求解。

首先,我们要读懂这道题,否则你会和我一开始产生一样的疑问,把所有的数都取走剩下一个最小的不就可以了么???然后我们发现样例完全不是这么回事。题目中所说的使相邻的两个数没有公共边,是指你去走的数,也就是取完之后矩阵里的空白格子。明白了这一点,我们可能会有一个比较基础的贪心思想,没错,就是隔一个取一个,但是这么做并不可行,具体反例很容易找。然后我们通过观察,发现这道题和某最大权闭合子图有些类似,如果我们全取所有点,删去最小割说不准可行。
开始考虑建图,首先所有的奇数格子连源点,偶数格子连汇点,边权为点权。他们之间的边只连奇数到偶数的,边权为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[1000001];
int head[1000001],cur[1000001],dep[60001],n,m,s,t,u,num=-1,x,y,l,tot,sum,d;
int nm,a[120][120];
int dx[5]={0,1,0,-1,0};
int dy[5]={0,0,1,0,-1};
inline int read()
{
    int x=0,c=1;
    char ch=' ';
    while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
    while(ch=='-')c*=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-'0',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,0);
}
inline bool bfs()
{
    memset(dep,0,sizeof(dep));
    queue<int> q;
    while(!q.empty())
    q.pop();
    dep[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(re int i=head[now];i!=-1;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(dep[v]==0&&edge[i].dis>0)
            {
                dep[v]=dep[now]+1;
                if(v==t)
                return 1;
                q.push(v); 
            }
        }
    }
    return 0;
}
inline int dfs(int u,int dis)
{
    if(u==t)
    return dis;
    int diss=0;
    for(re int i=head[u];i!=-1;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(dep[v]==dep[u]+1&&edge[i].dis!=0)
        {
            int check=dfs(v,min(dis,edge[i].dis));
            if(check>0)
            {
                diss+=check;
                dis-=check;
                edge[i].dis-=check;
                edge[i^1].dis+=check;
                if(dis==0) break;
            }
        }
    }
    return diss;
}
inline int dinic()
{
    int ans=0;
    while(bfs())
    {
        for(re int i=0;i<=t;i++)
        cur[i]=head[i];
        while(int d=dfs(s,inf))
        ans+=d;
    }
    return ans;
}
int main()
{
    memset(head,-1,sizeof(head));
    n=read();m=read();
    s=0;t=n*m+1;
    for(re int i=1;i<=n;i++)
     for(re int j=1;j<=m;j++)
     a[i][j]=read(),sum+=a[i][j];
    for(re int i=1;i<=n;i++)
     for(re int j=1;j<=m;j++)
     {
         if((i+j)%2==0)
         add(s,id,a[i][j]);
         else
         add(id,t,a[i][j]);
         for(re int h=1;h<=4;h++)
         {
             int lx=i+dx[h],ly=j+dy[h];
             if(lx>=1&&lx<=n&&ly>=1&&ly<=m)
             if((lx+ly)%2!=0)
             add(id,(lx-1)*m+ly,inf);
        }
     }
     cout<<sum-dinic();
}

 

转载于:https://www.cnblogs.com/victorique/p/8426683.html

标题基于SpringBoot的马术俱乐部管理系统设计实现AI更换标题第1章引言介绍马术俱乐部管理系统的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景意义阐述马术俱乐部管理系统对提升俱乐部管理效率的重要性。1.2国内外研究现状分析国内外马术俱乐部管理系统的发展现状及存在的问题。1.3研究方法以及创新点概述本文采用的研究方法,包括SpringBoot框架的应用,以及系统的创新点。第2章相关理论总结和评述马术俱乐部管理系统相关的现有理论。2.1SpringBoot框架理论介绍SpringBoot框架的基本原理、特点及其在Web开发中的应用。2.2据库设计理论阐述据库设计的基本原则、方法以及在管理系统中的应用。2.3马术俱乐部管理理论概述马术俱乐部管理的基本理论,包括会员管理、课程安排等。第3章系统设计详细描述马术俱乐部管理系统的设计方案,包括架构设计、功能模块设计等。3.1系统架构设计给出系统的整体架构,包括前端、后端和据库的交互方式。3.2功能模块设计详细介绍系统的各个功能模块,如会员管理、课程管理、预约管理等。3.3据库设计阐述据库的设计方案,包括结构、字段设计以及据关系。第4章系统实现介绍马术俱乐部管理系统的实现过程,包括开发环境、编码实现等。4.1开发环境搭建介绍系统开发所需的环境,包括操作系统、开发工具等。4.2编码实现详细介绍系统各个功能模块的编码实现过程。4.3系统测试调试阐述系统的测试方法、测试用例以及调试过程。第5章系统应用分析呈现马术俱乐部管理系统的应用效果,并进行性能分析。5.1系统应用情况介绍系统在马术俱乐部中的实际应用情况。5.2系统性能分析从响应时间、并发处理能力等方面对系统性能进行分析。5.3用户反馈改进收集用户反馈,提出系统改进建议。第6章结论展望总结马术俱乐部管理系统的设计实现成果,并展望未来的研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值