Cod sursa(job #1709556)

Utilizator TeamFIIBUAIC NoReturnValue TeamFIIB Data 28 mai 2016 12:51:11
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 1.98 kb
#include <iostream>
#include<vector>
#include<fstream>
#include<utility>
#include<algorithm>
#include <deque>
#include <queue>

using namespace std;

int N, M, S, T, ans;
vector <vector <int> > mat, graph;
vector <int> prec;

bool BFS() {
	 fill(prec.begin(), prec.end(), -1);
	 queue <int> coada;
	 coada.push(S);
	 prec[S] = 0;
	 bool ret = false;
	 while (!coada.empty()) {
		   int from = coada.front();
		   coada.pop();
		   for (auto to: graph[from]) {
			   if (to == T && mat[from][to] > 0) {
				  ret = true;
				  int flowmax = 1 << 22;
				  int back = T;
				  prec[T] = from;

				  while (back != S) {
						flowmax = min(flowmax, mat[prec[back]][back]);
						back = prec[back];
				  }
				  ans += flowmax;
				  back = T;
				  while (back != S) {
			  	  		mat[prec[back]][back] -= flowmax;
						mat[back][prec[back]] += flowmax;
						back = prec[back];
				  }
			   }
			   else if (prec[to] == -1 && mat[from][to] > 0) {
				  coada.push(to);
				  prec[to] = from;
			   }
		   }
	 }
	 return ret;
}

void Solve() {
	 mat.clear();
	 graph.clear();
	 prec.clear();
	 
	 int i, j, x, nr;
	 ans = 0;
	 
	 scanf("%d %d", &N, &M);
	 
	 graph.resize(1 + N + M + 1);
	 mat.resize(1 + N + M + 1, vector <int> (1 + N + M + 1));
	 prec.resize(1 + N + M + 1);
	 
	 S = 0;
	 T = N + M + 1;
	 
	 for (i = 1; i <= N; ++i) {
		 graph[S].push_back(i);
		 graph[i].push_back(S);
		 scanf("%d", &mat[S][i]);

	 }
	 
	 for (i = 1; i <= M; ++i) {
		 scanf("%d %d", &nr, &mat[N + i][T]);
		 graph[i + N].push_back(T);
		 graph[T].push_back(i + N);
		 for (j = 1; j <= nr; ++j) {
			 scanf("%d", &x);
			 graph[x].push_back(i + N);
			 graph[i + N].push_back(x);
			 mat[x][i + N] = 1 << 22;
		 }
	 }
	 
	 while (BFS()) {
	 }
	 
	 printf("%d\n", ans);
}

int main() {

	freopen ("tribut.in", "r", stdin);
	freopen ("tribut.out", "w", stdout);

	int t;
	
	scanf("%d", &t);
	while (t--) {
	  Solve();
    }

	return 0;
}