【网络流第二步】Hdu 1532——Drainage Ditches 邻接矩阵版

不多说,HDU卡数据还是挺厉害的

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#include<math.h>
#define maxn 205
#define INF 100000000
using namespace std;

//Template Bade By: Xiaobin Chen
int pointnum,edgenum;// pointnum点数,edgenum边数,s起点,t终点
int map[maxn][maxn],fa[maxn],gap[maxn],level[maxn];//map有向图,fa父节点,
//gap[i]=j表示以汇点距离为i的点有j个,level[i]=j表示点i与汇点距离为j 

void sap_bfs(int t)
{
	memset(level,1,sizeof(level));
	memset(gap,0,sizeof(gap));
	queue<int> q;
	q.push(t);
	level[t]=0;
	gap[level[t]]++;
	while(!q.empty())
	{
		int temp=q.front(); q.pop();
		for(int i=1;i<=pointnum;i++)  
		if(level[i]>pointnum && map[i][temp]>0)
		{
			q.push(i);
			level[i]=level[temp]+1;
			gap[level[i]]++;
		}
	}
}

int fine_path(int u)//查找残量网络中是否有与u相连 且距离为1的点 
{
	for(int i=1;i<=pointnum;i++) if(map[u][i]>0 && level[u]==level[i]+1)
		return i;
	return -1;
}

int Advance(int s,int t)//找到汇点时进行增广 
{
	int i,minflow=INF;
	for(i=t;i!=s;i=fa[i]) if(minflow>map[fa[i]][i])//查找这条增广路中最小的流量 
	{
		minflow=map[fa[i]][i];
	}
	for(i=t;i!=s;i=fa[i])
	{
		map[fa[i]][i]-=minflow;
		map[i][fa[i]]+=minflow;//反向边也要操作 
	}
	return minflow;
}

int retreat(int u)//对点u重新设置最小的距离 
{
	int fine=INF;
	for(int i=1;i<=pointnum;i++) if(map[u][i]>0 && fine>level[i]+1)
		fine=level[i]+1;
	if(fine==INF) fine=pointnum;//找不到的话设置为最大,即点u不会再被经过 
	return fine;
}

int sap(int s,int t)
{
	sap_bfs(t);
	int i,j,v,u=s,flow=0;//初始化 
	while(level[s]<=pointnum)//源点与汇点距离小于pointnum时执行,要是不存在源点到汇点的通路直接跳出 
	{
		v=fine_path(u);// 找u的下一个点 
		if(v>0)
		{
			fa[v]=u;//找到后标记父节点 
			u=v;//把v赋值给u,如果不是汇点,直接跳回75行了 
			if(u==t)
			{
				flow+=Advance(s,t);
				u=s;//找的一条路径后重新查找 
			}
		}
		else
		{
			if(--gap[level[u]]==0) return flow;//如果其中一个距离个数为0,即出现断层,没有通路看,直接跳出 
			v=retreat(u);
			gap[v]++;
			level[u]=v;
			if(u!=s) u=fa[u];
		}
	}
	return flow;
}

int main()
{

	int i,j,a,b,x;
	while(~scanf("%d%d",&edgenum,&pointnum))
	{
		memset(map,0,sizeof(map));
		for(i=0;i<edgenum;i++)
		{
			cin>>a>>b>>x;
			map[a][b]+=x;
		}
		int ans=sap(1,pointnum);
		cout<<ans<<endl;
	}
	return 0;
}


 

你可能感兴趣的:(【网络流第二步】Hdu 1532——Drainage Ditches 邻接矩阵版)