zoukankan      html  css  js  c++  java
  • [bzoj3894]文理分科

    假设没有同时选文理科的收益,可以先将所有点的文理科收益都加起来,考虑最少要删掉多少收益,源点连向每一个点文科的收益,每一个点向汇点流理科的收益,然后每一条路径都最小割,即去掉了较小的收益。

    但还有同时选同一种科目的收益,同样先加上所有选同种科目的收益,然后对于点(i,j),新增k1k2两个点,源点向k1流都选文科的边,k1向五个点、五个点向k2都连inf的边,k2向汇点流都选理科的边。同样跑最小割,考虑当这五个点全部都删去文理科,那么只需要再删掉这个点的都选文理科即可,当这个五个点选择删去的不同时,一定要两个都删掉才能满足,因此就是最小割。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 30005
     4 #define id (i-1)*m+j
     5 #define inf 0x3f3f3f3f
     6 struct ji{
     7     int nex,to,len;
     8 }edge[N*10];
     9 queue<int>q;
    10 int E,n,m,k,ans,d[N],head[N],work[N];
    11 void add(int x,int y,int z){
    12     edge[E].nex=head[x];
    13     edge[E].to=y;
    14     edge[E].len=z;
    15     head[x]=E++;
    16     if (E&1)add(y,x,0);
    17 }
    18 bool bfs(){
    19     q.push(0);
    20     memset(d,-1,sizeof(d));
    21     d[0]=0;
    22     while (!q.empty()){
    23         int k=q.front();
    24         q.pop();
    25         for(int i=head[k];i!=-1;i=edge[i].nex)
    26             if ((edge[i].len)&&(d[edge[i].to]<0)){
    27                 d[edge[i].to]=d[k]+1;
    28                 q.push(edge[i].to);
    29             }
    30     }
    31     return d[n]>=0;
    32 }
    33 int dfs(int k,int s){
    34     if (k==n)return s;
    35     int p;
    36     for(int &i=work[k];i!=-1;i=edge[i].nex)
    37         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
    38             p=dfs(edge[i].to,min(s,edge[i].len));
    39             if (p){
    40                 edge[i].len-=p;
    41                 edge[i^1].len+=p;
    42                 return p;
    43             }
    44         }
    45     return 0;
    46 }
    47 int dinic(){
    48     int k,ans=0;
    49     while (bfs()){
    50         memcpy(work,head,sizeof(work));
    51         while (k=dfs(0,inf))ans+=k;
    52     }
    53     return ans;
    54 }
    55 int main(){
    56     scanf("%d%d",&n,&m);
    57     memset(head,-1,sizeof(head));
    58     for(int i=1;i<=n;i++)
    59         for(int j=1;j<=m;j++){
    60             scanf("%d",&k);
    61             add(0,id,k);
    62             ans+=k;
    63         }
    64     for(int i=1;i<=n;i++)
    65         for(int j=1;j<=m;j++){
    66             scanf("%d",&k);
    67             add(id,3*n*m+1,k);
    68             ans+=k;
    69         }
    70     for(int i=1;i<=n;i++)
    71         for(int j=1;j<=m;j++){
    72             scanf("%d",&k);
    73             add(0,n*m+id,k);
    74             add(n*m+id,id,inf);
    75             if (j>1)add(n*m+id,id-1,inf);
    76             if (j<m)add(n*m+id,id+1,inf);
    77             if (i>1)add(n*m+id,id-m,inf);
    78             if (i<n)add(n*m+id,id+m,inf);
    79             ans+=k;
    80         }
    81     for(int i=1;i<=n;i++)
    82         for(int j=1;j<=m;j++){
    83             scanf("%d",&k);
    84             add(2*n*m+id,3*n*m+1,k);
    85             add(id,2*n*m+id,inf);
    86             if (j>1)add(id-1,2*n*m+id,inf);
    87             if (j<m)add(id+1,2*n*m+id,inf);
    88             if (i>1)add(id-m,2*n*m+id,inf);
    89             if (i<n)add(id+m,2*n*m+id,inf);
    90             ans+=k;
    91         }
    92     n=3*n*m+1;
    93     printf("%d",ans-dinic());
    94 }
    View Code
  • 相关阅读:
    机械键盘与选购技巧
    计算机科学与技术专业的知识架构
    加法器
    计算机底层逻辑电路
    小数在计算机的表示
    整数在计算机里的表示
    Core ML 机器学习
    MapFileParser.sh: Permission denied
    iOS开发创建UI的耗时操作处理
    iOS application/json上传文件等
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249878.html
Copyright © 2011-2022 走看看