QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#624764#9102. Zayin and ElementsFDUdululuAC ✓1ms3736kbC++204.0kb2024-10-09 16:35:222024-10-09 16:35:22

Judging History

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

  • [2024-10-09 16:35:22]
  • 评测
  • 测评结果:AC
  • 用时:1ms
  • 内存:3736kb
  • [2024-10-09 16:35:22]
  • 提交

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