标签:
Orz Hzwer
这类大概是最小割建模中的经典应用吧……
黑白染色,然后反转黑色的技巧感觉很巧妙!这个转化太神奇了……
1 /************************************************************** 2 Problem: 2132 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:0 ms 7 Memory:6252 kb 8 ****************************************************************/ 9 10 //BZOJ 2132 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 FOR for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) 21 #define pb push_back 22 using namespace std; 23 inline int getint(){ 24 int v=0,sign=1; char ch=getchar(); 25 while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();} 26 while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();} 27 return v*sign; 28 } 29 const int N=10010,M=300000,INF=~0u>>2; 30 const int fx[]={1,0,-1,0}, 31 fy[]={0,1,0,-1}; 32 typedef long long LL; 33 /******************tamplate*********************/ 34 int n,m,a[101][101],b[101][101],c[101][101],color[101][101],tot,ans; 35 struct edge{ 36 int from,to,v; 37 }; 38 inline int pack(int i,int j){ return (i-1)*m+j; } 39 struct Net{ 40 edge E[M]; 41 int head[N],next[M],cnt; 42 bool vis[110][110]; 43 void ins(int x,int y,int v){ 44 E[++cnt]=(edge){x,y,v}; 45 next[cnt]=head[x]; head[x]=cnt; 46 } 47 void add(int x,int y,int v){ 48 ins(x,y,v); ins(y,x,0); 49 } 50 void add2(int x,int y,int v){ 51 ins(x,y,v); ins(y,x,v); 52 } 53 int s,t,d[N],Q[N]; 54 void init(){ 55 n=getint();m=getint(); 56 cnt=1;tot=ans=0; 57 s=0;t=n*m+1; 58 int x,y; 59 memset(a,-1,sizeof a); 60 FOR a[i][j]=getint(); 61 FOR b[i][j]=getint(); 62 FOR c[i][j]=getint(); 63 FOR if ((i+j)&1) color[i][j]=1; 64 FOR{ 65 if (color[i][j]) swap(a[i][j],b[i][j]); 66 tot+=a[i][j]+b[i][j]; 67 add(s,pack(i,j),a[i][j]); 68 add(pack(i,j),t,b[i][j]); 69 if (color[i][j]) rep(k,4){ 70 int tx=i+fx[k],ty=j+fy[k]; 71 if (!tx||!ty||tx>n||ty>m) continue; 72 add2(pack(i,j),pack(tx,ty),c[i][j]+c[tx][ty]); 73 tot+=c[i][j]+c[tx][ty]; 74 } 75 } 76 } 77 bool mklevel(){ 78 memset(d,-1,sizeof d); 79 d[s]=0; 80 int l=0,r=-1; 81 Q[++r]=s; 82 while(l<=r){ 83 int x=Q[l++]; 84 for(int i=head[x];i;i=next[i]) 85 if (d[E[i].to]==-1 && E[i].v){ 86 d[E[i].to]=d[x]+1; 87 Q[++r]=E[i].to; 88 } 89 } 90 return d[t]!=-1; 91 } 92 int dfs(int x,int a){ 93 if(x==t)return a; 94 int flow=0; 95 for(int i=head[x];i && flow<a;i=next[i]) 96 if (d[E[i].to]==d[x]+1 && E[i].v){ 97 int f=dfs(E[i].to,min(a-flow,E[i].v)); 98 E[i].v-=f; 99 E[i^1].v+=f; 100 flow+=f; 101 } 102 if (!flow) d[x]=-1; 103 return flow; 104 } 105 void Dinic(){ 106 while(mklevel()) ans+=dfs(s,INF); 107 } 108 }G1; 109 int main(){ 110 #ifndef ONLINE_JUDGE 111 freopen("2132.in","r",stdin); 112 freopen("2132.out","w",stdout); 113 #endif 114 G1.init(); G1.Dinic(); 115 printf("%d\n",tot-ans); 116 return 0; 117 }
标签:
原文地址:http://www.cnblogs.com/Tunix/p/4338190.html