hdu3549及最大流ISAP模板

经过了几天的细心研究,终于把ISAP写出来了,直接上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define rep(i,a,b)	for (int i=a;i<(b+1);i++)
using namespace std;
int n,m;
int G[300][300]={0},d[500]={0},iter[300]={0},hash[300]={0},pre[300]={0};
bool vis[300]={false};
void bfs(){
	memset(d,-1,sizeof d);
	memset(vis,0,sizeof vis);
	queue<int> q;
	q.push(n);
	vis[n]=true;
	d[n]=0;
	while (!q.empty()){
		int cur=q.front();
		q.pop();
		rep(i,1,n)	if (!vis[i]&&G[i][cur]>0){
			vis[i]=true;
			d[i]=d[cur]+1;
			q.push(i);
		}
	}
}
int augment(){//增广 
	int f=0x3f3f3f3f;
	for (int i=n;i!=1;i=pre[i])	f=min(f,G[pre[i]][i]);
	for (int i=n;i!=1;i=pre[i]){
		G[pre[i]][i]-=f;
		G[i][pre[i]]+=f;
	}	
	return f;
}
int Max_flow(){
	int flow=0;
	bfs();
	memset(hash,0,sizeof hash);
	rep(i,1,n)	iter[i]=1;//当前弧优化 
	rep(i,1,n)	hash[d[i]]++;//gap 优化 
	int u=1;
	while (d[1]<n){
		if (u==n){
			flow+=augment();
			u=1;
		}
		bool advanced=false;
		for (int &i=iter[u];i<=n;i++)	if (G[u][i]>0&&d[u]==d[i]+1){
			advanced=true;
			pre[i]=u;
			u=i;
			break;
		}
		if (!advanced){//retreat
			int m=n;
			rep(i,1,n)	if (G[u][i]>0&&~d[i])	m=min(m,d[i]);
			if (--hash[d[u]]==0)	break;    //gap优化  
			d[u]=m+1;
			hash[d[u]]++;
			iter[u]=1;
			if (u!=1)	u=pre[u];
		}
	}
	return flow;
}
int main(){
	int T;
	scanf("%d",&T);
	rep(z,1,T){
		scanf("%d%d",&n,&m);
		memset(G,0,sizeof G);
		rep(i,1,m){
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			G[x][y]+=z;
		}
		printf("Case %d: %d\n",z,Max_flow());
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值