P2045 方格取数加强版

P2045 方格取数加强版

题目描述

给出一个 \(n\times n\) 的矩阵,每一格有一个非负整数 \(A_{i,j}\)\(A_{i,j} \le 10^3\)),现在从 \((1,1)\) 出发,可以往右或者往下走,最后到达 \((n,n)\),每达到一格,把该格子的数取出来,该格子的数就变成 \(0\),这样一共走 \(K\) 次,现在要求 \(K\) 次所达到的方格的数的和最大。

Solution:

有且仅有一点思维难度的费用题,我们考虑拆点来维护每个格子上的数只能被取一次和流量限制:

\(u_{in}\)\(u_{out}\) 连一条费用为 \(a_{u}\) , 流量为 1 的边。

\(u_{in}\)\(u_{out}\) 连一条费用为 0 ,流量为 \(K-1\) 的边。

然后再按题意将 \(u_{out}\) 向他的邻居的 \(in\) 连边就好了。

Code:

#include<bits/stdc++.h>
const int M=55;
const int N=M*M*2;
const int inf=1e9;
using namespace std;
int a[M][M];
int n,m,S,T,ans,cnt=1;
struct Edge{
    int to,w,fl,nxt;
}e[N<<2];int head[N];
inline void add(int x,int y,int w,int fl)
{
    e[++cnt]={y,w,fl,head[x]};head[x]=cnt;
    e[++cnt]={x,-w,0,head[y]};head[y]=cnt;
}
inline int id(int i,int j){return (i-1)*n+j;}
inline int idd(int i,int j){return n*n+id(i,j);}
int dis[N],dl[N],flow[N],pre[N];
inline void init()
{
    for(int u=0;u<=T;u++)dis[u]=-inf,flow[u]=0;
}
queue<int> Q;
bool spfa(int s,int t)
{
    init();flow[s]=m;dis[s]=0;
    Q.push(s);
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();dl[u]=0;
        for(int i=head[u],v,w,fl;i;i=e[i].nxt)
        {
            v=e[i].to,w=e[i].w,fl=e[i].fl;
            if(fl&&dis[v]<dis[u]+w)
            {
                dis[v]=dis[u]+w;flow[v]=min(fl,flow[u]);
                if(!dl[v])Q.push(v);pre[v]=i;
            }
        }
    }
    return dis[t]!=-inf;
}
void dinic()
{
    while(spfa(S,T))
    {
        int now=T,id,res=0;
        ans+=dis[T];
        while(now!=S)
        {
            id=pre[now];e[id].fl--;e[id^1].fl++;now=e[id^1].to;
        }
    }
}
void work()
{
    cin>>n>>m;S=1,T=idd(n,n);

    for(int i=1,x;i<=n;i++)for(int j=1;j<=n;j++)
    {
        scanf("%d",&x);
        add(id(i,j),idd(i,j),x,1);
        add(id(i,j),idd(i,j),0,m-1);
        if(i+1<=n)add(idd(i,j),id(i+1,j),0,m);
        if(j+1<=n)add(idd(i,j),id(i,j+1),0,m);
    }
    dinic();
    cout<<ans;
}
int main()
{
    //freopen("P2045.in","r",stdin);freopen("P2045.out","w",stdout);
    work();
    return 0;
}
posted @ 2025-02-19 14:17  liuboom  阅读(9)  评论(0)    收藏  举报