Cod sursa(job #378482)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 28 decembrie 2009 18:55:36
Problema Algola Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <fstream>
#include <vector>
#include <list>
#include <cstring>
#define MAX 5600
using namespace std;
char F[MAX][MAX],C[MAX][MAX];
vector<int> G[MAX];
int sursa,destinatie;
struct muchie{ int x,y,cap; } v[310];
int viz[MAX],dad[MAX];
int N,M,members[60],ReqSum=0;
list<int> L;

inline void add_Edge(int x,int y){
	G[x].push_back(y);
	G[y].push_back(x);
}

void get_network(int T){
	
	sursa=(T+1)*N+1;
	destinatie=(T+1)*N+2;
	
	for (int Time=0;Time<T;++Time){
		for (int i=1;i<=N;++i){
			add_Edge(Time*N+i,(Time+1)*N+i);
			C[Time*N+i][(Time+1)*N+i]=60;
		}
		for (int i=1;i<=M;++i){
			add_Edge(Time*N+v[i].x,(Time+1)*N+v[i].y);
			C[Time*N+v[i].x][(Time+1)*N+v[i].y]=v[i].cap;
			add_Edge(Time*N+v[i].y,(Time+1)*N+v[i].x);
			C[Time*N+v[i].y][(Time+1)*N+v[i].x]=v[i].cap;
		}
	}

	for (int i=1;i<=N;++i)
		if (members[i]) {
			add_Edge(sursa,i);
			C[sursa][i]=members[i];
		}
}


int BFS(int S,int D,int Time){
	memset(viz,0,sizeof(viz));
	memset(dad,0,sizeof(dad));
	
	viz[S]=1;
	L.push_back(S);

	while (!L.empty()){
		list<int>::iterator it=L.begin();
		for (vector<int>::iterator it2=G[*it].begin();it2!=G[*it].end();++it2)
			if (((*it2)<=(Time+1)*N || (*it2)==D) && viz[*it2]==0 && C[*it][*it2]>F[*it][*it2]){
				viz[*it2]=1;
				dad[*it2]=*it;
				L.push_back(*it2);
			}
		L.erase(it);
	}

	return viz[D];
}

int flow(int T){
	
	G[T*N+1].push_back(destinatie);
	G[destinatie].push_back(T*N+1);
	C[T*N+1][destinatie]=60;

	int maxflow=0;

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


	for (int i=1;i<=N;++i)
		if (members[i]) F[sursa][i]=F[i][sursa]=0;
	for (int Time=0;Time<T;++Time){
		for (int i=1;i<=N;++i)
			F[Time*N+i][(Time+1)*N+i]=F[(Time+1)*N+i][Time*N+i]=0;
		for (int 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;
		}
	}
	F[T*N+1][destinatie]=F[destinatie][T*N+1]=0;

	C[T*N+1][destinatie]=0;
	G[T*N+1].pop_back();
	G[destinatie].pop_back();
	return maxflow;
}





int main(){
	
	ifstream fi("algola.in");
	fi>>N>>M;
	for (int i=1;i<=N;++i) { fi>>members[i]; ReqSum+=members[i]; }
	for (int i=1;i<=M;++i) fi>>v[i].x>>v[i].y>>v[i].cap;
	fi.close();

	get_network(100);

	int REZ=101,p=0,u=100;
	while (p<=u){
		int m=(p+u)/2;
		int flux=flow(m);
		if (flux==ReqSum){ REZ=m;u=m-1;} else p=m+1;
	}

	ofstream fo("algola.out");
	fo<<REZ<<"\n";
	fo.close();
	
	return 0;
}