【BZOJ4261】建设游乐场(费用流)

mac2025-09-10  3

传送门


没有题解。

转化成要尽量少的格子是直的,然后就和这道题一样了:here


代码:

#include<bits/stdc++.h> #define ll long long #define re register #define cs const namespace IO{ inline char gc(){ static cs int Rlen=1<<22|1; static char buf[Rlen],*p1,*p2; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++; } template<typename T>inline T get(){ char c;T num; while(!isdigit(c=gc()));num=c^48; while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48); return num; }inline int gi(){return get<int>();} } using namespace IO; using std::cerr; using std::cout; cs int R=155,C=35; int S,T,tot; namespace NetWork{ cs int N=(R*C+100)<<1|7; struct edge{int to,rev,cap,w;}; typedef std::vector<edge>::iterator iter; std::vector<edge> G[N];iter cur[N]; inline void adde(int u,int v,int cap,int cost){ G[u].push_back((edge){v,(int)G[v].size(),cap,cost}); G[v].push_back((edge){u,(int)G[u].size()-1,0,-cost}); } int dis[N],vis[N]; inline bool SPFA(){ memset(dis+1,0x3f,tot<<2); std::deque<int> q;q.push_back(S),dis[S]=0; while(!q.empty()){ int u=q.front();q.pop_front(); vis[u]=false,cur[u]=G[u].begin(); for(iter e=G[u].begin();e!=G[u].end();++e) if(e->cap&&dis[e->to]>dis[u]+e->w){ dis[e->to]=dis[u]+e->w; if(!vis[e->to]){ if(!q.empty()&&dis[e->to]<dis[q.front()])q.push_front(e->to); else q.push_back(e->to); vis[e->to]=true; } } }return dis[T]<1e9; } int tot_flow,tot_cost; int dfs(int u,int flow){ if(u==T){ tot_flow+=flow; tot_cost+=dis[T]*flow; return flow; }int ans=0;vis[u]=true; for(iter &e=cur[u];e!=G[u].end();++e) if(e->cap&&dis[e->to]==dis[u]+e->w&&!vis[e->to]){ int delta=dfs(e->to,std::min(flow-ans,e->cap)); ans+=delta,e->cap-=delta,G[e->to][e->rev].cap+=delta; }vis[u]=false;return ans; } void Flow(){ tot_cost=tot_flow=0; while(SPFA())dfs(S,1e9); } } using NetWork::adde; using NetWork::tot_flow; using NetWork::tot_cost; int n,m,ct,cnt,ans; int id1[R][C],id2[R][C]; int ok[R][C],val[R][C]; #undef zxyoi signed main(){ #ifdef zxyoi freopen("project.in","r",stdin); #else #ifndef ONLINE_JUDGE freopen("project.in","r",stdin);freopen("project.out","w",stdout); #endif #endif n=gi(),m=gi();S=1,T=tot=2; for(int re i=1;i<=n;++i) for(int re j=1;j<=m;++j){ ok[i][j]=gi()^1; if(ok[i][j])id1[i][j]=++tot,id2[i][j]=++tot; } for(int re i=1;i<=n;++i) for(int re j=1;j<=m;++j){ val[i][j]=gi(); if(ok[i][j]){ ans+=val[i][j];++cnt; if((i^j)&1){ ++ct; adde(id1[i][j],T,1,0); adde(id2[i][j],T,1,0); }else { --ct; adde(S,id1[i][j],1,0); adde(S,id2[i][j],1,0); for(int re k=0;k<4;++k){ static cs int dx[]={0,1,0,-1}; static cs int dy[]={1,0,-1,0}; int x=i+dx[k],y=j+dy[k]; if(x<1||x>n||y<1||y>m||!ok[x][y])continue; if(k&1)adde(id1[i][j],id2[x][y],1,0); else adde(id2[i][j],id1[x][y],1,0); } } adde(id1[i][j],id2[i][j],1,val[i][j]); adde(id2[i][j],id1[i][j],1,val[i][j]); } } if(ct)return puts("-1"),0;NetWork::Flow(); if(tot_flow!=cnt)return puts("-1"),0; cout<<ans-tot_cost<<"\n"; return 0; }
最新回复(0)