QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#505011 | #9102. Zayin and Elements | WorldFinalEscaped | TL | 0ms | 4028kb | C++14 | 3.5kb | 2024-08-04 18:13:35 | 2024-08-04 18:13:35 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 105;
const int M = 100005;
const int inf = 1e6;
struct Edge {
int to, nxt, cap, flow;
ll cost;
} edge[M];
int head[N], tol;
int pre[N];
ll dis[N];
bool vis[N];
int node, n, m;
void add(int u, int v, int cap, ll cost) {
edge[tol] = {v, head[u], cap, 0, cost};
head[u] = tol;
tol++;
}
void addedge(int u, int v, int cap, ll cost) {
// printf("???? u = %d, v = %d, cap = %lld, cost = %lld\n", u, v, cap, cost);
add(u, v, cap, cost);
add(v, u, 0, -cost);
}
bool spfa(int S, int T) {
queue<int> q;
for (int i = 1; i <= node; i++) {
dis[i] = 1e18;
vis[i] = false;
pre[i] = -1;
}
dis[S] = 0, vis[S] = true, q.push(S);
while (!q.empty()) {
int u = q.front(); q.pop();
vis[u] = false;
for (int i = head[u]; i != -1; i = edge[i].nxt) {
int v = edge[i].to;
if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost) {
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!vis[v]) vis[v] = true, q.push(v);
}
}
}
if (pre[T] == -1) return false;
else return true;
}
int mcmf(int S, int T, ll &cost) {
int flow = 0; cost = 0;
while (spfa(S, T)) {
// printf("!!!\n");
int Min = inf;
for (int i = pre[T]; i != -1; i = pre[edge[i ^ 1].to]) {
if (Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
}
// printf("Min = %d\n", Min);
flow += Min;
for (int i = pre[T]; i != -1; i = pre[edge[i ^ 1].to]) {
edge[i].flow += Min;
edge[i ^ 1].flow -= Min;
cost += edge[i].cost * Min;
}
}
return flow;
}
int a[55], b[55], c[55], id[55];
vector<int> to[55];
void sc() {
memset(head, -1, sizeof(head));
tol = 0;
node = 0;
scanf("%d", &n);
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &a[i], &b[i], &c[i]);
int x; scanf("%d", &x);
while (x--) {
int t; scanf("%d", &t);
to[i].push_back(t);
}
id[i] = i;
}
sort(id + 1, id + m + 1, [&](int x, int y) {
int k1 = b[x] % 2 == 0;
int k2 = b[y] % 2 == 0;
return k1 != k2 ? k1 > k2 : x < y;
});
int S = n + m + 1, T = n + m + 2;
for (int i = 1; i <= n; i++) {
addedge(S, i, 1, 0);
}
int cur = 0;
int all = 0;
for (int _ = 1; _ <= m; _++) {
int i = id[_];
all += b[i] + c[i];
// printf("Now i = %d\n", i);
for (auto j: to[i])
addedge(j, n + i, 1, 0);
addedge(i + n, T, a[i], 0);
for (int j = 1; j <= 2 * b[i]; j++) {
++cur;
addedge(i + n, T, 1, cur * inf + (j & 1 ? 1 : 0));
}
addedge(i + n, T, c[i], 1ll * inf * inf);
}
// cerr << "out!\n";
// printf("S = %d, T = %d\n", S, T);
node = n + m + 2;
ll costs = 0;
int flows = mcmf(S, T, costs);
// printf("flows = %lld, costs = %lld\n", flows, costs);
if (flows == n) printf("%d\n", all - costs % inf);
else puts("-1");
for (int i = 1; i <= m; i++) to[i].clear();
}
int main() {
int T; scanf("%d", &T);
while (T--) sc();
return 0;
}
/*
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
*/
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 4028kb
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: -100
Time Limit Exceeded
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...