Submission #1278899

#TimeUsernameProblemLanguageResultExecution timeMemory
1278899poltomoJobs (BOI24_jobs)C++20
58 / 100
209 ms9388 KiB
#include<iostream>
#include<vector>
#include<queue>
//#include<functional>

using namespace std;

int find(vector<int>& U, int a) {
	while (a != U[a])
		a = U[a];
	return a;
}
 
// find + two pass path compression
int find2(vector<int>& U, int a) {
	int root = a;
	while (root != U[root])
		root = U[root]; 
	int next = U[a];
	while (next != root) {
		U[a] = root;
		a = next;
		next = U[a];
	}
	return root;
}
 
// merges roots only
void merge(vector<int>& U, int a, int b) {
	U[find(U,b)] = find(U, a);
}

int main() {
	int N, s;
	cin >> N >> s;
	vector<long long> x(N + 1);
	vector<int> p(N + 1);
	vector<long long> cost_to_take(N + 1);
	vector<int> U(N + 1);
	for (int i = 0;i < N + 1;++i) {
		U[i] = i;
	}
	auto cmp = [&](int a, int b) {return cost_to_take[a] > cost_to_take[b];}; // least expensive jobs first
	priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);
	x[0] = s;
	p[0] = 0;
	for (int i = 1;i < N + 1; ++i) {
		cin >> x[i] >> p[i];
		if (x[i] < 0) {
			cost_to_take[i] = -x[i];
		}
		else {
			pq.push(i);
		}
	}
	while (!pq.empty()) {
		int least_expensive_job = pq.top(); // least expensive job
		pq.pop();
		int least_expensive_job_parent = find2(U, p[least_expensive_job]); // least expensive job parent
		if (cost_to_take[least_expensive_job_parent] + x[least_expensive_job_parent] >= cost_to_take[least_expensive_job]) {
			merge(U, least_expensive_job_parent, least_expensive_job); // merge jobs
			x[least_expensive_job_parent] += x[least_expensive_job]; // add profits
			x[least_expensive_job] = 0;
//cout << 'a' << ' ' << least_expensive_job << ' ' << least_expensive_job_parent << ' ' << cost_to_take[least_expensive_job_parent] << ' ' << x[least_expensive_job_parent] << ' ' << x[0] << endl;
		}
		else {
//cout << 'b' << ' ' << least_expensive_job << ' ' << least_expensive_job_parent << ' ' << cost_to_take[least_expensive_job_parent] << ' ' << x[least_expensive_job_parent] << ' ' << x[0] << endl;
			if (least_expensive_job_parent != 0) {
				merge(U, least_expensive_job_parent, least_expensive_job); // merge jobs
				cost_to_take[least_expensive_job_parent] = cost_to_take[least_expensive_job] - x[least_expensive_job_parent];
				x[least_expensive_job_parent] += x[least_expensive_job]; // add profits
				x[least_expensive_job] = 0;
//cout << 'b' << ' ' << least_expensive_job << ' ' << least_expensive_job_parent << ' ' << cost_to_take[least_expensive_job_parent] << ' ' << x[least_expensive_job_parent] << endl;
			}
		}
		if (least_expensive_job_parent != 0 && x[least_expensive_job_parent] > 0) {
//cout << 'c' << ' ' << least_expensive_job << ' ' << least_expensive_job_parent << ' ' << cost_to_take[least_expensive_job_parent] << ' ' << x[least_expensive_job_parent] << endl;
			pq.push(least_expensive_job_parent);
		}
	}
	cout << x[0] - s << endl;
}	
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...