【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 }
View Code

 

posted @ 2015-03-13 22:32  Tunix  阅读(245)  评论(0编辑  收藏  举报