明天补题方便找

/**
 *    Author:  LZVSDY
**/
#include <bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 110;
const int M = 2e4 + 10;
int n, k;
int p[N], c[N], L[N];
int h[N], e[M], ne[M], f[M], cur[N], idx;
int d[N];
int sum, s, t;
void add(int a, int b, int c) {
    e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx ++;
    e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx ++;
}
bool judge(int x) {
    for (int i = 2; i <= x / i; i ++ ) 
        if (x % i) return 0;
    return 1;
}
void work(int mid) {
    idx = sum = 0;
    s = 0, t = n + 1;
    for (int i = 0; i <= n + 1; i ++ ) h[i] = -1;
    int pos = -1;
    for (int i = 1; i <= n; i ++ ) 
        if (c[i] == 1 && L[i] <= mid) 
            if (pos == -1 || p[i] > p[pos])
                pos = i;
    if (pos != -1) {
        add(s, pos, p[pos]);
        sum += p[pos];
        for (int i = 1; i <= n; i ++ ) 
            if (c[i] != 1 && L[i] <= mid && judge(1 + c[i]))
                add(pos, i, INF);
    }
    for (int i = 1; i <= n; i ++ ) {
        if (c[i] == 1 || L[i] > mid) continue;
        if (c[i] & 1) add(s, i, p[i]);
        else add(i, t, p[i]);
        sum += p[i];
        for (int j = i + 1; j <= n; j ++ ) {
            if (c[j] == 1 || L[j] > mid || !judge(c[i] + c[j]))
                continue;
            if (c[i] & 1) add(i, j, INF);
            else add(j, i, INF);
        }
    }
}
bool bfs() {
    queue<int> q;
    for (int i = 0; i <= n + 1; i ++ ) d[i] = -1;
    q.push(s), cur[s] = h[s];
    d[s] = 0;
    while (q.size()) {
        int t = q.front(); q.pop();
        for (int i = h[t]; ~i; i = ne[i]) {
            int j = e[i];
            if (d[j] == -1 && f[i]) {
                d[j] = d[t] + 1;
                cur[j] = h[j];
                if (j == t) return 1;
                q.push(j);
            }
        }
    }
    return 0;
}
int find(int u, int limit) {
    if (u == t) return limit;
    int flow = 0;
    for (int i = cur[u]; ~i && flow < limit; i = ne[i]) {
        cur[u] = i;
        int j = e[i];
        if (d[j] == d[u] + 1 && f[i]) {
            int t = find(j, min(f[i], limit - flow));
            if (!t) d[j] = -1;
            f[i] -= t, f[i ^ 1] += t, flow += t;
        }
    }
    return flow;
}
int dinic() {
    int r = 0, flow;
    while (bfs())
        while (flow = find(s, INF)) r += flow;
    return r;
}
int main() {
//	#ifdef lz
//		freopen("lz.in", "r", stdin);
//	#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> k;
    for (int i = 1; i <= n; i ++ ) 
        cin >> p[i] >> c[i] >> L[i];
    int l = 1, r = 100;
    while (l < r) {
        int mid = l + r + 1 >> 1;
        work(mid);
        int cnt = dinic();
        if (sum - cnt >= k) r = mid - 1;
        else l = mid;
    }
    cout << l << endl;
    return 0;
}
/*
1
2 5
1 6
10 6
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值