zoukankan      html  css  js  c++  java
  • BZOJ 3894 文理分科

    3894: 文理分科

    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
     

     
      DINIC模板题。很经典。又死在点、边数上,这个确实需要好好算一算。还有,if的判断……(本人是智障)
      
     1 /**************************************************************
     2     Problem: 3894
     3     User: Doggu
     4     Language: C++
     5     Result: Accepted
     6     Time:2380 ms
     7     Memory:19036 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12 #include <cstring>
    13 #include <queue>
    14 #define pos(x,y) ((x-1)*m+y)
    15 const int N = 200200;
    16 const int M = 1001001;
    17 const int dx[] = {0,1,-1,0,0};
    18 const int dy[] = {0,0,0,1,-1};
    19 struct Edge {int v,upre,cap,flow;}g[M];
    20 int head[N], ne = 0;
    21 inline void adde(int u,int v,int cap) {
    22     g[ne]=(Edge){v,head[u],cap,0};head[u]=ne++;
    23     g[ne]=(Edge){u,head[v],0,0};head[v]=ne++;
    24 }
    25 int n, m, s, t, x, sum, INF=0x3f3f3f3f;
    26 int d[N];
    27 bool vis[N];
    28 std::queue<int> q;
    29 bool BFS() {
    30     memset(vis, 0, sizeof(vis));
    31     while(!q.empty()) q.pop();
    32     d[s]=0;vis[s]=1;q.push(s);
    33     while(!q.empty()) {
    34         int u=q.front();q.pop();
    35         for( int i = head[u]; i != -1; i = g[i].upre ) {
    36             int v=g[i].v;
    37             if(!vis[v] && g[i].cap>g[i].flow) d[v]=d[u]+1,vis[v]=1,q.push(v);
    38         }
    39     }
    40     return vis[t];
    41 }
    42 int cur[N];
    43 int DFS(int u,int a) {
    44     if(u == t||a == 0) return a;
    45     int f, flow = 0;
    46     for( int& i = cur[u]; i != -1; i = g[i].upre ) {
    47         int v=g[i].v;
    48         if(d[v]==d[u]+1&&(f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) {
    49             g[i].flow+=f;g[i^1].flow-=f;a-=f;flow+=f;
    50             if(a==0) break;
    51         }
    52     }
    53     return flow;
    54 }
    55 void maxflow() {
    56     int flow = 0;
    57     while(BFS()) {
    58         memcpy(cur,head,sizeof(head));
    59         flow+=DFS(s,INF);
    60     }
    61     printf("%d
    ",sum-flow);
    62 }
    63 int main() {
    64     memset(head,-1,sizeof(head));
    65     scanf("%d%d",&n,&m);
    66     s=0;t=32999;
    67     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {
    68         scanf("%d",&x);sum+=x;adde(s,pos(i,j),x);
    69     }
    70     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {
    71         scanf("%d",&x);sum+=x;adde(pos(i,j),t,x);
    72     }
    73     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {
    74         scanf("%d",&x);sum+=x;adde(s,pos(n,m)+pos(i,j),x);
    75         for( int d = 0; d <= 4; d++ ) if(1<=i+dx[d]&&i+dx[d]<=n&&1<=j+dy[d]&&j+dy[d]<=m) adde(pos(n,m)+pos(i,j),pos(i+dx[d],j+dy[d]),INF);
    76     }
    77     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {
    78         scanf("%d",&x);sum+=x;adde(2*pos(n,m)+pos(i,j),t,x);
    79         for( int d = 0; d <= 4; d++ ) if(1<=i+dx[d]&&i+dx[d]<=n&&1<=j+dy[d]&&j+dy[d]<=m) adde(pos(i+dx[d],j+dy[d]),2*pos(n,m)+pos(i,j),INF);
    80     }
    81     maxflow();
    82     return 0;
    83 }
    84 
    DINIC
  • 相关阅读:
    Callable的Future模式
    并发队列
    并发工具类
    线程池
    并发编程专题
    侧边栏:内有友链,分类等等
    脑残错误记录
    博主的OI流水账
    NOI2019游记
    NOI数论姿势瞎总结(Pi也没有)
  • 原文地址:https://www.cnblogs.com/Doggu/p/bzoj3894.html
Copyright © 2011-2022 走看看