【BZOJ】【1324】王者之剑
网络流/二分图最大点权独立集
Amber(胡伯涛)论文《最小割模型在信息学竞赛中的应用》中的例题……
感觉这个好神啊,果然是一切皆为网络流……这转化太神奇了
1 /************************************************************** 2 Problem: 1324 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:168 ms 7 Memory:2228 kb 8 ****************************************************************/ 9 10 //BZOJ 1324 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=11000,M=50010,INF=~0u>>2; 29 typedef long long LL; 30 /******************tamplate*********************/ 31 int n,m,ans; 32 struct edge{ 33 int from,to,v; 34 }; 35 inline int pack(int i,int j){return (i-1)*m+j;} 36 struct Net{ 37 edge E[M]; 38 int head[N],next[M],cnt; 39 void add(int x,int y,int v){ 40 E[++cnt]=(edge){x,y,v}; 41 next[cnt]=head[x]; head[x]=cnt; 42 E[++cnt]=(edge){y,x,0}; 43 next[cnt]=head[y]; head[y]=cnt; 44 } 45 int s,t,cur[N],d[N],Q[N]; 46 void init(){ 47 n=getint();m=getint(); 48 ans=0;cnt=1; 49 s=0; t=n*m+1; 50 int x; 51 F(i,1,n) F(j,1,m){ 52 x=getint();ans+=x; 53 if ((i+j)&1) add(pack(i,j),t,x); 54 else{ 55 add(s,pack(i,j),x); 56 if (i!=1) add(pack(i,j),pack(i-1,j),INF); 57 if (i!=n) add(pack(i,j),pack(i+1,j),INF); 58 if (j!=1) add(pack(i,j),pack(i,j-1),INF); 59 if (j!=m) add(pack(i,j),pack(i,j+1),INF); 60 } 61 } 62 } 63 bool mklevel(){ 64 memset(d,-1,sizeof d); 65 d[s]=0; 66 int l=0,r=-1; 67 Q[++r]=s; 68 while(l<=r){ 69 int x=Q[l++]; 70 for(int i=head[x];i;i=next[i]) 71 if (d[E[i].to]==-1 && E[i].v){ 72 d[E[i].to]=d[x]+1; 73 Q[++r]=E[i].to; 74 } 75 } 76 return d[t]!=-1; 77 } 78 int dfs(int x,int a){ 79 if (x==t||a==0) return a; 80 int flow=0; 81 for(int &i=cur[x];i && flow<a;i=next[i]) 82 if (d[E[i].to]==d[x]+1 && E[i].v){ 83 int f=dfs(E[i].to,min(a-flow,E[i].v)); 84 E[i].v-=f; 85 E[i^1].v+=f; 86 flow+=f; 87 } 88 if (!flow) d[x]=-1; 89 return flow; 90 } 91 int Dinic(){ 92 int flow=0; 93 while(mklevel()){ 94 F(i,s,t) cur[i]=head[i]; 95 flow+=dfs(s,INF); 96 } 97 return flow; 98 } 99 }G1; 100 101 int main(){ 102 #ifndef ONLINE_JUDGE 103 freopen("1324.in","r",stdin); 104 freopen("1324.out","w",stdout); 105 #endif 106 G1.init(); 107 printf("%d\n",ans-G1.Dinic()); 108 return 0; 109 }