bzoj2127: happiness(双倍经验最小割)
2127: happiness
题目:传送门
题解:
双倍经验美滋滋~
请看蒟蒻以前写的渣题解...bzoj3894
表示做完自己就最小割了...
代码(直接改的...菜啊):
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #define inf 999999999 7 #define qread(x)x=read(); 8 using namespace std; 9 inline int read() 10 { 11 int f=1,x=0;char ch; 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return f*x; 15 } 16 const int dx[5]={0,-1,1,0,0}; 17 const int dy[5]={0,0,0,-1,1}; 18 struct node 19 { 20 int x,y,c,next,other; 21 }a[2100000];int len,last[1100000]; 22 int n,m,st,ed,head,tail; 23 void ins(int x,int y,int c) 24 { 25 int k1,k2; 26 k1=++len; 27 a[len].x=x;a[len].y=y;a[len].c=c; 28 a[len].next=last[x];last[x]=len; 29 30 k2=++len; 31 a[len].x=y;a[len].y=x;a[len].c=0; 32 a[len].next=last[y];last[y]=len; 33 34 a[k1].other=k2; 35 a[k2].other=k1; 36 } 37 int list[1100000],h[1100000]; 38 bool bt_h() 39 { 40 memset(h,0,sizeof(h));h[st]=1; 41 list[1]=st;head=1;tail=2; 42 while(head!=tail) 43 { 44 int x=list[head]; 45 for(int k=last[x];k;k=a[k].next) 46 { 47 int y=a[k].y; 48 if(h[y]==0 && a[k].c>0) 49 { 50 h[y]=h[x]+1; 51 list[tail++]=y; 52 } 53 } 54 head++; 55 } 56 if(h[ed]>0)return true; 57 return false; 58 } 59 int find_flow(int x,int flow) 60 { 61 if(x==ed)return flow; 62 int s=0,t; 63 for(int k=last[x];k;k=a[k].next) 64 { 65 int y=a[k].y; 66 if(h[y]==h[x]+1 && a[k].c>0 && s<flow) 67 { 68 s+=t=find_flow(y,min(a[k].c,flow-s)); 69 a[k].c-=t;a[a[k].other].c+=t; 70 } 71 } 72 if(s==0)h[x]=0; 73 return s; 74 } 75 int w[110][110],l[110][110],sw1[110][110],sl1[110][110],sw2[110][110],sl2[110][110]; 76 int d[110][110]; 77 int main() 78 { 79 qread(n);qread(m); 80 st=n*m*5+1;ed=st+1; 81 len=0;memset(last,0,sizeof(last)); 82 int ss=1; 83 for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)d[i][j]=ss++; 84 int sum=0; 85 for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){qread(w[i][j]);ins(st,d[i][j],w[i][j]);sum+=w[i][j];} 86 for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){qread(l[i][j]);ins(d[i][j],ed,l[i][j]);sum+=l[i][j];} 87 for(int i=1;i<n;i++) 88 for(int j=1;j<=m;j++) 89 { 90 qread(sw1[i][j]); 91 if(d[i][j]>0) 92 ins(d[i][j]+n*m,d[i][j],inf); 93 if(d[i+1][j]>0) 94 ins(d[i][j]+n*m,d[i+1][j],inf); 95 ins(st,d[i][j]+n*m,sw1[i][j]); 96 sum+=sw1[i][j]; 97 } 98 for(int i=1;i<n;i++) 99 for(int j=1;j<=m;j++) 100 { 101 qread(sl1[i][j]); 102 if(d[i][j]>0) 103 ins(d[i][j],d[i][j]+n*m*2,inf); 104 if(d[i+1][j]>0) 105 ins(d[i+1][j],d[i][j]+n*m*2,inf); 106 ins(d[i][j]+n*m*2,ed,sl1[i][j]); 107 sum+=sl1[i][j]; 108 } 109 for(int i=1;i<=n;i++) 110 for(int j=1;j<m;j++) 111 { 112 qread(sw2[i][j]); 113 if(d[i][j]>0) 114 ins(d[i][j]+n*m*3,d[i][j],inf); 115 if(d[i][j+1]>0) 116 ins(d[i][j]+n*m*3,d[i][j+1],inf); 117 ins(st,d[i][j]+n*m*3,sw2[i][j]); 118 sum+=sw2[i][j]; 119 } 120 for(int i=1;i<=n;i++) 121 for(int j=1;j<m;j++) 122 { 123 qread(sl2[i][j]); 124 if(d[i][j]>0) 125 ins(d[i][j],d[i][j]+n*m*4,inf); 126 if(d[i][j+1]>0) 127 ins(d[i][j+1],d[i][j]+n*m*4,inf); 128 ins(d[i][j]+n*m*4,ed,sl2[i][j]); 129 sum+=sl2[i][j]; 130 } 131 int ans=0; 132 while(bt_h())ans+=find_flow(st,inf); 133 printf("%d\n",sum-ans); 134 return 0; 135 }