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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P4313-文理分科【最小割】

發布時間:2023/12/3 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4313-文理分科【最小割】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P4313


題目大意

n?mn*mn?m個人,第(i,j)(i,j)(i,j)選擇文科就可以獲得arti,jart_{i,j}arti,j?的價值,選擇理科就可以獲得scii,jsci_{i,j}scii,j?的價值。如果一個選擇文科的人周圍都選擇了文科,那么就可以多獲得same_arti,jsame\_art_{i,j}same_arti,j?的價值。如果一個選擇了理科的人周圍都選擇了理科,那么就可以多獲得same_scii,jsame\_sci_{i,j}same_scii,j?的價值。

求最大價值和。


解題思路

顯然不考慮samesamesame的話如何將其模型轉移到網絡流上,考慮最小割。我們對于每個同學(i,j)(i,j)(i,j)建立一個節點pi,j,0p_{i,j,0}pi,j,0?,然后S?>pi,j,0S->p_{i,j,0}S?>pi,j,0?流量為arti,jart_{i,j}arti,j?pi,j,0?>Tp_{i,j,0}->Tpi,j,0??>T流量為scii,jsci_{i,j}scii,j?

考慮如何加入samesamesame入這個模型中,先考慮文科的,對于一個點我們發現如果它周圍的都割掉了理科的邊就不需要割same_artsame\_artsame_art,也就是我們需要新建一個節點連接這些周圍的節點,這樣這些被連接的節點就必須要割掉連向TTT的邊 。顯然我們還需要建立S?>pi,j,1S->p_{i,j,1}S?>pi,j,1?流量為same_arti,jsame\_art_{i,j}same_arti,j?

same_scii,jsame\_ sci_{i,j}same_scii,j?同理。


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define p(x,y,z) ((((x)-1)*m+(y))+(z)*S) using namespace std; const int N=3e4+10,inf=2147483647/3; struct node{int to,next,w; }a[N*20]; const int dx[5]={1,-1,0,0,0},dy[5]={0,0,1,-1,0}; int n,m,s,t,S,tot=1; int dep[N],ls[N],ans; queue<int> q; void adde(int x,int y,int w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;return; } bool bfs(){while(!q.empty())q.pop();memset(dep,0,sizeof(dep));dep[s]=1;q.push(s);while(!q.empty()){int x=q.front();q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!a[i].w||dep[y])continue;dep[y]=dep[x]+1;if(y==t)return 1;q.push(y);}}return 0; } int dinic(int x,int flow){int rest=0,k;if(x==t)return flow;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!a[i].w||dep[y]!=dep[x]+1)continue;rest+=(k=dinic(y,min(flow-rest,a[i].w)));a[i].w-=k;a[i^1].w+=k;if(rest==flow)return flow;}if(!rest)dep[x]=0;return rest; } int main() {scanf("%d%d",&n,&m);S=n*m;s=p(n,m,2)+1;t=s+1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int x;scanf("%d",&x);adde(s,p(i,j,0),x);ans+=x;}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int x;scanf("%d",&x);adde(p(i,j,0),t,x);ans+=x;}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int x;scanf("%d",&x);adde(s,p(i,j,1),x);ans+=x;for(int k=0;k<5;k++){int zx=i+dx[k],zy=j+dy[k];if(zx<1||zy<1||zx>n||zy>m)continue;adde(p(i,j,1),p(zx,zy,0),inf);}}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int x;scanf("%d",&x);adde(p(i,j,2),t,x);ans+=x;for(int k=0;k<5;k++){int zx=i+dx[k],zy=j+dy[k];if(zx<1||zy<1||zx>n||zy>m)continue;adde(p(zx,zy,0),p(i,j,2),inf);}}while(bfs())ans-=dinic(s,inf);printf("%d",ans); }

總結

以上是生活随笔為你收集整理的P4313-文理分科【最小割】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。