Cod sursa(job #1712795)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 3 iunie 2016 18:32:59
Problema Tribut Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.1 kb
using namespace std;
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define Vmax 210
#define INF 2000000000

int S, D;
int pred[Vmax], f[Vmax][Vmax], c[Vmax][Vmax];
vector< int > G[Vmax];
vector< bool > vis(Vmax);
queue< int > Q;

void read(ifstream&);
void edge(int, int, int);
int solve();
bool BFS();

int main()
{
	int t;
	ifstream fin("tribut.in");
	ofstream fout("tribut.out");

	for (fin >> t; t; --t)
	{
		memset(f, 0, sizeof(f));
		memset(c, 0, sizeof(c));

		read(fin);

		fout << solve() << '\n';
	}

	fin.close();
	fout.close();

    return 0;
}

void read(ifstream &fin)
{
	int i, n, m, a, nr;

	fin >> n >> m;
	S = 0; D = n + m + 1;

	for (i = 1; i <= n; ++i)
	{
		fin >> a;
		edge(0, i, a);
	}

	for (i = n + 1; i <= n + m; ++i)
	{
		fin >> nr >> a;
		edge(i, n + m + 1, a);

		for (; nr; --nr)
		{
			fin >> a;
			edge(a, i, INF);
		}
	}
}

void edge(int a, int b, int ca)
{
	G[a].push_back(b);
	G[b].push_back(a);

	c[a][b] = ca;
}

int solve()
{
	int flow, minF, node;

	for (flow = 0; BFS(); )
	{
		for(auto &to : G[D])
			if (vis[to] && f[to][D] < c[to][D])
			{
				pred[D] = to;
				for (minF = INF, node = D; pred[node] != -1; node = pred[node])
					if (minF > c[pred[node]][node] - f[pred[node]][node])
						minF = c[pred[node]][node] - f[pred[node]][node];

				if (minF)
				{
					for (node = D; pred[node] != -1; node = pred[node])
						f[pred[node]][node] += minF,
						f[node][pred[node]] -= minF;

					flow += minF;
				}
			}
	}

	return flow;
}

bool BFS()
{
	int node;
	fill(vis.begin(), vis.end(), false);

	for (Q.push(S), vis[S] = true, pred[S] = -1; !Q.empty(); Q.pop())
	{
		node = Q.front();
		if (node == D) continue;

		for(auto &to : G[node])
			if (!vis[to] && f[node][to] < c[node][to])
			{
				pred[to] = node;
				Q.push(to);
				vis[to] = true;
			}
	}

	return vis[D];
}