日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷2774:[网络流24题]方格取数问题——题解

發(fā)布時間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷2774:[网络流24题]方格取数问题——题解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

https://www.luogu.org/problemnew/show/P2774#sub

在一個有 m*n 個方格的棋盤中,每個方格中有一個正整數(shù)。現(xiàn)要從方格中取數(shù),使任意 2 個數(shù)所在方格沒有公共邊,且取出的數(shù)的總和最大。

試設(shè)計一個滿足要求的取數(shù)算法。對于給定的方格棋盤,按照取數(shù)要求編程找出總和最大的數(shù)。

最小割問題(然而我最開始想的是帶權(quán)二分圖……沒準(zhǔn)他們是一樣的……?)

先黑白染色,這樣黑點只能影響周圍的白點,那么設(shè)源點為S,匯點為T。

則黑點向S連邊權(quán)為其格子數(shù)的權(quán)值的邊,白點向T同理。

然后黑點和其影響的白點連INF的邊。

這樣的話我們的INF的邊不可以被刪,就只能在取黑不取白或取白不取黑之間猶豫了,最后的最小割即是我們選擇放棄的權(quán)值。

格子權(quán)值總和-最小割即可。

#include<cstdio> #include<cmath> #include<iostream> #include<vector> #include<cstring> #include<algorithm> #include<cctype> using namespace std; typedef long long ll; const int N=100100; const int M=800100; const int INF=1e9; inline int read(){int X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } struct node{int nxt,to,w; }edge[M]; int head[N],cnt=-1,S,T; inline void add(int u,int v,int w){edge[++cnt].to=v;edge[cnt].w=w;edge[cnt].nxt=head[u];head[u]=cnt;edge[++cnt].to=u;edge[cnt].w=0;edge[cnt].nxt=head[v];head[v]=cnt; } int lev[N],cur[N],dui[N]; bool bfs(int m){int r=0;for(int i=1;i<=m;i++){lev[i]=-1;cur[i]=head[i];}dui[0]=S,lev[S]=0;int u,v;for(int l=0;l<=r;l++){u=dui[l];for(int e=head[u];e!=-1;e=edge[e].nxt){v=edge[e].to;if(edge[e].w>0&&lev[v]==-1){ lev[v]=lev[u]+1;r++;dui[r]=v; if(v==T)return 1; }}}return 0; } int dinic(int u,int flow,int m){if(u==m)return flow;int res=0,delta;for(int &e=cur[u];e!=-1;e=edge[e].nxt){int v=edge[e].to;if(edge[e].w>0&&lev[u]<lev[v]){ delta=dinic(v,min(edge[e].w,flow-res),m); if(delta>0){edge[e].w-=delta;edge[e^1].w+=delta;res+=delta;if(res==flow)break; }}}if(res!=flow)lev[u]=-1;return res; } int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1}; int main(){memset(head,-1,sizeof(head));int m=read(),n=read();ll ans=0;S=m*n+1,T=S+1;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){int x=(i-1)*n+j,k=i+j,w=read();ans+=w;if(k&1){add(S,x,w);for(int l=0;l<4;l++){int nx=i+dx[l],ny=j+dy[l];if(nx<1||nx>m||ny<1||ny>n)continue;int y=(nx-1)*n+ny;add(x,y,INF);}}else add(x,T,w);}}while(bfs(T))ans-=dinic(S,INF,T);printf("%lld\n",ans);return 0; }

+++++++++++++++++++++++++++++++++++++++++++

?+本文作者:luyouqi233。               +

?+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

轉(zhuǎn)載于:https://www.cnblogs.com/luyouqi233/p/8492900.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的洛谷2774:[网络流24题]方格取数问题——题解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。