[BZOJ1475]方格取数 网络流 最小割

Posted wls001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ1475]方格取数 网络流 最小割相关的知识,希望对你有一定的参考价值。

1475: 方格取数

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1025  Solved: 512
[Submit][Status][Discuss]

Description

在一个n*n的方格里,每个格子里都有一个正整数。从中取出若干数,使得任意两个取出的数所在格子没有公共边,且取出的数的总和尽量大。

Input

第一行一个数n;(n<=30) 接下来n行每行n个数描述一个方阵

Output

仅一个数,即最大和

Sample Input

2
1 2
3 5

Sample Output

6
 
黑白染色求最小割
技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<algorithm>
 7 using namespace std;
 8 int tx[5]={0,1,0,-1};
 9 int ty[5]={1,0,-1,0};
10 struct data {
11     int to,next,f;
12 }e[800005];
13 int head[5005],cnt;
14 void add(int u,int v,int f){e[cnt].to=v;e[cnt].next=head[u];e[cnt].f=f;head[u]=cnt++;}
15 int n,m,s,t;
16 bool vis[5005];
17 int q[5005],dis[5005];
18 bool bfs() {
19     memset(dis,-57,sizeof(dis));
20     int h=0,tail=1;
21     q[h]=t;
22     dis[t]=0;
23     while(h!=tail) {
24         int now=q[h++];if(h==5000) h=0;
25         for(int i=head[now];i>=0;i=e[i].next) {
26             if(dis[e[i].to]>-100000||!e[i^1].f) continue;
27             dis[e[i].to]=dis[now]-1;
28             q[tail++]=e[i].to;if(tail==5000) tail=0;
29         }    
30     }
31     return dis[s]>=-100000;
32 }
33 int dfs(int now,int a) {
34     int f=0,flow=0;
35     if(now==t) return a;
36     for(int i=head[now];i>=0;i=e[i].next) {
37         int to=e[i].to;
38         if(dis[to]==dis[now]+1&&e[i].f>0) {
39             f=dfs(to,min(a,e[i].f));
40             flow+=f;
41             e[i].f-=f;
42             e[i^1].f+=f;
43             a-=f;
44             if(a==0) break;
45         }
46     }
47     return flow;
48 }
49 int num=0;
50 int ans=0;
51 int sum=0;
52 void dinic() {
53     while(bfs()) {
54         sum+=dfs(s,2147483647);
55     }
56     printf("%d",num-sum);
57 }
58 int tt=0;
59 int a[50][50];
60 int main() {
61     memset(head,-1,sizeof(head));
62     scanf("%d%d",&m,&n);
63     s=0,t=5000;
64     for(int i=1;i<=m;i++)
65         for(int j=1;j<=n;j++) {
66             scanf("%d",&a[i][j]);
67             num+=a[i][j];
68         }
69     for(int i=1;i<=m;i++) {
70         for(int j=1;j<=n;j++) {
71             if((i+j)&1) {
72                 add(s,(i-1)*n+j,a[i][j]),add((i-1)*n+j,s,0);
73                 for(int k=0;k<=3;k++) {
74                     int tox=i+tx[k],toy=j+ty[k];
75                     if(tox==0||tox>m||toy==0||toy>n) continue;
76                     add((i-1)*n+j,(tox-1)*n+toy,1e8);
77                     add((tox-1)*n+toy,(i-1)*n+j,0);
78                 }
79             } 
80             else add((i-1)*n+j,t,a[i][j]),add(t,(i-1)*n+j,0);
81             
82         }
83     }
84     dinic();
85 }
View Code

 








以上是关于[BZOJ1475]方格取数 网络流 最小割的主要内容,如果未能解决你的问题,请参考以下文章

网络流24题之方格取数问题 二分图+最小割

734. [网络流24题] 方格取数问题 二分图点权最大独立集/最小割/最大流

luogu 2774方格取数 (最小割)

luogu P2774 方格取数问题 网络流24 最小割

方格取数问题(网络流)

「网络流24题」 9. 方格取数问题