题目大意:
n
n
n个人,每个人有一个意愿
0
0
0或
1
1
1
m
m
m对关系,表示
(
i
,
j
)
(i,j)
(i,j)是一对好朋友,即意愿应该相同
求最小冲突
冲突数为
与
自
身
意
愿
冲
突
人
数
+
与
好
友
意
愿
冲
突
人
数
与自身意愿冲突人数+与好友意愿冲突人数
与自身意愿冲突人数+与好友意愿冲突人数
分析:
明显是求最小割
考虑建立源点汇点
S
,
T
S,T
S,T
①
S
−
>
意
愿
为
0
S->意愿为0
S−>意愿为0
②
意
愿
为
1
−
>
T
意愿为1->T
意愿为1−>T
③好友间连边
考虑就是使得不存在
S
−
>
意
愿
为
0
−
>
意
愿
为
1
−
>
T
S->意愿为0->意愿为1->T
S−>意愿为0−>意愿为1−>T这种路径
那就是最小割,网络流即可
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <algorithm>
#define inf 0x3f3f3f3f
#define N 305
using namespace std;
struct Node { int To, w, nxt; }e[N*N*2];
int A[N][N], id[N], dis[2*N*N], ls[2*N*N], n, m, d, cnt = 1, tot = 0, Total = 0, Maxflow = 0, S, T;
char s[N];
int num[2];
int Numid(int x, int y)
{
return (x - 1) * m + y;
}
void Addedge(int u, int v, int w)
{
e[++cnt].To = v, e[cnt].nxt = ls[u], e[cnt].w = w, ls[u] = cnt;
e[++cnt].To = u, e[cnt].nxt = ls[v], e[cnt].w = 0, ls[v] = cnt;
}
bool Checkjl(int ax, int ay, int bx, int by)
{
return (((ax - bx) * (ax - bx) + (ay - by) * (ay - by)) <= (d * d));
}
queue <int> Q;
bool bfs()
{
while (Q.size()) Q.pop();
for (int i = S; i <= T; i++) dis[i] = 0;
dis[S] = 1;
Q.push(S);
while (Q.size())
{
int u = Q.front(); Q.pop();
for (int i = ls[u]; i; i = e[i].nxt)
if (e[i].w && !dis[e[i].To])
{
dis[e[i].To] = dis[u] + 1;
if (e[i].To == T) return 1;
Q.push(e[i].To);
}
}
return 0;
}
int dfs(int u, int flow)
{
if (u == T) return flow;
int rest = flow, rp = 0;
for (int i = ls[u]; i && rest; i = e[i].nxt)
if (dis[e[i].To] == dis[u] + 1 && e[i].w)
{
rp = dfs(e[i].To, min(rest, e[i].w));
if (!rp) dis[e[i].To] = 0;
e[i].w -= rp;
e[i^1].w += rp;
rest -= rp;
}
return flow - rest;
}
void dinic()
{
int flow;
while (bfs())
while (flow = dfs(S, inf)) Maxflow += flow;
}
int main()
{
// freopen("data.in", "r", stdin);
scanf("%d%d", &n, &m);
S = 0, T = n + 1;
int x, y;
for (int i = 1; i <= n; i++)
{
scanf("%d", &id[i]);
if (!id[i]) Addedge(i, T, 1); else Addedge(S, i, 1);
}
for (int i = 1; i <= m; i++)
{
scanf("%d%d", &x, &y);
Addedge(x, y, 1); Addedge(y, x, 1);
}
dinic();
printf("%d\n", Maxflow);
return 0;
}