hdu4280Island Transport

本文介绍了一种用于解决最大流问题的高效算法——ISAP。该算法通过预流推进技术和间隙法则来加速寻找增广路径的过程,相较于传统的Ford-Fulkerson算法具有更好的时间效率。文章通过具体的实现代码展示了ISAP算法的具体应用。
摘要由CSDN通过智能技术生成

这题就是卡时间的,换成ISAP或时间更优的算法就好了。

/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2016
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1e5 + 10;
int n, m;
struct Edge{
	int from, to, cap, flow;
	Edge(){}
	Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){}
};
struct ISAP{
	int p[maxn], num[maxn], cur[maxn], d[maxn];
	int s, t, n, m;
	bool vis[maxn];

	vector<int> G[maxn];
	vector<Edge> edges;

	void init(int n) {
		this->n = n;
		for (int i = 0;i <= n;++i) {
			G[i].clear();
			d[i] = INF;
		}
		edges.clear();
	}

	void addedge(int from,int to,int cap) {
		edges.push_back(Edge(from, to, cap, 0));
		edges.push_back(Edge(to, from, 0, 0));
		m = (int)edges.size();
		G[from].push_back(m - 2);
		G[to].push_back(m - 1);
	}

	bool bfs() {
		memset(vis, false,sizeof vis);

		queue<int> que;
		d[t] = 0;
		vis[t] = true;
		que.push(t);

		while(!que.empty()) {
			int u = que.front();
			que.pop();

			for (int i = 0;i < G[u].size();++i) {
				Edge& e = edges[G[u][i]^1];
				if (e.cap > e.flow && !vis[e.from]) {
					vis[e.from] = true;
					d[e.from] = d[u] + 1;
					que.push(e.from);
				}
			}
		}
		return vis[s];
	}

	int Augment() {
		int u = t, flow = INF;
		while(u != s) {
			Edge& e = edges[p[u]];
			flow = min(flow, e.cap - e.flow);
			u = edges[p[u]].from;
		}

		u = t;
		while(u != s) {
			edges[p[u]].flow += flow;
			edges[p[u]^1].flow -= flow;
			u = edges[p[u]].from;
		}
		return flow;
	}

	int MaxFlow(int s,int t) {
		this->s = s,this->t = t;
		int ret = 0;
		bfs();
		if (d[s] >= n) return 0;

		memset(num, 0,sizeof num);
		memset(cur, 0,sizeof cur);
		for (int i = 0;i < n;++i) {
			if (d[i] < INF) num[d[i]]++;
		}
		int u = s;

		while(d[s] < n) {

			if (u == t) {
				ret += Augment();
				u = s;
			}

			bool ok = false;
			for (int i = cur[u];i < G[u].size();++i) {
				Edge& e = edges[G[u][i]];
				if (e.cap > e.flow && d[u] == d[e.to] + 1) {
					ok = true;
					p[e.to] = G[u][i];
					cur[u] = i;
					u = e.to;
					break;
				}
			}

			if (!ok) {
				int Min = n - 1;
				for (int i = 0;i < G[u].size();++i) {
					Edge& e = edges[G[u][i]];
					if (e.cap > e.flow) Min = min(Min, d[e.to]);
				}
				if (--num[d[u]] == 0) break;
				num[d[u] = Min + 1]++;
				cur[u] = 0;
				if (u != s) u = edges[p[u]].from;
			}
		}
		return ret;
	}
};
ISAP isap;
void init() {
	scanf("%d%d",&n,&m);
	isap.init(n);

	int x, y;
	int Min = INF, Max = -INF;

	int s, t;
	for (int i = 1;i <= n;++i) {
		scanf("%d%d",&x,&y);
		if (x <= Min) {
			s = i;
			Min = x;
		}
		if (x >= Max) {
			Max = x;
			t = i;
		}
	}
	int u, v, c;
	for (int i = 0;i < m;++i) {
		scanf("%d%d%d",&u,&v,&c);
		isap.addedge(u, v, c);
		isap.addedge(v, u, c);
	}

	int ans = isap.MaxFlow(s, t);
	printf("%d\n", ans);
}
int main()
{	
	// freopen("in.txt","r",stdin);
	// freopen("out.txt","w",stdout);
	int tt;
	scanf("%d",&tt);
	while(tt--) {
		init();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值