现在的位置: 首页 > 综合 > 正文

POJ 1273 SAP邻接表

2018年04月26日 ⁄ 综合 ⁄ 共 2339字 ⁄ 字号 评论关闭
const int null = -1;
const int VMAX = 500;
const int EMAX = 300000;

struct Edge
{
	int adj,next,re;    //指向的点,下一边的下标,逆边的下标
	int r;          //余留网边的容量
}h[EMAX+10];  //用下标模拟指针构邻接表
int p[VMAX+10],c;
int n,m,s,t;
int gap[VMAX+10],pre[VMAX+10],dis[VMAX+10];

//插边,k,l为端点,cap为边容量
void insert(int k,int l,int cap)
{
	h[++c].adj=l;
	h[c].r=cap;
	h[c].next=p[k];
	p[k]=c;
	h[c].re=c+1;   

    //逆边
	h[++c].adj=k;
	h[c].r=0;
	h[c].next=p[l];
	p[l]=c;
	h[c].re=c-1;    //与上面对应

}
int sap(int N)  //N为点数(包括源汇)
{
	memset(dis,0,sizeof(dis));
	memset(gap,0,sizeof(gap));
	gap[0]=N;
	int u=s,ca=inf,ans=0;
	while (dis[s]<N)
	{
		while (1)
		{
			bool flag=false;
			for (int j=p[u];j!=null;j=h[j].next)
			{
				int i=h[j].adj;
				if (h[j].r && dis[u]==dis[i]+1)
				{
					ca=min(ca,h[j].r);
					pre[i]=j;u=i;  //注意邻接表版的pre表示的是边
					if (i==t)
					{
						ans+=ca;
						while (i!=s)
						{
							u=pre[i];
							h[u].r-=ca;
							h[h[u].re].r+=ca;
							i=h[h[u].re].adj;
						}
						u=s;ca=inf;
					}
					flag=true;
					break;
				}
			}
			if (!flag) break;
		}

		int Min=N;
		for (int j=p[u];j!=null;j=h[j].next)
			if (h[j].r && dis[h[j].adj]<Min)
				Min=dis[h[j].adj];
		if (--gap[dis[u]] == 0) break;
		gap[dis[u]=Min+1]++;
		if (u!=s) u=h[h[pre[u]].re].adj;
	}
	
	return ans;
}


void init()
{
	c=-1;
	memset(p,-1,sizeof(p));
}
实例poj 1273
#include<stdio.h>
#include<string.h>
#define data 1<<29
#define min(a,b) ((a)>(b)?(b):(a))
const int null=-1;
const int maxe=41000;
const int maxv=210;
struct edge
{
	int adj,next,contain,re;
}edges[maxe];
int p[maxv],c,start,endp,gap[maxv],pre[maxv],dis[maxv];
void insert(int point1,int point2,int cap)
{
	edges[++c].adj=point2;
	edges[c].contain=cap;
	edges[c].next=p[point1];
	p[point1]=c;
	edges[c].re=c+1;

	edges[++c].adj=point1;
	edges[c].contain=0;
	edges[c].next=p[point2];
	p[point2]=c;
	edges[c].re=c-1; 

}
int sap(int N)
{
	memset(dis,0,sizeof(dis));
	memset(gap,0,sizeof(gap));
	gap[0]=N;
	int u=start,ca=data,ans=0;
	while (dis[start]<N)
	{
		while (1)
		{
			bool flag=false;
			for (int j=p[u];j!=null;j=edges[j].next)
			{
				int i=edges[j].adj;
				if (edges[j].contain && dis[u]==dis[i]+1)
				{
					ca=min(ca,edges[j].contain);
					pre[i]=j;
					u=i;  
					if (i==N)
					{
						ans+=ca;
						while (i!=start)
						{
							u=pre[i];
							edges[u].contain-=ca;
							edges[edges[u].re].contain+=ca;
							i=edges[edges[u].re].adj;
						}
						u=start;
						ca=data;
					}
					flag=true;
					break;
				}
				
			}
			if (!flag) break;
			
		}

		int Min=N;
		for (int j=p[u];j!=null;j=edges[j].next)
			if (edges[j].contain && dis[edges[j].adj]<Min)
				Min=dis[edges[j].adj];
		if (--gap[dis[u]] == 0) break;
		gap[dis[u]=Min+1]++;
		if (u!=start) u=edges[edges[pre[u]].re].adj;
	}
	return ans;
}
void init()
{
	c=-1;
	memset(p,-1,sizeof(p));
}
int main()
{
	int n,m,i,j,a,b,t;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		
		init();
		for(i=1;i<=n;i++)
		{
			scanf("%d%d%d",&a,&b,&t);
			insert(a,b,t);
		}
		start=1;
		printf("%dn",sap(m));
	}
	return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.