ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

方格取数加强版

2020-03-06 21:55:22  阅读:230  来源: 互联网

标签:加强版 int beg 取数 vis add maxn 方格 dis


努力刷网络流找感觉ing……


 这其实是一个费用流,拆点,流量为1,费用为val。

求其最大费用流,可以转化为边权相反,求最小费用流的相反数。

看代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
int val[100][100];
int n,k;
const int maxn=1e5+10;
int beg[maxn],nex[maxn],to[maxn],w[maxn],f[maxn],e;
inline void add(int x,int y,int z,int c){
    nex[e]=beg[x];beg[x]=e;
    to[e]=y;w[e]=c;f[e]=z;e++;
}
int flow[maxn],dis[maxn],vis[maxn];
queue<int>q;
int las[maxn],pos[maxn];
inline int spfa(){
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    while(!q.empty())q.pop();
    dis[0]=0;
    flow[0]=inf;
    vis[0]=1;
    q.push(0);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        vis[x]=0;
        for(int i=beg[x];~i;i=nex[i]){
            int t=to[i];
            if(f[i]&&dis[t]>dis[x]+w[i]){
                dis[t]=dis[x]+w[i];
                las[t]=x;
                pos[t]=i;
                flow[t]=min(flow[x],f[i]);
                if(!vis[t]){
                    vis[t]=1;
                    q.push(t);
                }
            }
        }
    }
    return dis[2*n*n+1]<=1000000;
}
int main(){
    memset(beg,-1,sizeof(beg));
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>val[i][j];
    add(0,1,k,0);
    add(1,0,0,0);
    add(2*n*n,2*n*n+1,k,0);
    add(2*n*n+1,2*n*n,0,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            add((i-1)*n+j,(i-1)*n+j+n*n,1,-val[i][j]);
            add((i-1)*n+j+n*n,(i-1)*n+j,0,val[i][j]);
            add((i-1)*n+j,(i-1)*n+j+n*n,inf,0);
            add((i-1)*n+j+n*n,(i-1)*n+j,0,0);
            if(i<n){
                add((i-1)*n+j+n*n,i*n+j,inf,0);
                add(i*n+j,(i-1)*n+j+n*n,0,0);
            }
            if(j<n){
                add((i-1)*n+j+n*n,(i-1)*n+j+1,inf,0);
                add((i-1)*n+j+1,(i-1)*n+j+n*n,0,0);
            }
        }
    int ans=0;
    while(spfa()){
        ans-=flow[2*n*n+1]*dis[2*n*n+1];
        int tmp=2*n*n+1;
        while(tmp!=0){
            f[pos[tmp]]-=flow[2*n*n+1];
            f[pos[tmp]^1]+=flow[2*n*n+1];
            tmp=las[tmp];
        }
    }
    printf("%d\n",ans);
    return 0;
}

深深地感到自己的弱小。

 

标签:加强版,int,beg,取数,vis,add,maxn,方格,dis
来源: https://www.cnblogs.com/syzf2222/p/12431118.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有