常州 d??
回来了!
今天(?发出来的时候可能已经是第二天了吧
真的爆零了qaq
挺难的 最高分只有100 而且t2t3t4一个人都没拿分qaq
这段时间在写网络流 唉博客还是不要写太水了 抄一点网络流代码上来
EK不写了 dinic会就行了
板子题洛谷p3376
dinic做法
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 210, M = 1e4+10;
int n, m, s, t, tot = 1, ver[M], h[N], nxt[M], edg[M], d[N], now[N], fl, inf = 0x7fffffff, maxf;
queue < int > q, clr;
void add(int u, int v, int w){
ver[++tot] = v; edg[tot] = w, nxt[tot] = h[u];
h[u] = tot;
ver[++tot] = u; edg[tot] = 0, nxt[tot] = h[v];
h[v] = tot;
}
bool bfs(){
memset(d, 0, sizeof d); q = clr;
q.push(s); d[s] = 1, now[s] = h[s];
while (q.size()){
int x = q.front(); q.pop();
for (int i = h[x]; i; i = nxt[i]){
if (!edg[i] || d[ver[i]]) continue;
q.push(ver[i]);
now[ver[i]] = h[ver[i]];
d[ver[i]] = d[x] + 1;
if (ver[i] == t) return true;
}
}
return false;
}
int dinic(int x, int flw){
if (x == t) return flw;
int rst = flw;
for (int i = now[x]; i; i = nxt[i]){
now[x] = i;
if (!edg[i] || d[ver[i]] != d[x] + 1) continue;
int k = dinic(ver[i], min(rst, edg[i]));
if (!k) d[ver[i]] = 0;
edg[i] -= k; edg[i ^ 1] += k;
rst -= k;
}
return flw - rst;
}
signed main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m >> s >> t;
for (int i = 1; i <= m; ++i){
int u, v, w; cin >> u >> v >> w;
add(u, v, w);
}
while (bfs()) while (fl = dinic(s, inf)) maxf += fl;
cout << maxf << "\n";
return 0;
}
dinic优化ISAP做法
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 210, M = 1e4+10;
int n, m, s, t, tot = 1, ver[M], h[N], nxt[M], edg[M], dep[N], gap[N], maxf, inf = 0x7fffffff, cur[N];
queue < int > q;
void add(int u, int v, int w){
ver[++tot] = v; nxt[tot] = h[u], edg[tot] = w;
h[u] = tot;
ver[++tot] = u; nxt[tot] = h[v], edg[tot] = 0;
h[v] = tot;
}
void bfs(){
memset(dep, -1, sizeof(dep));
q.push(t); gap[dep[t] = 0] = 1;
while (!q.empty()){
int x = q.front(); q.pop();
for (int i = h[x]; i; i = nxt[i]){
if (dep[ver[i]] != -1) continue;
q.push(ver[i]); dep[ver[i]] = dep[x] + 1;
++gap[dep[ver[i]]];
}
}
}
int dfs(int x, int flw){
if (x == t) return flw;
int rst = flw;
for (int i = cur[x]; i; i = nxt[i]){
cur[x] = i;
if (!edg[i] || dep[ver[i]] != dep[x] - 1) continue;
int k = dfs(ver[i], min(rst, edg[i]));
edg[i] -= k, edg[i ^ 1] += k;
rst -= k;
if (!rst) return flw;
}
--gap[dep[x]];
if (!gap[dep[x]]) dep[s] = n + 1;
++gap[++dep[x]];
return flw - rst;
}
int isap(){
bfs();
while (dep[s] < n){
memcpy(cur, h, sizeof(cur));
maxf += dfs(s, inf);
}
return maxf;
}
signed main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m >> s >> t;
for (int i = 1; i <= m; ++i){
int u, v, w; cin >> u >> v >> w;
add(u, v, w);
}
cout << isap() << "\n";
return 0;
}
费用流板子题洛谷p3381
dinic+spfa
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N = 5010, M = 200010, inf = 0x3f3f3f3f;
int m, n, k, tot = 1, h[N], ver[M], nxt[M], edg[M], cst[M], dis[N], cur[N], s, t, ans, maxf, fl;
bool vis[N], v[N];
queue < int > q, clr;
void add(int u, int v, int w, int c){
ver[++tot] = v; nxt[tot] = h[u], edg[tot] = w, cst[tot] = c;
h[u] = tot;
ver[++tot] = u; nxt[tot] = h[v], edg[tot] = 0, cst[tot] = -c;
h[v] = tot;
}
bool spfa(){
q = clr;
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof vis);
q.push(s); dis[s] = 0, vis[s] = 1;
while (q.size()){
int x = q.front(); q.pop(); vis[x] = 0;
for (int i = h[x]; i; i = nxt[i]){
if (!edg[i] || dis[ver[i]] <= dis[x] + cst[i]) continue;
dis[ver[i]] = dis[x] + cst[i];
if (!vis[ver[i]]) vis[ver[i]] = 1, q.push(ver[i]);
}
}
return dis[t] != inf;
}
int dinic(int x, int flw){
v[x] = 1;
if (x == t) return flw;
int rst = flw;
for (int i = cur[x]; i; i = nxt[i]){
cur[x] = i;
if (!edg[i] || dis[ver[i]] != dis[x] + cst[i] || v[ver[i]]) continue;
v[ver[i]] = 1;
int k = dinic(ver[i], min(rst, edg[i]));
edg[i] -= k, edg[i ^ 1] += k;
rst -= k; ans += k * cst[i];
}
return flw - rst;
}
signed main() {
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m >> s >> t;
for (int i = 1; i <= m; ++i){
int u, v, w, c; cin >> u >> v >> w >> c;
add(u, v, w, c);
}
while (spfa()){
memcpy(cur, h, sizeof(h));
memset(v, 0, sizeof(v));
while ((fl = dinic(s, inf)) > 0) maxf += fl;
}
cout << maxf << " " << ans << "\n";
return 0;
}
其他一些例题 不放代码了
洛谷p4452
洛谷p2053
洛谷p2045
如果有可能说不定到时候会写网络流学习笔记...?(大概率是不可能的