BZOJ 2127 happiness

http://www.lydsy.com/JudgeOnline/problem.php?id=2127

对于每个人都记一个点,

S->A 理[i][j]+理cost[A][B]/2 A->T 理[i][j]+理cost[A][B]/2

S->A 文[i][j]+文cost[A][B]/2 A->T 文[i][j]+文cost[A][B]/2

A<->B 理cost[i][j]/2+文cost[i][j]/2

  1 #include<algorithm>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<iostream>
  6 #define inf 0x7fffffff
  7 int w[105][105][2],flow[200005],next[200005],first[200005],nodes,T,S;
  8 int go[200005],op[200005],dis[200005],cnt[200005],tot,m,n,id[105][105];
  9 int read(){
 10     int t=0,f=1;char ch=getchar();
 11     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 12     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
 13     return t*f;
 14 }
 15 void insert(int x,int y,int z){
 16     tot++;
 17     go[tot]=y;
 18     next[tot]=first[x];
 19     first[x]=tot;
 20     flow[tot]=z;
 21 }
 22 void add(int x,int y,int z){
 23     insert(x,y,z);op[tot]=tot+1;
 24     insert(y,x,0);op[tot]=tot-1;
 25 }
 26 void add2(int x,int y,int z){
 27     insert(x,y,z);op[tot]=tot+1;
 28     insert(y,x,z);op[tot]=tot-1;
 29 }
 30 int dfs(int x,int f){
 31     if (x==T) return f;
 32     int mn=nodes,sum=0;
 33     for (int i=first[x];i;i=next[i]){
 34         int pur=go[i];
 35         if (flow[i]&&dis[pur]+1==dis[x]){
 36             int save=dfs(pur,std::min(f-sum,flow[i]));
 37             sum+=save;
 38             flow[i]-=save;
 39             flow[op[i]]+=save;
 40             if (sum==f||dis[S]>=nodes) return sum;
 41         }
 42         if (flow[i]) mn=std::min(mn,dis[pur]);
 43     }
 44     if (sum==0){
 45         cnt[dis[x]]--;
 46         if (cnt[dis[x]]==0){
 47             dis[S]=nodes;
 48         }else{
 49             dis[x]=mn+1;
 50             cnt[dis[x]]++;
 51         }
 52     }
 53     return sum;
 54 }
 55 int main(){
 56     n=read();m=read();
 57     S=0;
 58     T=n*m+1;
 59     nodes=T+1;
 60     int sz=0,ans=0;
 61     for (int i=1;i<=n;i++)
 62      for (int j=1;j<=m;j++)
 63        id[i][j]=++sz;
 64     for (int i=1;i<=n;i++)
 65      for (int j=1;j<=m;j++)
 66       w[i][j][0]=read(),ans+=w[i][j][0],w[i][j][0]*=2;
 67     for (int i=1;i<=n;i++)
 68      for (int j=1;j<=m;j++)
 69       w[i][j][1]=read(),ans+=w[i][j][1],w[i][j][1]*=2;
 70     for (int i=1;i<=n-1;i++)
 71      for (int j=1;j<=m;j++){
 72         int x=read();ans+=x;
 73         w[i][j][0]+=x;w[i+1][j][0]+=x;
 74         add2(id[i][j],id[i+1][j],x);
 75      }
 76     for (int i=1;i<=n-1;i++)
 77      for (int j=1;j<=m;j++){
 78         int x=read();ans+=x;
 79         w[i][j][1]+=x;w[i+1][j][1]+=x;
 80         add2(id[i][j],id[i+1][j],x);    
 81     } 
 82     for (int i=1;i<=n;i++)
 83      for (int j=1;j<=m-1;j++){
 84         int x=read();ans+=x;
 85         w[i][j][0]+=x;w[i][j+1][0]+=x;
 86         add2(id[i][j],id[i][j+1],x);
 87      } 
 88     for (int i=1;i<=n;i++)
 89      for (int j=1;j<=m-1;j++){
 90         int x=read();ans+=x;
 91         w[i][j][1]+=x;w[i][j+1][1]+=x;
 92         add2(id[i][j],id[i][j+1],x);
 93     }
 94     for (int i=1;i<=n;i++)
 95      for (int j=1;j<=m;j++)
 96       add(S,id[i][j],w[i][j][0]),add(id[i][j],T,w[i][j][1]);  
 97     int Mnflow=0;
 98     while (dis[S]<nodes) Mnflow+=dfs(S,inf);
 99     printf("%d\n",ans-Mnflow/2);
100 }

 

posted @ 2016-06-13 17:07  GFY  阅读(139)  评论(0编辑  收藏  举报