[bzoj2127]happiness

[bzoj3894]文理分科,只是将五个点一组改为2个点一组(另外还可以通过解方程优化建边,但这里不需要)。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 60005
  4 #define id (i-1)*m+j
  5 #define inf 0x3f3f3f3f
  6 struct ji{
  7     int nex,to,len;
  8 }edge[N*7];
  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,5*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             add(n*m+id,id+m,inf);
 76             ans+=k;
 77         }
 78     for(int i=1;i<n;i++)
 79         for(int j=1;j<=m;j++){
 80             scanf("%d",&k);
 81             add(2*n*m+id,5*n*m+1,k);
 82             add(id,2*n*m+id,inf);
 83             add(id+m,2*n*m+id,inf);
 84             ans+=k;
 85         }
 86     for(int i=1;i<=n;i++)
 87         for(int j=1;j<m;j++){
 88             scanf("%d",&k);
 89             add(0,3*n*m+id,k);
 90             add(3*n*m+id,id,inf);
 91             add(3*n*m+id,id+1,inf);
 92             ans+=k;
 93         }
 94     for(int i=1;i<=n;i++)
 95         for(int j=1;j<m;j++){
 96             scanf("%d",&k);
 97             add(4*n*m+id,5*n*m+1,k);
 98             add(id,4*n*m+id,inf);
 99             add(id+1,4*n*m+id,inf);
100             ans+=k;
101         }
102     n=5*n*m+1;
103     printf("%d",ans-dinic());
104 }
View Code

 

posted @ 2019-07-28 10:41  PYWBKTDA  阅读(92)  评论(0编辑  收藏  举报