#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
struct Edge {
int to, rev, cap, cost;
Edge(int t, int r, int ca, int co): to(t), rev(r), cap(ca), cost(co) {}
};
class MinCostMaxFlow {
public:
int n;
vector<vector<Edge>> g;
vector<int> dist, inqueue;
vector<int> prev, preve;
MinCostMaxFlow(int _n): n(_n), g(_n), prev(_n), preve(_n), dist(_n), inqueue(_n) {}
void addEdge(int from, int to, int cap, int cost) {
Edge e1(to, g[to].size(), cap, cost);
Edge e2(from, g[from].size(), 0, -cost);
g[from].push_back(e1);
g[to].push_back(e2);
}
pair<int, int> flow(int s, int t, int maxf) {
int flow = 0, cost = 0;
while (true) {
fill(dist.begin(), dist.end(), INF);
fill(inqueue.begin(), inqueue.end(), false);
queue<int> q;
dist[s] = 0;
q.push(s);
inqueue[s] = true;
while (!q.empty()) {
int v = q.front(); q.pop();
inqueue[v] = false;
for (int i = 0; i < g[v].size(); ++i) {
Edge &e = g[v][i];
if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
dist[e.to] = dist[v] + e.cost;
prev[e.to] = v;
preve[e.to] = i;
if (!inqueue[e.to]) {
q.push(e.to);
inqueue[e.to] = true;
}
}
}
}
if (dist[t] == INF) break;
int d = maxf - flow;
for (int v = t; v != s; v = prev[v])
d = min(d, g[prev[v]][preve[v]].cap);
flow += d;
cost += d * dist[t];
for (int v = t; v != s; v = prev[v]) {
Edge &e = g[prev[v]][preve[v]];
e.cap -= d;
g[v][e.rev].cap += d;
}
}
return {flow, cost};
}
};
int main() {
int N, K;
cin >> N >> K;
int totalStrength = 0;
vector<pair<int, int>> lr(2*N);
vector<int> s(2*N);
for (int i = 0; i < 2*N; ++i) {
int l, r, si;
cin >> l >> r >> si;
lr[i] = {l, r};
s[i] = si;
totalStrength += si;
}
const int SRC = 2*N + 2*N;
const int SINK = SRC + 1;
const int TOTAL = SINK + 1;
MinCostMaxFlow mcmf(TOTAL);
// Source -> Players
for (int i = 0; i < 2*N; ++i)
mcmf.addEdge(SRC, i, 1, 0);
// Players -> Left/Right Positions
for (int i = 0; i < 2*N; ++i) {
auto [l, r] = lr[i];
mcmf.addEdge(i, 2*N + (l-1), 1, s[i]); // left team adds strength
mcmf.addEdge(i, 2*N + N + (r-1), 1, -s[i]); // right team subtracts strength
}
// Positions -> Sink
for (int i = 0; i < N; ++i)
mcmf.addEdge(2*N + i, SINK, 1, 0);
for (int i = 0; i < N; ++i)
mcmf.addEdge(2*N + N + i, SINK, 1, 0);
auto [flow, cost] = mcmf.flow(SRC, SINK, 2*N);
if (flow != 2*N) {
cout << "NO\n";
return 0;
}
int sumLeft = (totalStrength + cost) / 2;
int sumRight = totalStrength - sumLeft;
if (abs(sumLeft - sumRight) <= K)
cout << "YES\n";
else
cout << "NO\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |