• 上海大都会赛 I Matrix Game(最大流)


    At the start of the matrix game, we have an N x M matrix. Each grid has some balls.
    The grid in (i,j) (0 ≤ i < N, 0 ≤ j < M) has Aij balls.
    In each operation you can remove one ball from a grid or add one ball into a grid.
    The goal of this game is to make each of the rows has the same number of balls and each of the columns has the same number of balls.
    What is the minumun operations you should use?

    输入描述:
    The first line of the input is T(1≤ T ≤ 100), which stands for the number of test cases you need to solve.
    The first line of each test case contains two integers N and M (1 ≤ N,M ≤ 20).
    The next N lines describe Aij, each line contains M integers. (0 ≤ Aij ≤ 20).

    输出描述:
    For each test case, print the case number and the answer.

    输入
    2
    2 3
    4 8 5
    2 4 6
    3 3
    1 5 2
    3 5 4
    2 3 4

    输出
    Case 1: 7
    Case 2: 7

    说明
    for the first example, the number of balls after operations is
    4 6 5
    6 4 5

    题意

    给你一个N*M的矩阵,有两个操作,每次对1个数+1或-1,问最少操作多少次使得每行和相同,每列和相同

    题解

    设每行X,每列Y,可知X*N=Y*M,每一行X/N,每一列Y/M,并且lcm(N,M)|X,0<=X<=20*n*m

    然后可以枚举每一个X+=lcm(N,M),再用网络流判断

    建图按行列建,S-每行流量X/N,T-每行流量Y/M,行列按a[i][j]建

    跑出来最大流maxflow

    +1,说明图中总共需要增加x-maxflow

    -1,说明图中总共需要减掉多出来的sum-maxflow

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn=1e5+5;
     5 const int maxm=2e5+5;
     6 const int INF=0x3f3f3f3f;
     7 
     8 int TO[maxm],CAP[maxm],NEXT[maxm],tote;
     9 int FIR[maxn],gap[maxn],cur[maxn],d[maxn],q[400000];
    10 int n,m,S,T;
    11 
    12 void add(int u,int v,int cap)
    13 {
    14     TO[tote]=v;
    15     CAP[tote]=cap;
    16     NEXT[tote]=FIR[u];
    17     FIR[u]=tote++;
    18     
    19     TO[tote]=u;
    20     CAP[tote]=0;
    21     NEXT[tote]=FIR[v];
    22     FIR[v]=tote++;
    23 }
    24 void bfs()
    25 {
    26     memset(gap,0,sizeof gap);
    27     memset(d,0,sizeof d);
    28     ++gap[d[T]=1];
    29     for(int i=1;i<=n;++i)cur[i]=FIR[i];
    30     int head=1,tail=1;
    31     q[1]=T;
    32     while(head<=tail)
    33     {
    34         int u=q[head++];
    35         for(int v=FIR[u];v!=-1;v=NEXT[v])
    36             if(!d[TO[v]])
    37                 ++gap[d[TO[v]]=d[u]+1],q[++tail]=TO[v];
    38     }
    39 }
    40 int dfs(int u,int fl)
    41 {
    42     if(u==T)return fl;
    43     int flow=0;
    44     for(int &v=cur[u];v!=-1;v=NEXT[v])
    45         if(CAP[v]&&d[u]==d[TO[v]]+1)
    46         {
    47             int Min=dfs(TO[v],min(fl,CAP[v]));
    48             flow+=Min,fl-=Min,CAP[v]-=Min,CAP[v^1]+=Min;
    49             if(!fl)return flow;
    50         }
    51     if(!(--gap[d[u]]))d[S]=n+1;
    52     ++gap[++d[u]],cur[u]=FIR[u];
    53     return flow;
    54 }
    55 int ISAP()
    56 {
    57     bfs();
    58     int ret=0;
    59     while(d[S]<=n)ret+=dfs(S,INF);
    60     return ret;
    61 }
    62 void init()
    63 {
    64     tote=0;
    65     memset(FIR,-1,sizeof FIR);
    66 }
    67 int main()
    68 {
    69     int t,N,M,ca=1;
    70     int a[25][25];
    71     scanf("%d",&t);
    72     while(t--)
    73     {
    74         int sum=0;
    75         scanf("%d%d",&N,&M);
    76         for(int i=1;i<=N;i++)
    77             for(int j=1;j<=M;j++)
    78                 scanf("%d",&a[i][j]),sum+=a[i][j];
    79         int up=N/__gcd(N,M)*M;
    80         int minn=1e9;
    81         S=N+M+1,T=S+1,n=T;
    82         for(int x=0;x<=20*N*M;x+=up)
    83         {
    84             init();
    85             for(int i=1;i<=N;i++)add(S,i,x/N);
    86             for(int i=1;i<=M;i++)add(N+i,T,x/M);
    87             for(int i=1;i<=N;i++)
    88                 for(int j=1;j<=M;j++)
    89                     add(i,N+j,a[i][j]);
    90             minn=min(minn,x+sum-ISAP()*2);
    91         }
    92         printf("Case %d: %d
    ",ca++,minn);
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    TCP的三次握手和四次挥手理解及面试题
    linux网卡配置文件参数
    linux的常用指令和配置文件
    django中的modelform和modelfoemset
    django中的form表单验证
    php快速开发的学习经历
    一个微信支付商场的经历
    https的学习过程
    使用java访问elasticsearch创建索引
    写博客是为什么
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/9598645.html
Copyright © 2020-2023  润新知