zoukankan      html  css  js  c++  java
  • 【网络流24题】方格取数问题

    Description

    在一个有m * n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。对于给定的方格棋盘,按照取数要求编程找出总和最大的数。

    Input

    第1 行有2 个正整数m和n,分别表示棋盘的行数和列数。
    接下来的m行,每行有n个正整数,表示棋盘方格中的数。

    Output

    将取数的最大总和输出

    Sample Input

    3 3
    1 2 3
    3 2 3
    2 3 1

    Sample Output

    11

    Hint

    数据范围:
    1<=N,M<=30

    正解:二分图最大独立集。

    一个二分图的最大独立集等于点权和-最小割。

    然后这题点权不为1,所以不能用匈牙利算法,只能用最大流。

    //It is made by wfj_2048~
    #include <algorithm>
    #include <iostream>
    #include <complex>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #define inf (1<<30)
    #define il inline
    #define RG register
    #define ll long long
    #define c(i,j) ( (i-1)*m+j )
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    
    using namespace std;
    
    struct edge{ int nt,to,flow,cap; }g[200010];
    
    int head[20010],vis[20010],d[20010],q[20010],G[110][110],a[110][110],n,m,S,T,tot,num=1;
    
    il int gi(){
        RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
        if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
    }
    
    il void insert(RG int from,RG int to,RG int cap){ g[++num]=(edge){head[from],to,0,cap},head[from]=num; return; }
    
    il int bfs(RG int S,RG int T){
        memset(vis,0,sizeof(vis));
        RG int h=0,t=1; q[t]=S,d[S]=0,vis[S]=1;
        while (h<t){
        RG int x=q[++h],v;
        for (RG int i=head[x];i;i=g[i].nt){
            v=g[i].to;
            if (!vis[v] && g[i].cap>g[i].flow)
            vis[v]=1,q[++t]=v,d[v]=d[x]+1;
        }
        }
        return vis[T];
    }
    
    il int dfs(RG int x,RG int T,RG int a){
        if (x==T || a==0) return a;
        RG int flow=0,f,v;
        for (RG int i=head[x];i;i=g[i].nt){
        v=g[i].to;
        if (d[v]==d[x]+1 && g[i].cap>g[i].flow){
            f=dfs(v,T,min(a,g[i].cap-g[i].flow));
            if (!f){ d[v]=-1; continue; }
            g[i].flow+=f,g[i^1].flow-=f;
            flow+=f,a-=f; if (a==0) return flow;
        }
        }
        return flow;
    }
    
    il int maxflow(RG int S,RG int T){ RG int flow=0; while (bfs(S,T)) flow+=dfs(S,T,inf); return flow; }
    
    il void work(){
        n=gi(),m=gi(); S=n*m+1,T=n*m+2;
        for (RG int i=1;i<=n;++i)
        for (RG int j=1;j<=m;++j){
            G[i][j]=gi(),tot+=G[i][j];
            if (a[i-1][j] || a[i][j-1]){
            insert(S,c(i,j),G[i][j]),insert(c(i,j),S,0);
            if (i-1>0) insert(c(i,j),c(i-1,j),inf),insert(c(i-1,j),c(i,j),0);
            if (j-1>0) insert(c(i,j),c(i,j-1),inf),insert(c(i,j-1),c(i,j),0);
            if (i+1<=n) insert(c(i,j),c(i+1,j),inf),insert(c(i+1,j),c(i,j),0);
            if (j+1<=m) insert(c(i,j),c(i,j+1),inf),insert(c(i,j+1),c(i,j),0);
            } else a[i][j]=1,insert(c(i,j),T,G[i][j]),insert(T,c(i,j),0);
        }
        printf("%d
    ",tot-maxflow(S,T)); return;
    }
    
    int main(){
        File("number");
        work();
        return 0;
    }
  • 相关阅读:
    Powershell数据处理
    Powershell About Active Directory Group Membership of a domain user
    Powershell About Active Directory Server
    Oracle Schema Objects——Tables——TableStorage
    Oracle Schema Objects——Tables——TableType
    English Grammar
    Oracle Database Documentation
    Oracle Schema Objects——Tables——Oracle Data Types
    Oracle Schema Objects——Tables——Overview of Tables
    What is Grammar?
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6429000.html
Copyright © 2011-2022 走看看