• 方格取数加强版


    努力刷网络流找感觉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
    ",ans);
        return 0;
    }

    深深地感到自己的弱小。

  • 相关阅读:
    深入理解Linux修改hostname
    Linux开发环境必备十大开发工具
    管理员必备的几个Linux系统监控工具
    Solaris&&QNX® Neutrino®&&OpenVMS&&FreeBSD&&AIX
    ansible来了
    Cobbler系统安装备用链接
    Web安全
    在Eclipse/STS中使用EclEmma进行覆盖率检查
    C#中使用扩展方法
    Winform中Textbox的使用
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12431118.html
Copyright © 2020-2023  润新知