网络流复习?预习!
由于我的网络流水平实在令人捧腹,所以今天该复习网络流了
算法
只准备弄下Dinic
Dinic最大流
1.处理出层次图
2.在层次图上dfs出最大流
3.将刚刚处理出的最大流叠加到答案中
4.直到建不出层次图为止
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define mkp make_pair
typedef unsigned long long ull;
typedef long long ll;
const int N = 200 + 5;
const int M = 5000 + 5;
constexpr ll INF = 1ll << 60ll;
constexpr int P = 1e9 + 7;
#define typ ll
#define writesp(x) write(x) , putchar(32)
#define writeln(x) write(x) , putchar(10)
inline char gc() {
static char buf[100000] , *p1 = buf , *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;
}
#define getc gc // ------>>>REMEMBER<<<------
inline typ read(){
typ x = 0; bool f = 0;
char ch = getc();
while(!isdigit(ch)){
f |= (ch == '-');
ch = getc();
}
while(isdigit(ch)){
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getc();
}
return (f ? -x : x);
}
inline void write(typ x){
if(x < 0) putchar('-') , x = -x;
if(x / 10) write(x / 10);
putchar(x % 10 ^ 48);
}
int n , m;
struct DINIC {
int s , t;
struct edge {
int to , nxt;
ll flow;
}e[M << 1];
int head[N] , cnt = 1;
void adde(int u , int v , ll flow){
e[ ++ cnt] = {v , head[u] , flow};
head[u] = cnt;
e[ ++ cnt] = {u , head[v] , 0};
head[v] = cnt;
}
int dis[N] , now[N];
int bfs(){
memset(dis , 0 , sizeof dis);
queue<int> q;
q.push(s); dis[s] = 1;
while(!q.empty()){
int u = q.front(); q.pop();
now[u] = head[u];
for(int i = head[u]; i; i = e[i].nxt){
int v = e[i].to , fl = e[i].flow;
if(fl && !dis[v]){
dis[v] = dis[u] + 1;
q.push(v);
}
}
}
return dis[t] != 0;
}
ll dfs(int u , ll flow){//进入时有多少流量
if(u == t) return flow;
ll rst = flow;
for(int i = now[u]; i && rst; i = e[i].nxt){
now[u] = i;
int v = e[i].to; ll fl = e[i].flow;
if(fl && dis[v] == dis[u] + 1){
ll cur = dfs(v , min(fl , rst));
// if(!cur) dis[v] = 0;
e[i].flow -= cur;
e[i ^ 1].flow += cur;
rst -= cur;
}
}
return flow - rst;//初始减剩下即为delta
}
ll Dinic(){
ll res = 0;
while(bfs()){
// for(int i = 1; i <= n; ++ i) now[i] = head[i];
// cout << res << endl;
res += dfs(s , INF);
}
return res;
}
}D;
signed main(){
n = read() , m = read();
D.s = read() , D.t = read();
for(int i = 1; i <= m; ++ i){
int u = read() , v = read() , fl = read();
D.adde(u , v , fl);
}
ll ans = D.Dinic();
writeln(ans);
return 0;
}
地震逃生
板子
酒店之王
板子,房->人->菜
Exploration plan
二分答案
s->有团队的点->时间限制内能走到的点->t
记得有重边,卡了我好久md
[CTSC1999] 家园 / 星际转移问题
按时间拆点