【BZOJ】【3894】文理分科
网络流/最小割
rausen大爷太神辣~作为一个蒟蒻还是搬运题解吧……
很明显的一道网络流题。。
首先把所有值的加起来,再减掉网络流最小割值就好了,问题就是如何建图。这貌似也是考了好多次了的。。。
把每个人抽象成一个点p,则
先是S向p连边,流量为选文科的高兴值,p向T连边,流量为选理科的高兴值。
然后是same的条件,对每个人新建两个点p1, p2
S向p1连边,流量为文科same的高兴值,p1向相邻点和自己的p连边,流量为inf
p2相T连边,流量为理科same的高兴值,相邻点和自己的p向p2连边,流量为inf
然后跑一下网络流就好了(蒟蒻tot = 1没写调了半天还以为建图错了= =b)
1 /************************************************************** 2 Problem: 3894 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:2404 ms 7 Memory:40340 kb 8 ****************************************************************/ 9 10 //BZOJ 3894 11 #include<vector> 12 #include<cstdio> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 #define pb push_back 21 using namespace std; 22 inline int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 25 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 26 return v*sign; 27 } 28 const int N=1e6+10,M=2000010,INF=~0u>>2; 29 typedef long long LL; 30 /******************tamplate*********************/ 31 const int fx[]={0,1,0,-1,0}, 32 fy[]={1,0,-1,0,0}; 33 int n,m,tot,ans; 34 struct edge{int to,v;}; 35 inline int pack(int i,int j){return (i-1)*m+j;} 36 #define FOR F(i,1,n)F(j,1,m) 37 struct Net{ 38 edge E[M]; 39 int head[N],next[M],cnt; 40 void ins(int x,int y,int v){ 41 E[++cnt]=(edge){y,v}; 42 next[cnt]=head[x]; head[x]=cnt; 43 } 44 void add(int x,int y,int v){ 45 ins(x,y,v); ins(y,x,0); 46 } 47 int s,t,cur[N],d[N],Q[N]; 48 bool mklevel(){ 49 memset(d,-1,sizeof d); 50 d[s]=0; 51 int l=0,r=-1; 52 Q[++r]=s; 53 while(l<=r){ 54 int x=Q[l++]; 55 for(int i=head[x];i;i=next[i]) 56 if (d[E[i].to]==-1 && E[i].v){ 57 d[E[i].to]=d[x]+1; 58 Q[++r]=E[i].to; 59 } 60 } 61 return d[t]!=-1; 62 } 63 int dfs(int x,int a){ 64 if (x==t) return a; 65 int flow=0; 66 for(int i=head[x];i && flow<a;i=next[i]) 67 if (E[i].v && d[E[i].to]==d[x]+1){ 68 int f=dfs(E[i].to,min(a-flow,E[i].v)); 69 E[i].v-=f; 70 E[i^1].v+=f; 71 flow+=f; 72 } 73 if (!flow) d[x]=-1; 74 return flow; 75 } 76 void Dinic(){ 77 while(mklevel()) ans-=dfs(s,INF); 78 } 79 void init(){ 80 n=getint(); m=getint(); cnt=1; 81 tot=n*m; s=0; t=tot*3+1; 82 int x=0; 83 FOR{ 84 x=getint(); ans+=x; 85 add(s,pack(i,j),x); 86 } 87 FOR{ 88 x=getint(); ans+=x; 89 add(pack(i,j),t,x); 90 } 91 FOR{ 92 x=getint(); ans+=x; 93 add(s,tot+pack(i,j),x); 94 F(k,0,4){ 95 int tx=i+fx[k],ty=j+fy[k]; 96 if(tx<1||ty<1||tx>n||ty>m)continue; 97 add(tot+pack(i,j),pack(tx,ty),INF); 98 } 99 } 100 FOR{ 101 x=getint(); ans+=x; 102 add(tot*2+pack(i,j),t,x); 103 F(k,0,4){ 104 int tx=i+fx[k],ty=j+fy[k]; 105 if(tx<1||ty<1||tx>n||ty>m)continue; 106 add(pack(tx,ty),tot*2+pack(i,j),INF); 107 } 108 } 109 Dinic(); 110 printf("%d\n",ans); 111 } 112 }G1; 113 114 int main(){ 115 #ifndef ONLINE_JUDGE 116 freopen("3894.in","r",stdin); 117 freopen("3894.out","w",stdout); 118 #endif 119 G1.init(); 120 return 0; 121 }