洛谷P2774 方格取数问题(最小割)
2018-08-19 19:01
281 查看
传送门
考虑一下,答案就是全局和减去舍弃和
不难发现,如果我们按行数+列数的奇偶性分为两类,那么每一类中的数必然互不相邻
那么我们把原图的点分为黑点和白点两类,原地向白点连边,黑点向汇点连边,容量为点权,然后白点向相邻的黑点连边
考虑一下,不能有相邻的,就是在残留网络中不能有$s->u->v->t$这一条路径,那么肯定要在某一个地方割掉。然后要求和最大,所以求得是最小割
然后最小割等于最大流,求一下最大流即可
考虑一下,答案就是全局和减去舍弃和
不难发现,如果我们按行数+列数的奇偶性分为两类,那么每一类中的数必然互不相邻
那么我们把原图的点分为黑点和白点两类,原地向白点连边,黑点向汇点连边,容量为点权,然后白点向相邻的黑点连边
考虑一下,不能有相邻的,就是在残留网络中不能有$s->u->v->t$这一条路径,那么肯定要在某一个地方割掉。然后要求和最大,所以求得是最小割
然后最小割等于最大流,求一下最大流即可
//minamoto #include<iostream> #include<cstdio> #include<queue> #include<cstring> #define inf 0x3f3f3f3f using namespace std; #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) char buf[1<<21],*p1=buf,*p2=buf; inline int read(){ #define num ch-'0' char ch;bool flag=0;int res; while(!isdigit(ch=getc())) (ch=='-')&&(flag=true); for(res=num;isdigit(ch=getc());res=res*10+num); (flag)&&(res=-res); #undef num return res; } const int N=10005,M=100005; int dx[]={1,-1,0,0},dy[]={0,0,1,-1}; int ver[M],Next[M],edge[M],head ,dep ,cur ,tot=1; int n,m,s,t,ans; queue<int> q; inline void add(int u,int v,int e){ ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0; } bool bfs(){ memset(dep,-1,sizeof(dep)); while(!q.empty()) q.pop(); for(int i=0;i<=n*m+1;++i) cur[i]=head[i]; q.push(s),dep[s]=0; while(!q.empty()){ int u=q.front();q.pop(); for(int i=head[u];i;i=Next[i]){ int v=ver[i]; if(dep[v]<0&&edge[i]){ dep[v]=dep[u]+1,q.push(v); if(v==t) return true; } } } return false; } int dfs(int u,int limit){ if(!limit||u==t) return limit; int flow=0,f; for(int i=cur[u];i;i=Next[i]){ int v=ver[i];cur[u]=i; if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){ flow+=f,limit-=f; edge[i]-=f,edge[i^1]+=f; if(!limit) break; } } return flow; } int dinic(){ int flow=0; while(bfs()) flow+=dfs(s,inf); return flow; } int main(){ n=read(),m=read(); s=0,t=n*m+1; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ int x=read();ans+=x; int id=(i-1)*m+j; ((i+j)&1)?(add(s,id,x)):(add(id,t,x)); } for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if((i+j)&1){ int id=(i-1)*m+j; for(int k=0;k<4;++k){ int xx=i+dx[k],yy=j+dy[k]; if(xx<=0||xx>n||yy<=0||yy>m) continue; add(id,(xx-1)*m+yy,inf); } } printf("%d\n",ans-dinic()); return 0; }
相关文章推荐
- 洛谷 P2774 方格取数问题【最小割】
- 洛谷P2774 方格取数问题 BZOJ 1143祭祀river【二分图最大独立集】
- 洛谷P2774:方格取数问题
- 洛谷 P2774 方格取数问题
- 网络流24题3最小路径覆盖问题(洛谷 P2764 最小路径覆盖问题)
- 洛谷 P3355 骑士共存问题【最小割】
- [网络流24题] 方格取数问题 (最大权独立集---网络最小割)
- 【网络流二十四题 方格取数问题】【二分图点权最大独立集->最小割】
- 【洛谷】方格取数问题-网络流
- 洛谷 P2762 太空飞行计划问题 【最大权闭合子图+最小割】
- AC日记——最小路径覆盖问题 洛谷 P2764
- 洛谷 P2764 最小路径覆盖问题【匈牙利算法】
- P2774 方格取数问题
- 洛谷2764:[网络流24题]最小路径覆盖问题——题解
- [网络流24题] 09 方格取数问题 (二分图点权最大独立集,最小割)
- luogu2774 方格取数问题(最小割)网络流24题:9
- 最小割的应用--方格取数问题(HDU 1565,HDU 1569)
- [题解] [网络流二十四题(九)] 方格取数问题(最小割)
- 洛谷P2774方格取数(网络流24题)
- (P2774 方格取数问题)<状压DP>