有上下界的网络流

补坑。。。

上下界网络流

主要分为以下的四类

  1. 无源无汇有上下界的网络流(判断是否有可行流)
  2. 有源有汇有上下界的网络流(判断是否有可行流)
  3. 有源有汇有上下界的网络流的最大流
  4. 有源有汇有上下界的网络流的最小流

注意第一种的图必须是存在环形的,一开始一直不理解,这种图必须存在循环流!!
他们的建模的方式网上资料也比较的全,
已经完成了loj上面的三道模板题了。

有源有汇的有上下界的网络流

link
很裸的一道题,但是我没有学过啊

ac code

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
94
95
96
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
const int maxn = 4010;
const int INF = 1e9+10;
struct Edge{
int to, cap, rev;
};
vector<Edge> G[maxn];
int cnt[maxn];
int level[maxn];
int s, t;
int n, m, k;
int l, r;
void add_edge(int u, int v, int cap){
G[u].push_back(Edge{v, cap, G[v].size()});
G[v].push_back(Edge{u, 0, G[u].size()-1});
}
void bfs(int s){
memset(level, -1, sizeof(level));
queue<int> q;
q.push(s);
level[s] = 0;
while(!q.empty()){
int v = q.front();
q.pop();
for(int i=0; i<G[v].size(); i++){
Edge& e = G[v][i];
if(e.cap>0&&level[e.to]<0){
level[e.to] = level[v]+1;
q.push(e.to);
}
}
}
}
int dfs(int v, int t, int flow){
if(v == t) return flow;
for(int& i=cnt[v]; i<G[v].size(); i++){
Edge& e = G[v][i];
if(e.cap>0&&level[v]<level[e.to]){
int d = dfs(e.to, t, min(flow, e.cap));
if(d>0){
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;//一旦有一条路径满足就立即返回!
}
}
}
return 0;
}
int max_flow(int s, int t){
int flow = 0;
for(;;){
//构造层次图
bfs(s);
//无法连通终点,结束访问
if(level[t]<0) return flow;
int f;
//cnt数组记录在递归的过程中的边的顺序。
memset(cnt, 0, sizeof(cnt));
//当存在增广路的时候不断的进行增广
while((f = dfs(s, t, INF))>0){
flow+=f;
}
}
}
int d[maxn];
int main()
{
int kase = 1;
while(~scanf("%d%d%d", &n, &m, &k)){
for(int i=0; i<maxn; i++) G[i].clear();
memset(d, 0, sizeof(d));
scanf("%d%d", &l, &r);
int u, v;
int sum = 0;
for(int i=0; i<k; i++){
scanf("%d %d", &u, &v);
add_edge(u, v+n, 1);
}
int ss = 4002;
int tt = 4003;
for(int i=1; i<=n; i++) add_edge(0, i, r-l), add_edge(ss, i, l);
for(int i=1; i<=m; i++) add_edge(i+n, 4001, r-l), add_edge(i+n, tt, l);
add_edge(4001, 0, 1000000);
int ans = max_flow(ss, tt);
//cout<<ans<<endl;
if(ans == n*l)printf("Case %d: Yes\n", kase++);
else printf("Case %d: No\n", kase++);
}
return 0;
}

未解决的问题

文章目录
  1. 1. 上下界网络流
  2. 2. 有源有汇的有上下界的网络流
    1. 2.1. ac code
  3. 3. 未解决的问题
{{ live2d() }}