zoukankan      html  css  js  c++  java
  • 【BZOJ3894】文理分科

    最小割劲啊

    原题:

     文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠
    结过)
     小P所在的班级要进行文理分科。他的班级可以用一个n*m的矩阵进行
    描述,每个格子代表一个同学的座位。每位同学必须从文科和理科中选择
    一科。同学们在选择科目的时候会获得一个满意值。满意值按如下的方式
    得到:
    1.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如
      果选择理科,将得到science[i][j]的满意值。
    2.如果第i行第J列的同学选择了文科,并且他相邻(两个格子相邻当且
      仅当它们拥有一条相同的边)的同学全部选择了文科,则他会更开
      心,所以会增加same_art[i][j]的满意值。
    3.如果第i行第j列的同学选择了理科,并且他相邻的同学全部选择了理
      科,则增加same_science[i]j[]的满意值。
      小P想知道,大家应该如何选择,才能使所有人的满意值之和最大。请
    告诉他这个最大值。
    N,M<=100,读入数据均<=500
     
    恩一眼秒掉,先转化成求最小得不到的收益
    s->i流量为选文收益,i->t为选理收益,额外点i'和i'',其中s->i'流量为i和周围全选文的收益,然后i'到i自己和周围共5个点连边,i''同理
    酱紫的话如果想要某点i和周围全选文,就要让s->i'这条边留下来,就必须割掉i自己和周围共5个点到汇的边,酱源到i自己和周围共5个点的边和s->i'就都留下来了,就表示大家一起选文的收益
    注意点i的两个辅助点都要和i自己连边,因为要求i和周围四个人共五个人选的都一样,然后边数也要更大,我因为这个re了一发没1A
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int oo=168430090;
     8 int rd(){int z=0,mk=1;  char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    11     return z*mk;
    12 }
    13 const int fx[5]={1,-1,0,0,0},fy[5]={0,0,1,-1,0};
    14 struct ddd{int nxt,y,v,rvs;}e[1041000];  int lk[31000],ltp=0;
    15 inline void ist(int x,int y,int z){
    16     e[++ltp].nxt=lk[x],lk[x]=ltp,e[ltp].y=y,e[ltp].v=z,e[ltp].rvs=ltp+1;
    17     e[++ltp].nxt=lk[y],lk[y]=ltp,e[ltp].y=x,e[ltp].v=0,e[ltp].rvs=ltp-1;
    18 }
    19 int n,m;  int N;  int s,t;
    20 int lvl[31000];
    21 int q[31000],hd=0;
    22 bool gtlvl(){
    23     memset(lvl,0,sizeof(lvl));
    24     q[hd=1]=s,lvl[s]=1;
    25     for(int k=1;k<=hd;++k)
    26         for(int i=lk[q[k]];i;i=e[i].nxt)if(e[i].v && !lvl[e[i].y])
    27             lvl[e[i].y]=lvl[q[k]]+1,q[++hd]=e[i].y;
    28     return lvl[t];
    29 }
    30 int mxflw(int x,int y){
    31     if(x==t)  return y;
    32     int bwl=0,flw=0;
    33     for(int i=lk[x];i && bwl<y;i=e[i].nxt)if(e[i].v && lvl[e[i].y]==lvl[x]+1)
    34         if((flw=mxflw(e[i].y,min(y-bwl,e[i].v)))){
    35             bwl+=flw;
    36             e[i].v-=flw,e[e[i].rvs].v+=flw;
    37         }
    38     if(!bwl)  lvl[x]=0;
    39     return bwl;
    40 }
    41 int dnc(){
    42     int bwl=0,flw=0;
    43     while(gtlvl())while(flw=mxflw(s,oo))  bwl+=flw;
    44     return bwl;
    45 }
    46 inline int gtid(int x,int y){  return (x-1)*m+y;}
    47 inline bool chck(int x,int y,int z){  
    48     return x+fx[z]>=1 && x+fx[z]<=n && y+fy[z]>=1 && y+fy[z]<=m;
    49 }
    50 int main(){//freopen("ddd.in","r",stdin);
    51     cin>>n>>m;  N=n*m;  s=0,t=3*N+1;
    52     int v,bwl=0;
    53     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
    54         ist(s,gtid(i,j),v=rd()),bwl+=v;
    55     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
    56         ist(gtid(i,j),t,v=rd()),bwl+=v;
    57     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
    58         ist(s,gtid(i,j)+N,v=rd()),bwl+=v;
    59     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
    60         ist(gtid(i,j)+N+N,t,v=rd()),bwl+=v;
    61     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
    62         for(int k=0;k<5;++k)if(chck(i,j,k)){
    63             ist(gtid(i,j)+N,gtid(i+fx[k],j+fy[k]),oo);
    64             ist(gtid(i+fx[k],j+fy[k]),gtid(i,j)+N+N,oo);
    65         }
    66     cout<<bwl-dnc()<<endl;
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    利用JavaScript制作网页中“选项卡”效果。 (二)
    Threading and UI
    我不太喜欢的一篇文章: [真爱无言]
    坚持,习惯,自然
    6行代码实现无组建上传(转)
    【转帖】20个你未必知道的CSS技巧
    CSS Filter 代替 图片 实现 渐变背景效果。
    Microsoft Excelに...
    ATM机的故事
    利用JavaScript制作网页中“选项卡”效果。 (三)——终极应用 JavaScript tabifier
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6541781.html
Copyright © 2011-2022 走看看