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

    3894: 文理分科

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 1076  Solved: 630
    [Submit][Status][Discuss]

    Description

     文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠
    结过)
     小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想知道,大家应该如何选择,才能使所有人的满意值之和最大。请
    告诉他这个最大值。
     

    Input

     
    第一行为两个正整数:n,m
    接下来n术m个整数,表示art[i][j];
    接下来n术m个整数.表示science[i][j];
    接下来n术m个整数,表示same_art[i][j];
     

    Output

     
    输出为一个整数,表示最大的满意值之和
     

    Sample Input

    3 4
    13 2 4 13
    7 13 8 12
    18 17 0 5

    8 13 15 4
    11 3 8 11
    11 18 6 5

    1 2 3 4
    4 2 3 2
    3 1 0 4

    3 2 3 2
    0 2 2 1
    0 2 4 4

    Sample Output

    152

    HINT

    样例说明

    1表示选择文科,0表示选择理科,方案如下:

    1  0  0  1

    0  1  0  0

    1  0  0  0

     

    N,M<=100,读入数据均<=500

    思路{

      首先应当想到这是一道最小割的题。

      如何连边呢?我们想,

      无论怎么样即使连一条Inf的边它也不会是最小割(因为有其他边的限制);

      要保证最小割能分成两个点集,且保证决策的合理性,还要考虑周围的人的影响。

      所以我们不难想到{

         设源点S所在的点集为文科,汇点T所在点集为理科.

         那么连S到点i的容量为文科费用,i到T的容量为理科费用。

         好的,接下来是最重要的一部分。

         一个点和周围4个点有共同贡献,所以考虑新建一个点;

         与这5个点连Inf的边,贡献的话,

         由于是割,最后的答案为总权值减最小割,那么

         文科贡献连S∈割集就对应当前这些点不属于文科,理科同理。

         否则的话连出来无意义。。。。

      }还是比较水的,还有一道一毛一样的题BZOJ2127happiness

      网络流好久没敲了,调了好久。。。。。。。。

    }

    #include<bits/stdc++.h>
    #define N 101*101
    #define Inf (1<<20)
    #define pos(i,j) ((i-1)*m+j)
    using namespace std;
    struct ed{int nxt,to,c;}e[N*100];
    int head[N*10],tot,deep[N*10],n,m;
    
    void add(int u,int v,int c){e[tot].nxt=head[u];e[tot].to=v;e[tot].c=c;head[u]=tot++;}
    void ADD(int u,int v,int c){add(u,v,c),add(v,u,0);}
    
    bool BFS(int s,int t){queue<int>que;while(!que.empty())que.pop();
      memset(deep,0,sizeof(deep));deep[s]=1;
      que.push(s);while(!que.empty()){
        int u=que.front();que.pop();
        for(int i=head[u];i!=-1;i=e[i].nxt)if(e[i].c&&(!deep[e[i].to])){
    	int v=e[i].to;deep[v]=deep[u]+1;
    	que.push(v);
    	if(v==t)return true;
          }
      }return false;
    }
    int dinic(int s,int t,int T){
      if(s==t)return T;int tag(0);
      for(int i=head[s];i!=-1;i=e[i].nxt)if(deep[e[i].to]==deep[s]+1&&e[i].c){
          int v=e[i].to;int d=dinic(v,t,min(T-tag,e[i].c));
          e[i].c-=d,e[i^1].c+=d;tag+=d;
          if(tag==T)break;
        }if(!tag)deep[s]=0;return tag;
    }
    int maxflow(int s,int t){int flow=0;
      while(BFS(s,t))flow+=dinic(s,t,Inf);
      return flow;
    }
    int main(){
      freopen("1.in","r",stdin);
      //freopen("1.out","w",stdout);
      memset(head,-1,sizeof(head));
      int f,Ans(0);scanf("%d%d",&n,&m);
      for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
          scanf("%d",&f),ADD(0,pos(i,j),f),Ans+=f;
      for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
          scanf("%d",&f),ADD(pos(i,j),n*m+1,f),Ans+=f;
      int cnt=n*m+1;
      for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
          scanf("%d",&f);cnt++;
          if(i!=1)ADD(cnt,pos(i-1,j),Inf);
          if(i!=n)ADD(cnt,pos(i+1,j),Inf);
          if(j!=1)ADD(cnt,pos(i,j-1),Inf);
          if(j!=m)ADD(cnt,pos(i,j+1),Inf);
          ADD(cnt,pos(i,j),Inf);
          ADD(0,cnt,f),Ans+=f;
        }
      for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
          scanf("%d",&f);cnt++;
          if(i!=1)ADD(pos(i-1,j),cnt,Inf);
          if(i!=n)ADD(pos(i+1,j),cnt,Inf);
          if(j!=1)ADD(pos(i,j-1),cnt,Inf);
          if(j!=m)ADD(pos(i,j+1),cnt,Inf);
          ADD(pos(i,j),cnt,Inf);
          ADD(cnt,n*m+1,f),Ans+=f;
        }
      cout<<Ans-maxflow(0,n*m+1)<<"
    ";
      return 0;
    }
    

      

  • 相关阅读:
    单例模式
    抽象类的作用和应用场景
    java内部类的作用
    java多线程
    IO流--与properties集合配合使用
    IO流--序列化流与反序列化流
    8 个必备的PHP功能开发
    CSS3 box-shadow:
    移动平台的meta标签-----神奇的功效
    Android Screen Monitor抓取真机屏幕
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7212452.html
Copyright © 2011-2022 走看看