Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

SPA 模版详解

Posted by zero0769 at 2015-02-09 16:58:45 on Problem 1273
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
#define MAX 1000
#define inf 100000000+1000

int map[MAX][MAX];	//小规模数据用邻接矩阵存图 
int dis[MAX];		//dis[i]表示i点到汇点的距离 
int gap[MAX];		//gap[i]记录dis为i的点的个数 
int pre[MAX];		//pre[i]表示i点的前导 

int SAP(int s,int t){
	memset(dis,0,sizeof(dis));
	memset(gap,0,sizeof(gap));
	memset(pre,-1,sizeof(pre));
	gap[0]=t;		//所有点dis初始值为0, 
	int i,u,maxflow=0,low=inf,mindis;
	u=s; 			//u为临时储存的当前点 
	pre[s]=s;
	
	while(dis[s]<t){
		for(i=1;i<=t;i++)
			if(map[u][i]>0&&dis[u]==dis[i]+1)
				break;	
		if(i<=t){	//找到一条通路 
			pre[i]=u;
			u=i;	//往下走 
			if(i==t){						//若走到汇点则回溯 
				low=inf;
				for(int j=i;j!=s;j=pre[j])	//寻找这条路上的最大堵塞流 
					if(low>map[pre[j]][j])
						low=map[pre[j]][j];
				maxflow+=low;
				
				for(int j=i;j!=s;j=pre[j]){	//设置为回路 
					map[pre[j]][j]-=low;
					map[j][pre[j]]+=low;
				}
				u=s;						//从源点继续搜 
			}
		}else{								//找不到通路 
			mindis=t;
			for(i=1;i<=t;i++)
				if(map[u][i]>0&&mindis>dis[i])
					mindis=dis[i];
			
			gap[dis[u]]--;
			
			if(gap[dis[u]]==0&&gap[dis[u]+1]==0)				//出现断层 
				break;		
											
			dis[u]=mindis+1;
			gap[dis[u]]++;
			u=pre[u];
			
		}
		
	}
	return maxflow;
}


int main(){
	freopen("in.txt","r",stdin);
	
	int n,m,u,v,cap;
	
    while(~scanf("%d%d",&m,&n)){
    	
		memset(map,0,sizeof(map));
		
		for(int i=1;i<=m;i++){
			scanf("%d%d%d",&u,&v,&cap);
			map[u][v]+=cap;
		}
		printf("%d\n",SAP(1,n));
	}
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator