QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#484804#9102. Zayin and ElementsPetroTarnavskyiAC ✓32ms3924kbC++203.3kb2024-07-20 00:24:132024-07-20 00:24:13

Judging History

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

  • [2024-07-20 00:24:13]
  • 评测
  • 测评结果:AC
  • 用时:32ms
  • 内存:3924kb
  • [2024-07-20 00:24: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 = 1e18;

struct Graph
{
	struct Edge
	{
		int from, to;
		LL cap, flow;
	};
	int n;
	vector<Edge> edges;
	vector<VI> g;
	VI d, p;
	void init(int _n)
	{
		n = _n;
		edges.clear();
		g.clear();
		g.resize(n);
		d.resize(n);
		p.resize(n);
	}
	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});
	}
	int bfs(int s, int t)
	{
		fill(ALL(d), -1);
		d[s] = 0;
		queue<int> q;
		q.push(s);
		while (!q.empty())
		{
			int v = q.front();
			q.pop();
			for (int e : g[v])
			{
				int to = edges[e].to;
				if (edges[e].flow < edges[e].cap && d[to] == -1)
				{
					d[to] = d[v] + 1;
					q.push(to);
				}
			}
		}
		return d[t];
	}
	LL dfs(int v, int t, LL flow)
	{
		if (v == t || flow == 0)
			return flow;
		for (; p[v] < SZ(g[v]); p[v]++)
		{
			int e = g[v][p[v]], to = edges[e].to;
			LL c = edges[e].cap, f = edges[e].flow;
			if (f < c && (to == t || d[to] == d[v] + 1))
			{
				LL push = dfs(to, t, min(flow, c - f));
				if (push > 0)
				{
					edges[e].flow += push;
					edges[e ^ 1].flow -= push;
					return push;
				}
			}
		}
		return 0;
	}
	LL flow(int s, int t)
	{
		assert(0 <= s && s < n);
		assert(0 <= t && t < n);
		assert(s != t);
		LL flow = 0;
		while (bfs(s, t) != -1)
		{
			fill(ALL(p), 0);
			while (true)
			{
				LL f = dfs(s, t, LINF);
				if (f == 0)
					break;
				flow += f;
			}
		}
		return flow;
	}
};

int Flow(int n, int m, const VI& a, const vector<VI>& g)
{
	Graph G;
	G.init(n + m + 2);
	int s = n + m;
	int t = s + 1;
	FOR (i, 0, m)
	{
		G.addEdge(s, i, a[i]);
		for (int to : g[i])
			G.addEdge(i, to + m, 1);
	}
	FOR (i, 0, n)
		G.addEdge(i + m, t, 1);
	return G.flow(s, t);
}

void solve()
{
	int n, m;
	cin >> n >> m;
	VI a(m), b(m), c(m);
	vector<VI> g(m);
	int res = 0;
	FOR(i, 0, m)
	{
		cin >> a[i] >> b[i] >> c[i];
		res += b[i] + c[i];
		b[i] *= 2;
		int t;
		cin >> t;
		g[i].resize(t);
		for (int& x : g[i])
		{
			cin >> x;
			x--;
		}
	}
	FOR (i, 0, m)
		a[i] += b[i] + c[i];
	if (Flow(n, m, a, g) != n)
	{
		cout << "-1\n";
		return;
	}
	FOR(i, 0, m)
		a[i] -= b[i] + c[i];
	VI vec(m);
	iota(ALL(vec), 0);
	mt19937 rng;
	VI sa = a, sb = b;
	int maxAns = 0;
	FOR(it, 0, 20)
	{
		a = sa;
		b = sb;
		shuffle(ALL(vec), rng);
		int ans = 0;
		int f = Flow(n, m, a, g);
		for (int i : vec)
		{
			a[i] += b[i];
			int nf = Flow(n, m, a, g);
			int x = nf - f;
			x -= x % 2;
			a[i] -= b[i];
			a[i] += x;
			b[i] -= x;
			f += x;
			ans += x / 2;
		}
		ans += n - f;
		maxAns = max(maxAns, res - ans);
	}
	cout << maxAns << '\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: 0ms
memory: 3540kb

input:

2
5
2
2 3 1 2 3 1
1 1 1 3 4 5 2
5
2
2 3 1 1 3
1 0 1 2 1 2

output:

5
-1

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 32ms
memory: 3924kb

input:

5
9
10
0 0 10 2 3 8
0 0 10 2 4 6
0 8 2 2 2 4
0 0 10 3 1 3 8
0 4 6 2 2 3
0 8 2 3 2 6 7
0 9 1 2 1 7
0 2 8 3 1 4 9
0 7 3 1 5
0 0 10 3 5 6 9
3
10
0 9 1 1 2
0 5 5 1 1
0 1 9 1 1
0 7 3 1 1
0 7 3 0
0 0 10 0
0 6 4 1 3
0 9 1 0
0 7 3 0
0 9 1 1 2
90
20
0 6 4 12 1 4 5 22 32 64 66 67 73 87 88 89
0 1 9 12 3 8 21 3...

output:

94
97
155
151
152

result:

ok 5 lines