Loading

网络流复习?预习!

由于我的网络流水平实在令人捧腹,所以今天该复习网络流了

算法

只准备弄下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] 家园 / 星际转移问题

按时间拆点

posted @ 2024-04-02 11:25  TongKa  阅读(6)  评论(1编辑  收藏  举报