Luogu P2045 checkered take several enhanced solution to a problem

Cackle

So I will not do network flow ah. . .

Make a template and more relaxed ah, why it was built map,The sky so blue, then green forest, how beautiful this world ah!

Map building routine feel better ah. . Or slowly learning it. .

Solution

Topic analysis / map building

Because the direction of the limit, but also limits each to take the most time, and maximum requirements, think of what?Think nothing The maximum cost maximum flow!

Because each point can only choose once, so we consider this point apart, into a point, one exit point, and then between the in and out points on a traffic even as \ (1 \) , costs \ (val_i \) side. But after each number can still take a pass this position, so even in a flow between two points even as \ (INF \) , cost \ (0 \) side to this point indicates the number of take off after that, you can still pass freely.

Because each point can only point to the right and below it, even from this point a flow to it even to the point of a point to point \ (INF \) , cost \ (0 \) edges express connectivity.

A super virtual source point, even to the point of the first point, the flow is \ (k \) , cost \ (0 \) , restrictions can only take \ (k \) times.

A super virtual meeting point, a point from the last even to the point of change point, flow \ (k \) , cost \ (0 \) , but also limit the role can only take \ (k \) times.

Then run again is the biggest cost maximum flow template.

Tips

① for limiting the number of the access point, it can be split into two points, an even flow between the two sides of the frequency of use; If we take the finished, but still can pass, the flow then even a \ (INF \) side.

② maximum cost maximum flow, costs just want to take the opposite side of the whole number, and then run the minimum cost maximum flow, and finally get the answer once again take the opposite number to.

Code

#include<bits/stdc++.h>
#define del(a,i) memset(a,i,sizeof(a))
#define ll long long
#define inl inline
#define il inl void
#define it inl int
#define ill inl ll
#define re register
#define ri re int
#define rl re ll
#define mid ((l+r)>>1)
#define lowbit(x) (x&(-x))
#define INF 0x3f3f3f3f
using namespace std;
template<class T>il read(T &x){
    int f=1;char k=getchar();x=0;
    for(;k>'9'||k<'0';k=getchar()) if(k=='-') f=-1;
    for(;k>='0'&&k<='9';k=getchar()) x=(x<<3)+(x<<1)+k-'0';
    x*=f;
}
template<class T>il print(T x){
    if(x/10) print(x/10);
    putchar(x%10+'0');
}
ll mul(ll a,ll b,ll mod){long double c=1.;return (a*b-(ll)(c*a*b/mod)*mod)%mod;}
it qpow(int x,int m,int mod){
    int res=1,bas=x%mod;
    while(m){
        if(m&1) res=(res*bas)%mod;
        bas=(bas*bas)%mod,m>>=1;
    }
    return res%mod;
}
const int MAXN = 5e3+5;
int n,m,s,t,val,head[MAXN],num_edge=-1,pre[MAXN],last[MAXN],dis[MAXN],flow[MAXN],ans;
struct Edge{
    int next,to,w,c;
    Edge(){}
    Edge(int next,int to,int w,int c):next(next),to(to),w(w),c(c){}
}edge[MAXN<<2];
il add_edge(int u,int v,int w,int c){
    edge[++num_edge]=Edge(head[u],v,w,c),head[u]=num_edge;
    edge[++num_edge]=Edge(head[v],u,0,-c),head[v]=num_edge;
}
bool tr[MAXN];
inl bool SPFA(int s,int t){
    queue<int> q;q.push(s);
    del(dis,0x3f),del(flow,0x3f);
    dis[s]=0,pre[t]=-1,tr[s]=1;
    while(!q.empty()){
        ri pos=q.front();q.pop();tr[pos]=0;
        for(ri i=head[pos];i!=-1;i=edge[i].next)
            if(dis[edge[i].to]>dis[pos]+edge[i].c&&edge[i].w>0){
                dis[edge[i].to]=dis[pos]+edge[i].c;
                pre[edge[i].to]=pos,last[edge[i].to]=i;
                flow[edge[i].to]=min(flow[pos],edge[i].w);
                if(!tr[edge[i].to]) q.push(edge[i].to),tr[edge[i].to]=1;
            }
    }
    return pre[t]!=-1;
}
il MCMF(int s,int t){
    while(SPFA(s,t)){
        ans+=flow[t]*dis[t];
        for(ri u=t;u^s;u=pre[u]) edge[last[u]].w-=flow[t],edge[last[u]^1].w+=flow[t];
    }
}
int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n),read(m),t=n*n*2+1,del(head,-1);
    for(ri i=1;i<=n;++i)
        for(ri j=1;j<=n;++j){
            read(val);
            add_edge(2*((i-1)*n+j)-1,2*((i-1)*n+j),1,-val),add_edge(2*((i-1)*n+j)-1,2*((i-1)*n+j),INF,0);
            if(j!=n) add_edge(2*((i-1)*n+j),2*((i-1)*n+j+1)-1,INF,0);
            if(i!=n) add_edge(2*((i-1)*n+j),2*(i*n+j)-1,INF,0);
        }
    add_edge(s,1,m,0),add_edge(n*n*2,t,m,0);
    MCMF(s,t);
    printf("%d",-ans);
    return 0;
}

to sum up

The main topic of network flow or build, and FIG completed, then the rest is a template. For different problems should be approached, but do question when to pay attention to the accumulation of skills to build graphs.

Konjac and \ (dalao \) who are still far away, to refuel ah! !

Guess you like

Origin www.cnblogs.com/TheShadow/p/11371517.html