前置-重贴标签算法的问题
查看原帖
前置-重贴标签算法的问题
98555
徐一凡楼主2022/4/19 20:45
#include<iostream>
#include<vector>
#include<list>

using namespace std;

constexpr long long inf = 1000000000000000000ll;
constexpr int iinf = 1000000000;

void push(vector<vector<long long>>& remnant,
          vector<long long>& preflow, int i, int j)
{
	long long amount = min(remnant[i][j], preflow[i]);
	remnant[i][j] -= amount;
	remnant[j][i] += amount;
	preflow[i] -= amount;
	preflow[j] += amount;
}

void discharge(vector<vector<long long>>& remnant,
               vector<long long>& preflow,
               vector<int>& label,
               vector<int>& current, int i)
{
	int n = remnant.size();
	
	while (preflow[i] > 0)
	{
		if (current[i] == n)
		{
			current[i] = 0;
			int min_label = iinf;
			
			for (int j = 0; j < n; ++j)
			{
				if (remnant[i][j] > 0)
				{
					min_label = min(min_label, label[j]);
				}
			}
			
			label[i] = min_label + 1;
		}
		else
		{
			if (label[current[i]] == label[i] - 1 and remnant[i][current[i]] > 0)
			{
				push(remnant, preflow, i, current[i]);
			}
			
			++current[i];
		}
	}
}

long long relable_to_front(const vector<vector<int>>& g, int s, int t)
{
	int n = g.size();
	vector<vector<long long>> remnant(n, vector<long long>(n));
	vector<long long> preflow(n);
	vector<int> label(n), current(n);
	
	preflow[s] = inf;
	label[s] = n;
	
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			remnant[i][j] = g[i][j];
		}
	}
	
	for (int i = 0; i < n; ++i)
	{
		push(remnant, preflow, s, i);
	}
	
	list<int> l;
	
	for (int i = 0; i < n; ++i)
	{
		if (i != s and i != t)
		{
			l.push_back(i);
		}
	}
	
	list<int>::iterator it = l.begin();
	
	while (it != l.end())
	{
		int old_label = label[*it];
		
		discharge(remnant, preflow, label, current, *it);
		
		if (label[*it] > old_label)
		{
			l.splice(l.begin(), l, it);
		}
		
		++it;
	}
	
	return preflow[t];
}

int main()
{
	int n, m, s, t;
	cin >> n >> m >> s >> t;
	--s, --t;
	
	vector<vector<int>> g(n, vector<int>(n));
	
	for (int i = 0; i < m; ++i)
	{
		int x, y, v;
		cin >> x >> y >> v;
		--x, --y;
		
		g[x][y] = v;
	}
	
	long long ans = relable_to_front(g, s, t);
	
	cout << ans << "\n";
	return 0;
}

#8 #9 #10 过不了。有可能是没考虑反向边,但是没有反向边的 #9 也没过。

2022/4/19 20:45
加载中...