关于此题当前弧优化
查看原帖
关于此题当前弧优化
661135
Mr_Gengar楼主2025/1/18 20:46

rt,我的dinic加入当前弧优化 TLE70,但是删除后成功ac且跑得飞快。

有当前弧:

// Dinic
#include<bits/stdc++.h>
using namespace std;
using LL = int;

const int kMaxN = 201, kMaxM = 2e5 + 1;

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};

LL n, m, s, t, d, ans, dep[kMaxM], cur[kMaxM], a[kMaxN][kMaxN];
LL tot = 1, head[kMaxM], to[kMaxM], nxt[kMaxM], c[kMaxM];

void add(int u, int v, LL w) {
  to[++tot] = v, c[tot] = w, nxt[tot] = head[u], head[u] = tot;
  to[++tot] = u, c[tot] = 0, nxt[tot] = head[v], head[v] = tot;
}

bool bfs() {
	queue<int> q;
	fill(dep, dep + n * m + 2, 0);
	dep[s] = 1, q.push(s);
	while(!q.empty()) {
		int u = q.front();
		cur[u] = head[u], q.pop();
		for(int i = head[u]; i; i = nxt[i]) {
			int v = to[i];
			if(c[i] && !dep[v]) {
				q.push(v), dep[v] = dep[u] + 1;
				if(v == t) return 1;
			}
		}
	}
	return 0;
}

LL dinic(int u, LL flow) {
	if(u == t) return flow;
	LL rest = flow;
	for(int i = cur[u], v; i && rest; i = nxt[i]) {
		v = to[i], cur[u] = i;
		if(c[i] && dep[v] == dep[u] + 1) {
			LL inc = dinic(v, min(rest, c[i]));
			if(!inc) dep[v] = 0;
			c[i] -= inc, c[i ^ 1] += inc, rest -= inc;
		}
	}
	return flow - rest;
}

int id(int i, int j) {
	return (i - 1) * m + j;
}

LL dis(LL xa, LL ya, LL xb, LL yb) {
	return (xa - xb) * (xa - xb) + (ya - yb) * (ya - yb);
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> m;
	t = n * m + 1;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			cin >> a[i][j];
		}
	}
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			if(a[i][j] == 2) {
				add(id(i, j), t, 1e9);
			} else if(a[i][j] == 1) {
				add(s, id(i, j), 1e9);
			}
			for(int k = 0; k < 4; k++) {
				int px = i + dx[k], py = j + dy[k];
				if(px < 1 || py < 1 || px > n || py > m) continue;
				add(id(i, j), id(px, py), 1);
			}
		}
	}
	while(bfs()) ans += dinic(s, 1e9);
	cout << ans;
	return 0;
}

提交记录:https://www.luogu.com.cn/record/199067647

没当前弧:

// Dinic
#include<bits/stdc++.h>
using namespace std;
using LL = int;

const int kMaxN = 201, kMaxM = 2e5 + 1;

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};

LL n, m, s, t, d, ans, dep[kMaxM], cur[kMaxM], a[kMaxN][kMaxN];
LL tot = 1, head[kMaxM], to[kMaxM], nxt[kMaxM], c[kMaxM];

void add(int u, int v, LL w) {
  to[++tot] = v, c[tot] = w, nxt[tot] = head[u], head[u] = tot;
  to[++tot] = u, c[tot] = 0, nxt[tot] = head[v], head[v] = tot;
}

bool bfs() {
	queue<int> q;
	fill(dep, dep + n * m + 2, 0);
//	memset(dep, 0, sizeof dep);
	dep[s] = 1, q.push(s);
	for(int u = s; !q.empty(); q.pop(), u = q.front()) {
		for(int i = head[u]; i; i = nxt[i]) {
			int v = to[i];
			if(c[i] && !dep[v]) {
				q.push(v), dep[v] = dep[u] + 1;
				if(v == t) return 1;
			}
		}
	}
	return 0;
}

int dinic(int u, int flow) {
	if(u == t) return flow;
	int rest = flow;
	for(int i = head[u]; i && rest; i = nxt[i]) {
		int v = to[i];
		if(c[i] && dep[v] == dep[u] + 1) {
			int inc = dinic(v, min(rest, c[i]));
			if(!inc) dep[v] = 0;
			c[i] -= inc, c[i ^ 1] += inc, rest -= inc;
		}
	}
	return flow - rest;
}

int id(int i, int j) {
	return (i - 1) * m + j;
}

LL dis(LL xa, LL ya, LL xb, LL yb) {
	return (xa - xb) * (xa - xb) + (ya - yb) * (ya - yb);
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> m;
	t = n * m + 1;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			cin >> a[i][j];
		}
	}
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			if(a[i][j] == 2) {
				add(id(i, j), t, 1e9);
			} else if(a[i][j] == 1) {
				add(s, id(i, j), 1e9);
			}
			for(int k = 0; k < 4; k++) {
				int px = i + dx[k], py = j + dy[k];
				if(px < 1 || py < 1 || px > n || py > m) continue;
				add(id(i, j), id(px, py), 1);
			}
		}
	}
	while(bfs()) ans += dinic(s, 1e9);
	cout << ans;
	return 0;
}

提交记录:https://www.luogu.com.cn/record/199068410

马蜂略丑(因为是板子copy过来改的),有没有巨佬可以给我解释为什么会有这样的情况......

2025/1/18 20:46
加载中...