Luogu P2057 最小割

熟练一下 Luogu P2057

问题转化为最小割

建图

  • 同意睡觉和反对睡觉恰好为2部分,
  1. 同意睡觉的点和$S$部分的源点连边, 同理, 反对睡觉的点和$T$部分的汇点连边, 边权都为1
  2. 朋友之间连边 因为都可以违背自己的意愿, 所以建双向边且边权为1
  • 最后每个人只有一个决定(每个点都只能属于一个部分),为了使得冲突最小,,割掉最少的边将图分成2部分,即求最小割
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <bits/stdc++.h>
using namespace std;
const int maxn = 400;
const int maxm = 1e5+5;
const int inf = 1e8;

struct Edge{
int v,next,c;
}edge[maxm];

int n,m,tot,source,sink;
int head[maxn],dep[maxn],cur[maxn];

void add(int u,int v,int c) {
edge[tot].v=v; edge[tot].c=c;
edge[tot].next=head[u]; head[u]=tot++;
}
void addedge(int u,int v,int c) {
add(u,v,c);
add(v,u,0);
}

bool bfs() {
queue<int> que;
memset(dep,-1,sizeof dep);
dep[source]=0;
que.push(source);
while (!que.empty()) {
int u = que.front(); que.pop();
for (int i=head[u]; i!=-1; i=edge[i].next) {
int to = edge[i].v;
if (edge[i].c>0 && dep[to] == -1) {
dep[to] = dep[u] + 1;
que.push(to);
if (to == sink) return 1;
}
}
}
return dep[sink] != -1;
}

int dfs(int u,int dist) {
if (u == sink)
return dist;
for (int &i=cur[u]; i!=-1; i=edge[i].next) {
int to = edge[i].v;
if (edge[i].c>0 && dep[to]==dep[u]+1) {
int temp = dfs(to,min(dist,edge[i].c));
if (temp > 0) {
edge[i].c -= temp;
edge[i^1].c += temp;
return temp;
}
}
}
return 0;
}

int Dinic() {
int ans = 0;
while (bfs()) {
for (int i=0; i<=sink; ++i)
cur[i] = head[i];
while(1) {
int temp = dfs(source,inf);
if (!temp) break;
ans += temp;
}
}
return ans;
}

int main() {
cin >> n >> m;
memset(head,-1,sizeof head);
source=0; sink = n+1;
for(int i=1; i<=n; ++i) {
int temp; cin >> temp;
if (temp)
addedge(source,i,1);
else
addedge(i , sink,1);
}
while (m--) {
int fri_1,fri_2;
cin >> fri_1 >> fri_2;
add(fri_1,fri_2,1);
add(fri_2,fri_1,1);
//addedge(fri_1,fri_2,1);
}
cout << Dinic() << endl;
return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!