Cod sursa(job #378609)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 29 decembrie 2009 03:03:47
Problema Algola Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <cstdio>
#include <list>
#include <vector>
#define MAX 5060
using namespace std;
char C[MAX][MAX],F[MAX][MAX];
struct muchie{ int x,y,cap; } v[310];
int coada[MAX],viz[MAX],dad[MAX],STEP=0;
int N,M,SS,DD,SR;
int members[60];
list<int> G[MAX];

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

inline int BFS(int S,int D,int T){
	int p=1,u=1;
	viz[S]=STEP;
	coada[p]=S;
	while (p<=u){
		for (list<int>::iterator it=G[coada[p]].begin();it!=G[coada[p]].end();++it)
			if (((*it)==D || (*it)<=(T+1)*N) && viz[*it]<STEP && C[coada[p]][*it]>F[coada[p]][*it]){
				viz[*it]=STEP;
				dad[*it]=coada[p];
				coada[++u]=*it;
			}
		++p;
	}
	return viz[D];
}

void init(int T){
	SS=(T+1)*N+1;
	DD=(T+1)*N+2;

	for (int i=1;i<=N;++i)
		if (members[i]){
			G[SS].push_back(i);
			G[i].push_back(SS);
			C[i][SS]=members[i];
		}

	for (int Time=0;Time<T;++Time){
		for (int i=1;i<=N;++i){
			G[Time*N+i].push_back((Time+1)*N+i);
			G[(Time+1)*N+i].push_back(Time*N+i);
			C[(Time+1)*N+i][Time*N+i]=60;
		}
		for (int i=1;i<=M;++i){
			G[Time*N+v[i].x].push_back((Time+1)*N+v[i].y);
			G[(Time+1)*N+v[i].y].push_back(Time*N+v[i].x);
			C[(Time+1)*N+v[i].y][Time*N+v[i].x]=v[i].cap;
			
			G[Time*N+v[i].y].push_back((Time+1)*N+v[i].x);
			G[(Time+1)*N+v[i].x].push_back(Time*N+v[i].y);
			C[(Time+1)*N+v[i].x][Time*N+v[i].y]=v[i].cap;
		}
	}
}


inline int flow(int T){
	int i;

	G[DD].push_back(N*T+1);
	G[N*T+1].push_back(DD);
	C[DD][N*T+1]=60;

	int maxflow=0;
	++STEP;
	while (BFS(DD,SS,T)==STEP){
		for (int i=1;i<=N;++i)
		if (viz[i]==STEP && C[i][SS]>F[i][SS]){
			int sat=C[i][SS]-F[i][SS];
			for (int nod=i;dad[nod];nod=dad[nod])
				sat=min(sat,C[dad[nod]][nod]-F[dad[nod]][nod]);
			if (sat==0) continue;
			F[i][SS]+=sat;
			F[SS][i]-=sat;
			for (int nod=i;dad[nod];nod=dad[nod]){
				F[dad[nod]][nod]+=sat;
				F[nod][dad[nod]]-=sat;
			}
			maxflow+=sat;
		}
		++STEP;
	}

	G[DD].pop_back();
	G[N*T+1].pop_back();
	C[DD][N*T+1]=0;

	F[N*T+1][DD]=F[DD][N*T+1]=0;

	for (i=1;i<=N;++i)
		F[SS][i]=F[i][SS]=0;

	for (int Time=0;Time<T;++Time){
		for (i=1;i<=N;++i)
			F[Time*N+i][(Time+1)*N+i]=F[(Time+1)*N+i][Time*N+i]=0;
		for (i=1;i<=M;++i){
			F[Time*N+v[i].x][(Time+1)*N+v[i].y]=F[(Time+1)*N+v[i].y][Time*N+v[i].x]=0;
			F[Time*N+v[i].y][(Time+1)*N+v[i].x]=F[(Time+1)*N+v[i].x][Time*N+v[i].y]=0;
		}
	}

	return maxflow;
}


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]; }
	for (int i=1;i<=M;++i) scanf("%d%d%d\n",&v[i].x,&v[i].y,&v[i].cap);
	fclose(stdin);

	init(N*2);

	STEP=0;
	int REZ=N*2+1;
	int p=0,u=N*2;
	while (p<=u){
		int m=(p+u)/2;
		int flux=flow(m);
		if (flux==SR){ REZ=m; u=m-1;} else p=m+1;
	}

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

	return 0;
}