luogu2774 [网络流24题]方格取数问题 (最小割)

常见套路:棋盘黑白染色,就变成了一张二分图

然后如果选了黑点,四周的白点就不能选了,也是最小割的套路。先把所有价值加起来,再减掉一个最少的不能选的价值,也就是割掉表示不选

建边(S,黑点i,v[i]),(黑点i,i四周的白点,inf),(白点j,T,v[j])

(黑点还是白点,你必须要割一个...)

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=100*100+10,maxm=100*100*20+5,inf=1e9;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 struct Edge{
16     int a,b,l,ne;
17 }eg[maxm];
18 int egh[maxn],ect=1,cur[maxn];
19 int N,M,S,T;
20 int dep[maxn];
21 queue<int> q;
22 
23 inline void adeg(int a,int b,int c){
24     // printf("!%d %d %d
",a,b,c);
25     eg[++ect].a=a,eg[ect].b=b,eg[ect].l=c,eg[ect].ne=egh[a],egh[a]=ect;
26     eg[++ect].a=b,eg[ect].b=a,eg[ect].l=0,eg[ect].ne=egh[b],egh[b]=ect;
27 }
28 
29 inline bool bfs(){
30     CLR(dep,0);CLR(cur,-1);
31     dep[S]=1,q.push(S);
32     while(!q.empty()){
33         int p=q.front();q.pop();
34         for(int i=egh[p];i;i=eg[i].ne){
35             int b=eg[i].b;
36             if(!eg[i].l||dep[b]) continue;
37             dep[b]=dep[p]+1;
38             q.push(b);
39         }
40     }
41     return dep[T];
42 }
43 
44 int dinic(int x,int y){
45     if(x==T) return y;
46     if(cur[x]==-1) cur[x]=egh[x];
47     int tmp=y;
48     for(int &i=cur[x];i;i=eg[i].ne){
49         int b=eg[i].b;
50         if(dep[b]!=dep[x]+1||!eg[i].l) continue;
51         int re=dinic(b,min(tmp,eg[i].l));
52         tmp-=re,eg[i].l-=re,eg[i^1].l+=re;
53         if(!tmp) break;
54     }return y-tmp;
55 }
56 int main(){
57     //freopen("","r",stdin);
58     int i,j,k;
59     M=rd(),N=rd();
60     S=N*M+1,T=N*M+2;
61     int ans=0;
62     for(i=1;i<=M;i++){
63         for(j=1;j<=N;j++){
64             int id=(i-1)*N+j;
65             k=rd();ans+=k;
66             if(((i&1)&&(j&1))||(!(i&1)&&!(j&1))){
67                 adeg(S,id,k);
68                 if(j<N) adeg(id,id+1,inf);
69                 if(j>1) adeg(id,id-1,inf);
70                 if(i<M) adeg(id,id+N,inf);
71                 if(i>1) adeg(id,id-N,inf);
72             }else  adeg(id,T,k);
73         }
74     }
75     while(bfs()) ans-=dinic(S,inf);
76     printf("%d
",ans);
77     return 0;
78 }
原文地址:https://www.cnblogs.com/Ressed/p/9816531.html