1459

/*
邻接矩阵实现ISAP算法

1459(4)进行再次优化
*/

// include file
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <bitset>

#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <list>
#include <functional>

using namespace std;

// typedef
typedef long long LL;
typedef unsigned long long ULL;
typedef __int64 Bint;

// 
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)
#define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
#define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
#define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
#define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
#define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
#define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
#define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)

#define FF(i,a)    for(int i=0;i<(a);i++)
#define FFD(i,a)   for(int i=(a)-1;i>=0;i--)

#define Z(a) (a<<1)
#define Y(a) (a>>1)

const double eps = 1e-6;
const double INFf = 1e10;
const int INFi = 1000000000;
const double Pi = acos(-1.0);

template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T TMAX(T x,T y)
{
	if(x>y) return x;
	return y;
}
template<class T> inline T TMIN(T x,T y)
{
	if(x<y) return x;
	return y;
}
template<class T> inline void SWAP(T &x,T &y)
{
	T t = x;
	x = y;
	y = t;
}
template<class T> inline T MMAX(T x,T y,T z)
{
	return TMAX(TMAX(x,y),z);
}


// code begin
#define MAXN 110
int N,M,NP,NC;
int source,sink;

// 剩余网络
int G[MAXN][MAXN];

int que[MAXN]; //BFS
int dis[MAXN]; //distance

int pos[MAXN]; // current
int lay[MAXN]; // gap 

int fat[MAXN]; // father

int stkmin[MAXN],mtop;
int stkdex[MAXN],dtop;
int stkver[MAXN],vtop;

void BFS()
{
	int head(0),tail(0);
	fill(lay,lay+N+1,0);
	fill(dis,dis+N+1,N);
	FORi(1,N+1,1)
	{
		lay[dis[i]]++;
	}

	// sink
	lay[dis[sink]]--;
	dis[sink] = 0;
	lay[dis[sink]]++;
	
	que[++tail] = sink;
	while(head!=tail)
	{
		int cur = que[++head];

		FORi(1,N+1,1)
		{
			if(G[i][cur]==0 || dis[i]<N) continue;
			lay[dis[i]]--;
			dis[i] = dis[cur]+1;
			lay[dis[i]]++;

			que[++tail] = i;
		}
	}
}

int Augment()
{
	int minp = stkmin[mtop-1];
	FORi(1,mtop,1)
	{
		stkmin[i] -= minp;
	}
	int cur = sink;
	while(cur!=source)
	{
		G[fat[cur]][cur] -= minp;
		G[cur][fat[cur]] += minp;
		cur = fat[cur];
	}

	return minp;
}

int Retreat(int &cur)
{
	int tmp,mind(N-1);

	FORi(1,N+1,1)
	{
		if(G[cur][i]>0 && dis[i]<mind)
		{
			mind = dis[i];
		}
	}

	tmp = dis[cur];

	lay[dis[cur]]--;
	dis[cur] = 1+mind;
	lay[dis[cur]]++;

	if(cur!=source)
	{
		cur = fat[cur];
		mtop--;
		vtop--;
		dtop--;
	}
	return lay[tmp];
}

int MaxFlow_ISAP()
{
	int flow(0);

	BFS(); // from sink;

	// 当前弧优化
	fill(pos,pos+N+1,1);
	
	// 为了返回0加的优化
	stkmin[0] = INFi;
	mtop = 1;
	stkdex[0] = -1;
	dtop = 1;
	stkver[0] = -1;
	vtop = 1;

	int st = source;
	while(dis[source]<N)
	{
		int ds;
		for(ds=pos[st];ds<=N;ds++)
		{
			if(G[st][ds]>0 && dis[st]==dis[ds]+1)
			{
				break;
			}
		}

		if(ds<=N)
		{ // 找到了
			pos[st] = ds;
			
			//
			if( G[st][ds]<stkmin[mtop-1])
			{
				stkmin[mtop] = G[st][ds];
				stkdex[dtop] = mtop;
				stkver[vtop] = st;
			}
			else
			{
				stkmin[mtop] = stkmin[mtop-1];
				stkdex[dtop] = stkdex[dtop-1];
				stkver[vtop] = stkver[vtop-1];
			}

			mtop++;dtop++;vtop++;

			fat[ds] = st;
			st = ds;

			if(st==sink)
			{
				flow += Augment();

				st = stkver[vtop-1]; 
				
				mtop = stkdex[dtop-1];
				vtop = stkdex[dtop-1];
				dtop = stkdex[dtop-1];

			}
		}
		else
		{
			pos[st] = 1;
			if(Retreat(st)==0)
				break;
		}
	}

	return flow;
}

int main()
{
	read;
	write;
	int a,b,c;

	while(scanf("%d %d %d %d",&N,&NP,&NC,&M)!=-1)
	{
		memset(G,0,sizeof(G));
		source = N+1;
		sink = N+2;

		getchar();
		while(M--)
		{
			scanf(" (%d,%d)%d",&a,&b,&c);
			G[++a][++b]=c;
		}
		while(NP--)
		{
			scanf(" (%d)%d",&b,&c);
			G[N+1][++b] = c;
		}
		while(NC--)
		{
			scanf(" (%d)%d",&a,&c);
			G[++a][N+2] = c;
		}
		N+=2;
		
		printf("%d\n",MaxFlow_ISAP());
	}
	return 0;
}
posted @ 2011-03-16 15:34  AC2012  阅读(226)  评论(0编辑  收藏  举报