结合图片使用更佳
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 1 << 30
using namespace std;
int n, m, s, t;
int tot = 1, head[305], ver[400010], nxt[400010], edge[400010];
int d[305], now[305], side[305];
queue<int> q;
void add(int x, int y, int z){
ver[++tot] = y;edge[tot] = z;
nxt[tot] = head[x];head[x] = tot;
ver[++tot] = x;edge[tot] = 0;
nxt[tot] = head[y];head[y] = tot;
}
bool bfs(){
memset(d, 0, sizeof d);
while(q.size())q.pop();
d[s] = 1;now[s] = head[s];
q.push(s);
while(q.size()){
int x = q.front();q.pop();
for(int i=head[x];i;i=nxt[i]){
int y = ver[i];
int z = edge[i];
if(z && !d[y]){
q.push(y);
now[y] = head[y];
d[y] = d[x] + 1;
if(y == t)return 1;
}
}
}
return 0;
}
int dinic(int x, int flow){
if(x == t)return flow;
int res = flow, k, i;
for(i = now[x];i&&res;i=nxt[i]){
int y = ver[i];
int z = edge[i];
if(z && d[y] == d[x] + 1){
k = dinic(y, min(res, z));
if(!k)d[y] = 0;
edge[i] -= k;
edge[i^1] += k;
res -= k;
}
}
now[x] = i;
return flow - res;
}
int main(){
scanf("%d%d", &n, &m);
s = n + 1;t = n + 2;
for(int i=1;i<=n;i++){
scanf("%d", &side[i]);
if(side[i])add(s, i, 1);
else add(i, t, 1);
}
for(int i=1;i<=m;i++){
int x, y;
scanf("%d%d", &x, &y);
if(side[x] == side[y])continue;
if(side[x])add(x, y, 1);
else add(y, x, 1);
}
int ans = 0, flow;
while(bfs())
while(flow = dinic(s, inf))
ans += flow;
printf("%d\n", ans);
return 0;
}