【学术篇】网络流24题——方格取数问题

xiaoxiao2021-02-28  21

Emmmm昨天晚上下第二节课回家, 本来觉得自己应该能在1h之内写完调完, 但是网络流板子好像出锅了? 好像加完当前弧优化就WA掉了? 去掉之后就可以过? 非常不能理解.

好吧我们来分析题目.

我们还是按照题目的要求来建图: - 不能选有公共边的格子, 我们可以很显然地想到黑白染色, 然后黑点一排, 白点一排. - 将源点与每个黑点相连(当然你想连白点也没人管), 流量是这个点的权值. - 将每个白点(如果之前连了白点那这次就连黑点咯), 流量是这个点的权值. - 将每个黑(白)点与和其有公共边的白(黑)点相连, 流量为 . - 那么割掉一个点与源点或汇点的连边就表示不选这个点. - 所以我们用所有点权的总和减去最小割就ok咯~

还是画一下样例建图(似乎windows下的画图还是要好用些←_←

然后就是代码

#include <queue> #include <cstdio> #include <cstring> using std::queue; const int N=1e4+8; const int M=1e5+5; const int INF=0x7f7f7f7f; inline int gn(int a=0,char c=0){ for(;c<'0'||c>'9';c=getchar()); for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a; } struct edge{ int to,next,flow; }e[M]; int v[N],tot=1; void buildedge(int x,int y,int z){ e[++tot].to=y; e[tot].next=v[x]; e[tot].flow=z; v[x]=tot; e[++tot].to=x; e[tot].next=v[y]; e[tot].flow=0; v[y]=tot; } int d[N],cur[N],n,m,s,t,sum; queue<int> q; bool bfs(){ memset(d,-1,sizeof(d)); d[s]=0; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=v[x];i;i=e[i].next) if(e[i].flow&&d[e[i].to]<0){ d[e[i].to]=d[x]+1; q.push(e[i].to); } } return d[t]>0; } int dfs(int x,int mx,int s=0){ int k; if(!mx||x==t) return mx; for(int i=v[x];i;i=e[i].next){ if(d[e[i].to]==d[x]+1){ k=dfs(e[i].to,std::min(mx,e[i].flow)); if(k) s+=k,mx-=k,e[i].flow-=k,e[i^1].flow+=k; if(!mx) break; } } return s; } int main(){ n=gn(); m=gn(); s=0; t=n*m+1; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ int k=(i-1)*m+j,x=gn(); sum+=x; if((i+j)&1){ buildedge(s,k,x); if(i>1) buildedge(k,k-m,INF); if(i<n) buildedge(k,k+m,INF); if(j>1) buildedge(k,k-1,INF); if(j<m) buildedge(k,k+1,INF); } else buildedge(k,t,x); } while(bfs()) sum-=dfs(s,INF); printf("%d",sum); }

反正就这样吧 dinic板子是真的打不对了… 所以到底为什么当前弧优化会被卡啊QAQ

转载请注明原文地址: https://www.6miu.com/read-2049992.html

最新回复(0)