Cod sursa(job #1709900)

Utilizator UPB_Hulea_Ionescu_RomanNo Idea UPB_Hulea_Ionescu_Roman Data 28 mai 2016 14:21:51
Problema Tribut Scor 0
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 1.72 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>

using namespace std;

int minim(int a, int b)
{
	if (a < b)
		return a;
	return b;
}

int main()
{
	int t;
	int n, m, x, nr, max;
	vector<int> S;
	int nr_s[102], max_u[101];
	vector<int> uni[103];

	ifstream in("tribut.in");
	ofstream out("tribut.out");

	in >> t;

	for (int i = 0; i < t; ++i) {

		S.clear();
		for (int j = 0; j < 102;++j)
			uni[j].clear();

		in >> n >> m;
		for (int j = 0; j < n; ++j) {
			in >> x;
			S.push_back(x);
		}

		for (int j = 0; j < m; ++j) {

			in >> nr >> max;
			nr_s[j] = nr;
			max_u[j] = max;
			for (int k = 0; k < nr; ++k){
				in >> x;
				uni[j].push_back(x);
			}
			//cout << "C" << endl;

		}

		long long s = 0;

		// choose for one union at each step
		for (int j = 0; j < m; ++j) {
			max = max_u[j];
			nr = nr_s[j];

			vector< pair<int, int> > v;
			v.clear();
			for (int p = 0; p < nr; ++p)
				v.push_back(make_pair(0, p));
			

			// find the maximum gain on the remaining 
			for (int k = j + 1; k < m; ++k) {

				//all sistem for current union
				for (int p = 0; p < nr; ++p){

					// sistem union iterate
					for (int l = 0; l < nr_s[k]; ++l) {
						if (uni[j][p] == uni[k][l]) {
							v[p].first = v[p].first + max_u[k];
						}
					}
				}
			}

			sort(v.begin(), v.end());
			for (unsigned int k = 0; k < v.size(); ++k) {
				//out << uni[j][v[k].second] <<" " << v[k].first<< " | ";
				s += minim(max, S[uni[j][v[k].second]-1]);
				S[uni[j][v[k].second]-1] -= minim(max, S[uni[j][v[k].second]-1]);
				max -= minim(max, S[uni[j][v[k].second] - 1]);
			}
			//out << endl;
		}

		out <<s << endl;
	}

	return 0;
}