Cod sursa(job #804723)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 30 octombrie 2012 11:02:59
Problema Algola Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cassert>
#include<queue>

using namespace std;

int n, m, need, k, dest = 2900, source = 0, cit[55];
int flow, vis[3000], fl[130005], cap[130005];
pair<int, int> dad[3000];
vector<pair<int, int> > graph[3000];
vector<pair<int, pair<int, int> > > edg;

void read(){
	assert(freopen("algola.in", "r", stdin));
	
	scanf("%d%d", &n, &m);
	
	++k;
	cap[k] = 9001;
	graph[1].push_back(make_pair(dest, k));
	graph[2900].push_back(make_pair(1, k));
	for(int i = 1; i <= n; ++i){
		scanf("%d", &cit[i]);
		need += cit[i];
		++k;
		graph[0].push_back(make_pair(i, k));
		graph[i].push_back(make_pair(0, k));
		cap[k] = cit[i];
	}
	
	for(int i = 1; i <= m; ++i){
		int x, y, c;
		++k;
		scanf("%d%d%d", &x, &y, &c);
		y += n;
		graph[x].push_back(make_pair(y, k));
		graph[y].push_back(make_pair(x, k));
		cap[k] = c;
		edg.push_back(make_pair(c, make_pair(x, y)));
	}
	
}

void add(int x){
	++k;
	cap[k] = 9001;
	graph[1 + x * n].push_back(make_pair(2900, k));
	graph[2900].push_back(make_pair(1 + x * n, k));
	
	for(int i = x * n + 1; i <= x * n + n; ++i){
		++k;
		graph[i].push_back(make_pair(i - n, k));
		graph[i - n].push_back(make_pair(i, k));
		cap[k] = 9001;
	}
	
	for(int i = 0; i < edg.size(); ++i){
		++k;
		graph[x * n + edg[i].second.first].push_back(make_pair(edg[i].second.second + x * n, k));
		graph[x * n + edg[i].second.second].push_back(make_pair(edg[i].second.first + x * n, k));
		cap[k] = edg[i].first;
	}
}

void init(){
	for(int i = 0; i < 3000; ++i)
		vis[i] = 0;
}

int ans;

int canpush(int x, int y, int e){
	if(vis[y])
		return 0;
	if(x < y)
		return fl[e] < cap[e];
	else
		return fl[e] > -cap[e]; 
}

int bfs(){
	init();
	
	queue<int> q;
	q.push(source);
	vis[source] = 1;
	
	while(!q.empty()){
		int now = q.front();
		q.pop();
		
		for(int i = 0; i < graph[now].size(); ++i)
			if(canpush(now, graph[now][i].first, graph[now][i].second)){
				vis[graph[now][i].first] = 1;
				dad[graph[now][i].first] = make_pair(now, graph[now][i].second);
				q.push(graph[now][i].first);
			}
		
		if(vis[dest])
			return 1;
	}
	return 0;
}

void flu(){
	while(bfs()){
		int minf = 9001;
		for(int i = dest; i != 0; i = dad[i].first)
			minf = min(minf, cap[dad[i].second] - fl[dad[i].second]);
		for(int i = dest; i != 0; i = dad[i].first)
			if(dad[i].first > i)
				fl[dad[i].second] += minf;
			else
				fl[dad[i].second] -= minf;
		flow += minf;
	}
}

void solve(){
	int i = 0;
	while(++i){
		flu();
		if(flow == need){
			ans = i;
			break;
		}
		add(i);
	}
}

void write(){
	assert(freopen("algola.out", "w", stdout));
	
	printf("%d", ans);
}

int main(){
	read();
	solve();
	write();
	return 0;
}