QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#624764 | #9102. Zayin and Elements | FDUdululu | AC ✓ | 1ms | 3736kb | C++20 | 4.0kb | 2024-10-09 16:35:22 | 2024-10-09 16:35:22 |
Judging History
answer
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const ll inf = 1e15 + 7;
const int N = 125;
struct Graph {
int n;
struct Edge {
int v, nxt;
ll cap, flow;
int b;
};
vector<Edge> e;
int S, T;
int vis[N];
int fir[N], tot;
ll dis[N], incf[N], pre[N];
queue<int> q;
ll flow, ans;
void init() {
memset(fir, -1, sizeof fir);
e.clear();
flow = ans = tot = 0;
}
void add(int u, int v, ll w, int b) {
e.push_back({v, fir[u], w, 0, b});
fir[u] = tot++;
e.push_back({u, fir[v], 0, 0, b}); // -cost
fir[v] = tot++;
}
bool BFS(int s) {
while (!q.empty())
q.pop();
for (int i = 0; i <= n; i++)
dis[i] = inf, incf[i] = 0, vis[i] = 0;
dis[s] = 0, vis[s] = 1, incf[s] = inf;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = fir[u]; ~i; i = e[i].nxt) {
int v = e[i].v;
if ((!vis[v]) && (s == S | (v != S && v != T)) && (dis[v] > dis[u] + 1) && (e[i].cap > e[i].flow)) {
dis[v] = dis[u] + 1;
incf[v] = min(incf[u], e[i].cap - e[i].flow);
pre[v] = i;
q.push(v), vis[v] = 1;
}
}
}
return dis[T] != dis[0];
}
int update() {
flow += incf[T];
int last;
for (int u = T; u != S; u = e[pre[u] ^ 1].v) {
e[pre[u]].flow += incf[T];
e[pre[u] ^ 1].flow -= incf[T];
ans += 1 * incf[T];
if (e[pre[u] ^ 1].v == S)
last = u;
}
return last;
}
void EK() {
while (BFS(S))
update();
}
int adjust(int m) {
int ans = 0;
vector<int> odd(m + 1, 0);
for (int i = fir[S]; ~i; i = e[i].nxt) {
if (!e[i].b)
continue;
ans += e[i].flow / 2;
if (e[i].flow & 1) {
ans++;
odd[e[i].v] = 1;
}
}
for (int i = 1; i <= m; i++) {
if (!odd[i])
continue;
BFS(i);
for (int j = 1; j <= m; j++) {
if (i == j || (!odd[j]))
continue;
if (dis[j] == dis[0])
continue;
ans--;
odd[i] = odd[j] = 0;
break;
}
}
return ans;
}
} g;
int n, m;
int a[N], b[N], c[N], cnt[N];
vector<int> son[N];
int tot, ans;
void solve() {
cin >> n >> m;
tot = ans = 0;
for (int i = 1; i <= m; i++)
son[i].clear(), cnt[i] = 0;
for (int i = 1; i <= m; i++) {
cin >> a[i] >> b[i] >> c[i];
int x, y;
cin >> x;
for (int j = 1; j <= x; j++) {
cin >> y;
son[i].push_back(y);
}
tot += (b[i] + c[i]);
}
g.n = n + m + 2;
g.S = n + m + 1, g.T = n + m + 2;
g.init();
for (int i = 1; i <= n; i++)
g.add(m + i, g.T, 1, 0);
for (int i = 1; i <= m; i++)
g.add(g.S, i, a[i], 0);
for (int i = 1; i <= m; i++) {
for (auto x : son[i])
g.add(i, m + x, 1, 0);
}
// a
g.EK();
// b
for (int i = 1; i <= m; i++)
g.add(g.S, i, b[i] * 2, 1);
g.EK();
ans += g.adjust(m);
// c
int flow = g.flow;
for (int i = 1; i <= m; i++)
g.add(g.S, i, c[i], 0);
g.EK();
if (g.flow < n) {
cout << "-1\n";
return;
}
ans += g.flow - flow;
cout << tot - ans << "\n";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3508kb
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: 1ms
memory: 3736kb
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