【题意】
每个点有一个价值,选了一个点,就不能选周围四个点,求最大的价值
【分析】
依然是很裸的黑白染色
【代码】
#include<bits/stdc++.h> using namespace std; #define mp make_pair #define fi first #define se second #define lson now<<1 #define rson now<<1|1 typedef long long ll; const int maxn=205; const int maxm=40005; int id[maxn][maxn],cnt; int val[maxn][maxn],n,m; int S,T; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; const ll inf=1e17; int head[10005],tot=1,cur[10005]; struct edge { int to,nxt; ll v; }e[maxm<<1]; void add(int x,int y,ll z) { e[++tot].to=y; e[tot].nxt=head[x]; e[tot].v=z; head[x]=tot; e[++tot].to=x; e[tot].nxt=head[y]; e[tot].v=0; head[y]=tot; } int dep[10005]; bool bfs() { for(int i=S;i<=T;i++) dep[i]=-1,cur[i]=head[i]; // memset(dep,-1,sizeof(dep)); // memcpy(cur,head,sizeof(cur)); queue <int> q; dep[S]=0; q.push(S); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=e[i].nxt) { int to=e[i].to; if(dep[to]!=-1 || !e[i].v) continue; q.push(to); dep[to]=dep[u]+1; } } return (dep[T]!=-1); } ll dfs(int u,ll flow) { if(u==T) return flow; ll res=0; for(int &i=cur[u];i;i=e[i].nxt) { int to=e[i].to; if(dep[to]!=dep[u]+1 || e[i].v<=0) continue; ll tmp=dfs(to,min(e[i].v,flow)); flow-=tmp; res+=tmp; e[i].v-=tmp; e[i^1].v+=tmp; if(!flow) break; } if(!res) dep[u]=-1; return res; } ll ans; ll dinic() { ll ans=0; while(bfs()) { ans+=dfs(S,inf); } return ans; } int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); scanf("%d%d",&n,&m); S=0; T=n*m+1; ll sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&val[i][j]); id[i][j]=++cnt; sum+=val[i][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if((i+j)%2==0) { add(S,id[i][j],val[i][j]); for(int k=0;k<4;k++) { int tox=i+dx[k]; int toy=j+dy[k]; if(tox<1 || toy<1 || tox>n || toy>m) continue; add(id[i][j],id[tox][toy],inf/2); } } else add(id[i][j],T,val[i][j]); } printf("%lld",sum-dinic()); return 0; }
原文:https://www.cnblogs.com/andylnx/p/14845240.html