Cod sursa(job #378611)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 29 decembrie 2009 03:47:06
Problema Algola Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.45 kb
#include <cstdio>
#include <cstring>
#include <vector>
#define MAX 5060
#define MAXN 60
using namespace std;
vector<int> G[MAXN];
char C[MAX][MAX];
int dad[MAX],flow[MAX];
bool ok;
int Q[MAX];
int N,M,S,D,SR;
struct muchie { int x,y,cap; } v[310];
int members[MAXN];

inline int min(char x,char y){ return x<y?x:y; }

inline int BFS(int S,int D,int T){
	
	memset(flow,0,sizeof(flow));
	memset(dad,0,sizeof(dad));

	
	int p=1,u=1;
	Q[p]=S;
	flow[S]=60;
	while (p<=u){
		if (Q[p]==S){
			for (int i=1;i<=N;++i) if (C[S][i]){
				flow[i]=C[S][i];
				Q[++u]=i;
				dad[i]=S;
			} 
		} else {
				int timp=Q[p]/N;
				int nr=Q[p]%N;
				if (nr==0){ --timp; nr=N; }
				if (timp==T && nr==1){
					flow[D]=flow[Q[p]];
					dad[D]=Q[p];
					p=u+1;
					break;
				}
				for (vector<int>::iterator it=G[nr].begin();it!=G[nr].end();++it){
					if (timp<T){
						int x=(timp+1)*N+*it;
						if (!flow[x] && C[Q[p]][x]){
							Q[++u]=x;
							dad[x]=Q[p];
							flow[x]=min(flow[Q[p]],C[Q[p]][x]);
						}
					}
					if (timp==0) continue;
					int x=(timp-1)*N+*it;
					if (!flow[x] && C[Q[p]][x]){
						Q[++u]=x;
						dad[x]=Q[p];
						flow[x]=min(flow[Q[p]],C[Q[p]][x]);
					}
				}
			}
		++p;
	}
	if (!flow[D]) return 0;
	ok=true;
	for (int nod=D;dad[nod];nod=dad[nod]){
		C[dad[nod]][nod]-=flow[D];
		C[nod][dad[nod]]+=flow[D];
	}
	return flow[D];
}


inline int maxflow(int T){
	
	
	C[T*N+1][D]=60;
	C[D][T*N+1]=0;
	
	for (int i=1;i<=N;++i){
		C[S][i]=members[i];
		C[i][S]=0;
	}
	
	for (int Time=0;Time<T;++Time){
		for (int i=1;i<=N;++i){
			C[Time*N+i][(Time+1)*N+i]=60;
			C[(Time+1)*N+i][Time*N+i]=0;
		}
		for (int i=1;i<=M;++i){
			C[Time*N+v[i].x][(Time+1)*N+v[i].y]=v[i].cap;
			C[(Time+1)*N+v[i].y][Time*N+v[i].x]=0;
			C[Time*N+v[i].y][(Time+1)*N+v[i].x]=v[i].cap;
			C[(Time+1)*N+v[i].x][Time*N+v[i].y]=0;
		}
	}
	
	int flux=0;
	for (ok=true;ok;){
		ok=false;
		flux+=BFS(S,D,T);
	}
	
	return flux;
}


int main(){

	freopen("algola.in","rt",stdin);
	scanf("%d%d\n",&N,&M);
	SR=0;
	for (int i=1;i<=N;++i){ scanf("%d",&members[i]); SR+=members[i]; G[i].push_back(i); }
	for (int i=1;i<=M;++i){ scanf("%d%d%d",&v[i].x,&v[i].y,&v[i].cap); G[v[i].x].push_back(v[i].y); G[v[i].y].push_back(v[i].x); }
	fclose(stdin);

	int REZ=100;
	int p=0,u;
	if (N<M) u=2*N; else u=2*M;
	S=(u+1)*N+1;
	D=(u+1)*N+2;
	while (p<=u){
		int m=(p+u)/2;
		int flx=maxflow(m);
		if (flx>=SR){ REZ=m; u=m-1; } else p=m+1;
	}

	freopen("algola.out","wt",stdout);
	printf("%d\n",REZ);
	fclose(stdout);


	return 0;
}