[网络流24题] 方格取数问题
2018-02-19 20:18
330 查看
题面:
传送门
思路:
相邻的点不能同时取,那么在这个图中,实际上分了两种格子,每种格子相互之间随便取
那么就是二分图了
把相邻的点之间连边,得到一个二分图,我们实际上就是要求这个图的带权最大独立集
于是这道题转化为二分图问题,而二分图中最大独立集等于全集减去最小点覆盖,最小点覆盖等于这个图的最大匹配(都带权)
那么用网络流做就好了
将这个平面上的方格像国际象棋那样黑白染色
源点连黑点,容量为黑点权值
黑点连白点,容量为inf
白点连汇点,容量为白点权值
跑S-T最大流(即S-T最小割),用所有点的权值和减去最大流值,就得到了答案
因为在这个建好的网络流图里面,最大流等于最小割等于最小点覆盖
Code:
建图比较丑,请见谅
传送门
思路:
相邻的点不能同时取,那么在这个图中,实际上分了两种格子,每种格子相互之间随便取
那么就是二分图了
把相邻的点之间连边,得到一个二分图,我们实际上就是要求这个图的带权最大独立集
于是这道题转化为二分图问题,而二分图中最大独立集等于全集减去最小点覆盖,最小点覆盖等于这个图的最大匹配(都带权)
那么用网络流做就好了
将这个平面上的方格像国际象棋那样黑白染色
源点连黑点,容量为黑点权值
黑点连白点,容量为inf
白点连汇点,容量为白点权值
跑S-T最大流(即S-T最小割),用所有点的权值和减去最大流值,就得到了答案
因为在这个建好的网络流图里面,最大流等于最小割等于最小点覆盖
Code:
建图比较丑,请见谅
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define inf 0x7fffffff using namespace std; inline int read(){ int re=0,flag=1;char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') flag=-1; ch=getchar(); } while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar(); return re*flag; } inline int _min(int l,int r){return (l>r)?r:l;} const int dx[5]={0,-1,0,1,0},dy[5]={0,0,-1,0,1}; int n,m,cnt=-1,ans,x[50][50],first[2500],dep[2500],cur[2500]; struct edge{ int to,next,w; }a[500010]; inline void add(int u,int v,int w){ // cout<<"add "<<u<<ends<<v<<ends<<w<<endl; a[++cnt].to=v;a[cnt].next=first[u];first[u]=cnt;a[cnt].w=w; a[++cnt].to=u;a[cnt].next=first[v];first[v]=cnt;a[cnt].w=0; } inline bool bfs(int s,int t){ int q[2500],head=0,tail=1,i,u,v; for(i=s;i<=t;i++) dep[i]=inf,cur[i]=first[i]; q[0]=s;dep[s]=0; while(head<tail){ u=q[head++]; // cout<<"bfs "<<u<<ends<<dep[u]<<ends<<head<<ends<<tail<<endl; for(i=first[u];~i;i=a[i].next){ v=a[i].to; if(!a[i].w||dep[v]!=inf) continue; // cout<<"to "<<v<<endl; dep[v]=dep[u]+1; q[tail++]=v; } // system("pause"); } return dep[t]!=inf; } int dfs(int u,int t,int low){ // cout<<"dfs "<<u<<ends<<t<<ends<<low<<endl; if(u==t||!low) return low; int flow=0,f,i,v; for(i=cur[u];~i;i=a[i].next){ cur[u]=i;v=a[i].to; if(dep[v]==dep[u]+1&&(f=dfs(v,t,_min(low,a[i].w)))){ // cout<<"in "<<u<<" return from "<<v<<ends<<f<<endl; flow+=f;low-=f; a[i].w-=f;a[i^1].w+=f; if(!low) break; } } // cout<<"return "<<u<<ends<<t<<ends<<low<<ends<<flow<<endl; return flow; } void dinic(){ while(bfs(0,n*m+1)) ans+=dfs(0,n*m+1,inf); } int main(){ freopen("grid.in","r",stdin); freopen("grid.out","w",stdout); memset(first,-1,sizeof(first)); int i,j,k,ti,tj; n=read();m=read(); for(i=1;i<=n;i++) for(j=1;j<=m;j++) x[i][j]=read(),ans-=x[i][j]; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if((i+j)&1) add((i-1)*m+j,n*m+1,x[i][j]); else add(0,(i-1)*m+j,x[i][j]); if((i+j)&1) continue; for(k=1;k<=4;k++){ ti=i+dx[k];tj=j+dy[k]; if(ti<1||ti>n||tj<1||tj>m) continue; add((i-1)*m+j,(ti-1)*m+tj,inf); } } } dinic(); printf("%d",-ans); }
相关文章推荐
- 【网络流24题】方格取数问题
- 【线性规划与网络流24题 9】方格取数问题
- [网络流24题 #9]方格取数问题
- 【网络流24题】方格取数问题
- 【网络流24题】方格取数问题(最大流)
- cogs 734. [网络流24题] 方格取数问题
- [网络流24题] 方格取数问题 (最大权独立集---网络最小割)
- 线性规划与网络流24——方格取数问题
- 【网络流24题----09】方格取数问题
- [网络流24题] 09 方格取数问题 (二分图点权最大独立集,最小割)
- 洛谷2774:[网络流24题]方格取数问题——题解
- 【网络流24题】方格取数问题
- Cogs 734. [网络流24题] 方格取数问题(最大闭合子图)
- 【网络流24题】No.9 方格取数问题 (二分图点权最大独立集)
- 网络流24题--方格取数问题
- Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)
- [网络流24题]方格取数问题
- [网络流 24 题] 方格取数问题 骑士共存问题
- AC日记——[网络流24题]方格取数问题 cogs 734
- [网络流24题] 方格取数问题(cogs 734)