제출 #1369642

#제출 시각아이디문제언어결과실행 시간메모리
1369642marcogambaroTug of War (BOI15_tug)C++20
큐에 대기중
0 ms0 KiB
#include <bits/stdc++.h>
#include <cassert>
using namespace std;
mt19937 timmy_loves_gambling(73);
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define readv(v) do { for(auto &i: v) cin >> i; } while(0)
#define _ << " " <<
#define lf "\n"
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define fi first
#define se second
template<typename... Args>
using vec = vector<Args...>;
#ifndef MARCO
bool dbg = 0;
#define infor(str, ...)
#define infof(str, ...)
#else
bool dbg = 1;
#define infor(str, ...) do { print(stderr, str, ##__VA_ARGS__); } while(0)
#define infof(str, ...) do { println(stderr, str, ##__VA_ARGS__); } while(0)
#endif



signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);   
    
	int N, K; cin >> N >> K;

	vec<pii> V(N*2);
	vec<int> W(N*2);
	vector<vector<pii>> G(N*2);
	vector<int> dg(N*2);
	vector<bool> player(N*2);

	for(int i=0; i<N*2; i++) {
		cin >> V[i].fi >> V[i].se >> W[i];
		V[i].fi--;
		V[i].se+=N-1;

		dg[V[i].fi]++;
		dg[V[i].se]++;

		G[V[i].fi].push_back({V[i].se, i});
		G[V[i].se].push_back({V[i].fi, i});
	}
	
	int wl = 0;
	int wtot = accumulate(all(W), 0);
	
	stack<int> st;
	for(int i=0; i<N*2; i++) {
		if(dg[i] == 1) st.push(i);
		if(dg[i] == 0) {
			cout << "NO\n";
			return 0;
		}
	}

	while(!st.empty()) {
		int v = st.top();
		st.pop();

		int pl = -1;
		for(auto &[u, p]: G[v])
			if(!player[p]) pl = p;

		assert(pl != -1);
		player[pl] = 1;

		if(v < N) wl += W[pl];

		if(--dg[V[pl].fi] == 1) st.push(V[pl].fi);
		if(--dg[V[pl].se] == 1) st.push(V[pl].se);
	}

	// all remaining nodes should have degree 2
	vec<pii> Q;

	for(int i=0; i<2*N; i++)
		if(dg[i] != 2 && dg[i] != 0) exit(1);

	auto dfs = [&](int v, int p, auto &&dfs) -> pii {
		player[p] = 1;

		for(auto &[u, pu]: G[v]) {
			if(player[pu]) continue;
			auto [a, b] = dfs(u, pu, dfs);

			if(v < N) return {W[p]+a, b};
			else return {a, W[p]+b};
		}

		if(v < N) 	return {W[p], 0};
		else 		return {0, W[p]};
	};

	for(int i = 0; i < 2*N; i++) {
		if(player[i]) continue;

		auto [a, b] = dfs(V[i].fi, i, dfs);
		Q.push_back({a, b});
	}

	bitset<73000> knap;
	knap[wl] = 1;

	for(auto &[a, b]: Q) {
		knap = (knap << a) | (knap << b);
	}

	for(int i = max(0, (wtot-K+1)/2); i < min(73000, (K+wtot)/2 + 1); i++) {
		if(knap[i]) {
			cout << "YES\n";
			return 0;
		}
	}
	cout << "NO\n";
}