Cod sursa(job #469020)

Utilizator AndreyPAndrei Poenaru AndreyP Data 5 iulie 2010 20:42:02
Problema Algola Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <bitset>
using namespace std;
#define pb push_back
#define N 53
#define M 5210

short n,rez;
short sursa;
vector< short > a[N];
char c[M][M];
short sum;
short flow;
queue< int > q;
short last;
short t[M];
bitset< M > viz;

inline short hash1(short nod,short t)
{
	return (t*51)+nod;
}

inline void citire()
{
	short m;
	scanf("%hd%hd",&n,&m);
	sursa=n+1;
	short x,y,z;

	scanf("%hd\n",&x);
	for(short i=2; i<=n; ++i)
	{
		scanf("%hd",&x);
		sum+=x;
		a[sursa].pb(i);
		c[sursa][hash1(i,1)]=(char)x;
		for(short j=0; j<100; ++j)
		{
			y=hash1(i,j+1);
			c[x][y]=100;
			x=y;
		}
	}
	if(sum==0)
	{
		printf("0\n");
		exit(0);
	}

	char z1;
	short x1,y1;
	for(short i=0; i<m; ++i)
	{
		scanf("%hd%hd%hd",&x,&y,&z);
		z1=(char)z;
		a[x].pb(y);
		a[y].pb(x);

		for(short t=0; t<100; ++t)
		{
			x1=hash1(x,t);
			y1=hash1(y,t+1);
			c[x1][y1]+=z1;
			if(c[x1][y1]>50)
				c[x][y]=50;
			x1=hash1(x,t+1);
			y1=hash1(y,t);
			c[y1][x1]+=z1;
			if(c[y1][x1]>50)
				c[y1][x1]=50;
		}
	}
}

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

inline bool bfs()
{
	while(!q.empty())
		q.pop();
	short now,next;
	short x,ti,y;
	viz.reset();
	q.push(sursa);
	viz[sursa]=1;

	while(!q.empty())
	{
		now=q.front();
		q.pop();
		x=now%51;
		ti=now/51;
		if(x==0)
		{
			x=sursa;
			ti=0;
		}
		
		for(size_t i=0,lim=a[x].size(); i<lim; ++i)
		{
			y=a[x][i];
			next=hash1(y,ti+1);
			//if(next<0)
			//	fprintf(stderr,"%hd\n",next);
			if(viz[next]==0 && c[now][next]>0 && ti<rez)
			{
				viz[next]=1;
				t[next]=now;
				if(y==1)
				{
					last=next;
					return true;
				}
				q.push(next);
			}

			if(ti==0)
				continue;
			next=hash1(y,ti-1);
			//if(next<0)
			//	fprintf(stderr,"%hd\n",next);
			if(viz[next]==0 && c[now][next]>0)
			{
				viz[next]=1;
				t[next]=now;
				if(y==1)
				{
					last=next;
					return true;
				}
				q.push(next);
			}
		}

		next=hash1(x,ti+1);
		//if(next<0)
		//	fprintf(stderr,"%hd\n",next);
		if(viz[next]==0 && ti<rez)
		{
			viz[next]=1;
			t[next]=now;
			q.push(next);
		}
	}

	return false;
}

inline void flux()
{
	char r;
	short x;
	while(bfs())
	{
		x=last;
		r=55;
		while(x!=sursa)
		{
			r=minim(r,c[t[x]][x]);
			x=t[x];
		}

		x=last;
		while(x!=sursa)
		{
			c[t[x]][x]-=r;
			c[x][t[x]]+=r;
			x=t[x];
		}
		flow+=(short)r;
	}
}

int main()
{
	freopen("algola.in","r",stdin);
	freopen("algola.out","w",stdout);

	citire();
	rez=1;
	while(flow<sum)
	{
		++rez;
		flux();
	}

	printf("%hd\n",rez-1);
	return 0;
}