最大流,反复跑流
题意:
分析:
这题我不会,是看人题解后做的。汗
这题有两个收获:
1.网络流建无向图。
void add(int from, int to, int cap) {
E[cnt].to = to;
E[cnt].cap = cap;
E[cnt].rev = cnt + 1;
E[cnt].next = head[from];
head[from] = cnt++;
E[cnt].to = from;
E[cnt].cap = cap; //有向图 为 0
E[cnt].rev = cnt - 1;
E[cnt].next = head[to];
head[to] = cnt++;
}2.反复跑图:
为什么先跑一遍a1,a1 到 b1,b2
然后再交换一下b1,b2就可以了呢?
推荐这篇博客:https://www.cnblogs.com/chenyushuo/p/5139556.html
代码如下,面向结果编程:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int inf = 2e9;
const int max_n = 55;
const int max_m = max_n * max_n;
int n, m;
char ma[max_n][max_n];
struct edge
{
int to, cap, rev, next;
}E[max_m * 2];
int head[max_n * 2];
int cnt = 1;
void add(int from, int to, int cap) {
E[cnt].to = to;
E[cnt].cap = cap;
E[cnt].rev = cnt + 1;
E[cnt].next = head[from];
head[from] = cnt++;
E[cnt].to = from;
E[cnt].cap = cap; //有向图 为 0
E[cnt].rev = cnt - 1;
E[cnt].next = head[to];
head[to] = cnt++;
}
void init() {
fill(head, head + n + 10, false);
cnt = 1;
for (int i = 1;i <= n;i++)
for (int j = 1;j < i;j++)
if (ma[i][j] == 'O')add(i, j, 2);
else if (ma[i][j] == 'N') add(i, j, inf);
}
int iter[max_n * 2];
int dist[max_n * 2];
bool searchpath(int s, int t) {
fill(dist, dist + max_n * 2, -1);
queue<int> que;dist[s] = 0;
que.push(s);
while (!que.empty()) {
int u = que.front();que.pop();
for (int i = head[u];i;i = E[i].next) {
edge& e = E[i];
if (dist[e.to] != -1 || e.cap == 0)continue;
dist[e.to] = dist[u] + 1;
que.push(e.to);
}
}return dist[t] != -1;
}
int matchpath(int u, int t, int f) {
if (u == t)return f;
for (int& i = iter[u];i;i = E[i].next) {
edge& e = E[i];
if (dist[e.to] <= dist[u] || e.cap <= 0)continue;
int d = matchpath(e.to, t, min(e.cap, f));
if (d > 0) {
e.cap -= d;
E[e.rev].cap += d;
return d;
}
}return false;
}
int dinic(int s, int t) {
int flow = 0;int f;
while (searchpath(s, t)) {
for (int i = 1;i < max_n * 2;i++)iter[i] = head[i];
while (f = matchpath(s, t, inf))
flow += f;
}return flow;
}
int main() {
ios::sync_with_stdio(0);
int a1, a2, b1, b2, an, bn;
while (cin >> n >> a1 >> a2 >> an >> b1 >> b2 >> bn) {
a1++;a2++;b1++;b2++;an <<= 1;bn <<= 1;
int start = n + 1;int ed = start + 1;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)
cin >> ma[i][j];
init();
add(start, a1, an);add(start, b1, bn);
add(a2, ed, an);add(b2, ed, bn);
if (dinic(start, ed) != an + bn)cout << "No\n";
else {
init();
add(start, a1, an);add(a2, ed, an);
add(start, b2, bn);add(b1, ed, bn);
if (dinic(start, ed) == an + bn)cout << "Yes\n";
else cout << "No\n";
}
}
}
京公网安备 11010502036488号