zoukankan      html  css  js  c++  java
  • A1261. happiness(吴确)[二元组暴力最小割建模]

    A1261. happiness(吴确)
    时间限制:500ms   内存限制:512.0MB  
    总提交次数:158   AC次数:72   平均分:56.71
     
    将本题分享到:
          
       
    试题来源
      2011中国国家集训队命题答辩
    问题描述
      高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。
    输入格式
      第一行两个正整数n,m。
      接下来是六个矩阵
      第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。
      第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。
      第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。
      第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。
      第五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。
      第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。
    输出格式
      输出一个整数,表示喜悦值总和的最大值
    样例输入
    1 2
    1 1
    100 110
    1
    1000
    样例输出
    1210
    样例说明
      两人都选理,则获得100+110+1000的喜悦值。
    数据规模和约定
      对于10%以内的数据,n,m<=4
      对于30%以内的数据,n,m<=8
      对于100%以内的数据,n,m<=100 数据保证答案在2^30以内
      对于100%的数据,时间限制为0.5s。

    源代码

    1. #include<cstdio>
    2. #include<cstring>
    3. #include<iostream>
    4. #define EF if(ch==EOF) return x;
    5. #define rep for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    6. #define rep1 for(int i=1;i<n;i++)for(int j=1;j<=m;j++)
    7. #define rep2 for(int i=1;i<=n;i++)for(int j=1;j<m;j++)
    8. using namespace std;
    9. const int Z=105;
    10. const int N=Z*Z;
    11. const int M=N*30;
    12. struct edge{int v,next,cap;}e[M<<1];int tot=1,head[N];
    13. int n,m,cnt,res,ans,S,T,dis[N],q[N+M];
    14. int a[Z][Z],b[Z][Z],id[Z][Z];
    15. inline int read(){
    16.     int x=0,f=1;char ch=getchar();
    17.     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;EF;ch=getchar();}
    18.     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    19.     return x*f;
    20. }
    21. void add(int x,int y,int z){
    22.     e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
    23.     e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot;
    24. }
    25. void Add(int x,int y,int z){
    26.     e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
    27.     e[++tot].v=x;e[tot].cap=z;e[tot].next=head[y];head[y]=tot;
    28. }
    29. bool bfs(){
    30.     memset(dis,-1,sizeof dis);
    31.     int h=0,t=1;q[t]=S;dis[S]=0;
    32.     while(h!=t){
    33.         int x=q[++h];
    34.         for(int i=head[x];i;i=e[i].next){
    35.             if(e[i].cap&&dis[e[i].v]==-1){
    36.                 dis[e[i].v]=dis[x]+1;
    37.                 if(e[i].v==T) return 1;
    38.                 q[++t]=e[i].v;
    39.             }
    40.         } 
    41.     }
    42.     return 0;
    43. }
    44. int dfs(int x,int f){
    45.     if(x==T) return f;
    46.     int used=0,t;
    47.     for(int i=head[x];i;i=e[i].next){
    48.         if(e[i].cap&&dis[e[i].v]==dis[x]+1){
    49.             t=dfs(e[i].v,min(e[i].cap,f));
    50.             e[i].cap-=t;e[i^1].cap+=t;
    51.             used+=t;f-=t;
    52.             if(!f) return used;
    53.         }
    54.     }
    55.     if(!used) dis[x]=-1;
    56.     return used;
    57. }
    58. void dinic(){
    59.     res=0;
    60.     while(bfs()) res+=dfs(S,2e9);
    61. }
    62. int main(){
    63.     n=read();m=read();
    64.     rep a[i][j]=read();
    65.     rep b[i][j]=read();
    66.     rep id[i][j]=++cnt;
    67.     S=0;T=cnt+1;
    68.     #define u id[i][j]
    69.     #define v id[i+1][j]
    70.     rep{
    71.         add(S,u,b[i][j]<<1);
    72.         add(u,T,a[i][j]<<1);
    73.         ans+=a[i][j]+b[i][j];
    74.     }
    75.     rep1 a[i][j]=read();
    76.     rep1 b[i][j]=read();
    77.     rep1{
    78.         add(S,u,b[i][j]);add(S,v,b[i][j]);
    79.         add(u,T,a[i][j]);add(v,T,a[i][j]);
    80.         Add(u,v,a[i][j]+b[i][j]);
    81.         ans+=a[i][j]+b[i][j];
    82.     }
    83.     #undef v
    84.     #define v id[i][j+1]
    85.     rep2 a[i][j]=read();
    86.     rep2 b[i][j]=read();
    87.     rep2{
    88.         add(S,u,b[i][j]);add(S,v,b[i][j]);
    89.         add(u,T,a[i][j]);add(v,T,a[i][j]);
    90.         Add(u,v,a[i][j]+b[i][j]);
    91.         ans+=a[i][j]+b[i][j];
    92.     }
    93.     dinic();
    94.     res>>=1;
    95.     printf("%d",ans-res);
    96.     return 0;
    97. }
  • 相关阅读:
    [原创]Acronis True Image使用手记
    毕业日志
    我的L6修好了
    三峡实习记之二
    初到华南理工印象
    三峡实习记之三
    SHOW毕业衫
    自己的第一次装机
    iOS Tools
    [转] A few things iOS developers ought to know about the ARM architecture
  • 原文地址:https://www.cnblogs.com/shenben/p/6606447.html
Copyright © 2011-2022 走看看