QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#416660#4775. Pool constructionmshcherbaAC ✓106ms5084kbC++204.0kb2024-05-22 01:39:132024-05-22 01:39:14

Judging History

你现在查看的是最新测评结果

  • [2024-05-22 01:39:14]
  • 评测
  • 测评结果:AC
  • 用时:106ms
  • 内存:5084kb
  • [2024-05-22 01:39:13]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;

const LL LINF = 1e9;

struct Graph
{
	struct Edge
	{
		int from, to;
		LL cap, flow;
	};
	int n;
	vector<Edge> edges;
	vector<VI> g;
	vector<LL> e;
	VI h, current;
	priority_queue<PII> overflowing;
	VI d;
	void init(int _n)
	{
		n = _n;
		edges.clear();
		g.clear();
		g.resize(n);
		e.assign(n, 0);
		h.assign(n, 0);
		current.assign(n, 0);
	}
	void addEdge(int from, int to, LL cap)
	{
		assert(0 <= from && from < n);
		assert(0 <= to && to < n);
		assert(0 <= cap);
		g[from].PB(SZ(edges));
		edges.PB({from, to, cap, 0});
		g[to].PB(SZ(edges));
		edges.PB({to, from, 0, 0});
	}
	void push(int i)
	{
		Edge& edge = edges[i];
		int delta = min(e[edge.from], edge.cap - edge.flow);
		edge.flow += delta;
		edges[i ^ 1].flow -= delta;
		e[edge.from] -= delta;
		if (e[edge.to] == 0)
			overflowing.push({h[edge.to], edge.to});
		e[edge.to] += delta;
	}
	void relabel(int u)
	{
		h[u] = 4 * n + 47;
		for (int i : g[u])
		{
			const Edge& edge = edges[i];
			if (edge.flow < edge.cap)
				h[u] = min(h[u], h[edge.to] + 1);
		}
	}
	void discharge(int u)
	{
		while (e[u] > 0)
		{
			for (; e[u] > 0 && current[u] < SZ(g[u]); current[u]++)
			{
				int i = g[u][current[u]];
				const Edge& edge = edges[i];
				if (edge.flow < edge.cap && h[u] == h[edge.to] + 1)
					push(i);
			}
			if (e[u] > 0)
			{
				relabel(u);
				current[u] = 0;
			}
		}
	}
	void globalRelabel(int t)
	{
		d.assign(n, n);
		d[t] = 0;
		queue<int> q;
		q.push(t);
		while (!q.empty())
		{
			int u = q.front();
			q.pop();
			for (int i : g[u])
			{
				const Edge& edge = edges[i ^ 1];
				if (edge.flow == edge.cap)
					continue;
				int to = edge.from;
				if (d[to] == n)
				{
					d[to] = d[u] + 1;
					q.push(to);
				}
			}
		}
		FOR(u, 0, n)
		{
			h[u] = max(h[u], d[u]);
		}
	}
	void initializePreflow(int s)
	{
		for (int i : g[s])
		{
			Edge& edge = edges[i];
			if (edge.cap > 0)
			{
				edge.flow = edge.cap;
				edges[i ^ 1].flow = -edge.cap;
				e[edge.to] += edge.cap;
				e[s] -= edge.cap;
			}
		}
	}
	LL flow(int s, int t)
	{
		assert(0 <= s && s < n);
		assert(0 <= t && t < n);
		assert(s != t);
		initializePreflow(s);
		globalRelabel(t);
		assert(h[s] == n);
		for (const Edge& edge : edges)
		{
			if (edge.flow < edge.cap)
			{
				assert(h[edge.from] <= h[edge.to] + 1);
			}
		}
		FOR(u, 0, n)
		{
			if (e[u] > 0)
				overflowing.push({h[u], u});
		}
		while (!overflowing.empty())
		{
			int u = overflowing.top().S;
			overflowing.pop();
			if (u != t)
				discharge(u);
		}
		return e[t];
	}
};

void solve()
{
	int n, m;
	cin >> m >> n;
	
	int d, f, b;
	cin >> d >> f >> b;
	
	Graph F;
	F.init(n * m + 2);
	
	int S = n * m;
	int T = n * m + 1;
	
	int ans = 0;
	FOR(i, 0, n)
	{
		string s;
		cin >> s;
		FOR(j, 0, m)
		{
			int valT = 0;
			if(s[j] == '.')
				valT = f;
			
			
			int valF = 0;
			if(s[j] == '#')
				valF = d;
			
			if(i % (n - 1) == 0 || j % (m - 1) == 0)
				valF = LINF;
			
			
			if(valT <= valF)
			{
				ans += valT;
				F.addEdge(S, i * m + j, valF - valT);
			}
			else
			{
				ans += valF;
				F.addEdge(i * m + j, T, valT - valF);
			}
		
		
			
			if(i != n - 1)
			{
				F.addEdge(i * m + j, (i + 1) * m + j, b);
				F.addEdge((i + 1) * m + j, i * m + j, b);
			}
			if(j != m - 1)
			{
				F.addEdge(i * m + j, i * m + j + 1, b);
				F.addEdge(i * m + j + 1, i * m + j, b);
			}
		}
	}
	cout << ans + F.flow(S, T) << "\n";
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	int t;
	cin >> t;
	while(t--)
		solve();
	
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3520kb

input:

3
3 3
5 5 1
#.#
#.#
###
5 4
1 8 1
#..##
##.##
#.#.#
#####
2 2
27 11 11
#.
.#

output:

9
27
22

result:

ok 3 lines

Test #2:

score: 0
Accepted
time: 106ms
memory: 5084kb

input:

56
3 3
5 5 1
#.#
#.#
###
5 4
1 8 1
#..##
##.##
#.#.#
#####
2 2
1 1 1
##
##
2 2
1 10000 1
..
..
5 4
20 41 9
#####
##.##
#.#.#
#####
5 4
20 41 10
#####
##.##
#.#.#
#####
5 4
20 41 11
#####
##.##
#.#.#
#####
5 4
20 39 10
#####
##.##
#.#.#
#####
3 3
9760 9015 711
.#.
#.#
###
5 5
7415 7931 2080
.....
#.....

output:

9
27
0
40000
108
120
123
117
20874
100110
112364
203900
271440
462119
490330
1746528
1067774
1055196
2609818
2094932
5199902
13978
73960
99018
262976
224632
78984
167795
392774
649054
1232290
135876
318982
413042
1479538
1680354
349557
540100
2101110
335884
2245998
170698
780013
1804351
2998519
3661...

result:

ok 56 lines