P2805-[NOI2009]植物大战僵尸【网络流,最大权闭合图】
生活随笔
收集整理的這篇文章主要介紹了
P2805-[NOI2009]植物大战僵尸【网络流,最大权闭合图】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P2805
題目大意
n?mn*mn?m的格子,攻擊這個(gè)格子(x,y)(x,y)(x,y)可以獲得價(jià)值cx,yc_{x,y}cx,y?,攻擊一個(gè)格子(x,y)(x,y)(x,y)前要攻擊(x,y+1)(x,y+1)(x,y+1)。
對(duì)于有的格子(x,y)(x,y)(x,y)會(huì)保護(hù)些格子,攻擊一個(gè)格子直接必須攻擊掉保護(hù)它的格子。
求最大價(jià)值
解題思路
先用拓?fù)渑判蛉サ粢恍o(wú)法攻擊的格子(相互保護(hù)或者被相互保護(hù)的格子保護(hù)的)。
然后就是最大權(quán)閉合圖的問(wèn)題就好了,跑網(wǎng)絡(luò)流
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define p(x,y) ((x-1)*m+y) using namespace std; const int N=30*40,inf=2e9; struct node{int to,next,w; }a[N*N]; int ls[N],dep[N],tot=1,n,m,ans,s,e,in[N],edge[N][N],c[N],v[N][N]; queue<int>q; void add_edge(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; } bool bfs() {memset(dep,0,sizeof(dep));while(!q.empty())q.pop();q.push(s);dep[s]=1;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(dep[y]||!a[i].w) continue;q.push(y);dep[y]=dep[x]+1;if(y==e) return 1;}}return 0; } int dinic(int x,int flow){int rest=0,k;if(x==e) return flow;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(dep[x]+1==dep[y]&&a[i].w){rest+=(k=dinic(y,min(a[i].w,flow-rest)));a[i].w-=k;a[i^1].w+=k;if(rest==flow) return flow;} }if(!rest) dep[x]=0;return rest; } void net_flow(){while(bfs())ans-=dinic(s,inf); } void init(){scanf("%d%d",&n,&m);s=p(n,m)+1;e=s+1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int k;scanf("%d%d",&c[p(i,j)],&k);if(c[p(i,j)]>=0) edge[s][p(i,j)]=c[p(i,j)];if(c[p(i,j)]<0) edge[p(i,j)][e]=-c[p(i,j)];while(k--){int x,y;scanf("%d%d",&x,&y);x++;y++;v[p(i,j)][p(x,y)]++;edge[p(x,y)][p(i,j)]=inf,in[p(x,y)]++;}if(j<m) v[p(i,j+1)][p(i,j)]++,edge[p(i,j)][p(i,j+1)]=inf,in[p(i,j)]++;} } void top_sort(){for(int i=1;i<s;i++)if(!in[i])q.push(i);while(!q.empty()){int x=q.front();q.pop();for(int y=1;y<s;y++){if(!v[x][y]) continue;in[y]-=v[x][y];if(!in[y])q.push(y);}} } void build_graph(){for(int i=1;i<s;i++)if(!in[i]&&c[i]>0)ans+=c[i];for(int i=1;i<=e;i++)for(int j=1;j<=e;j++) if(edge[i][j]&&!in[i]&&!in[j])add_edge(i,j,edge[i][j]); } int main() {init();top_sort();build_graph();net_flow();printf("%d",ans); } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的P2805-[NOI2009]植物大战僵尸【网络流,最大权闭合图】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 流星花园演员表 流星花园演员表介绍
- 下一篇: jzoj3852-单词接龙【0/1分数规