bzoj1570

本文介绍了一种基于分层图的最大流算法实现方法。通过构造分层图并使用最大流算法解决特定问题,该算法适用于求解网络流量优化等场景。文章提供了详细的代码示例及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一道挺裸的题~~~~

分层建图,常用技巧~~~~

最大流。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int amountt[3000];
int daytot = 0;
const int inf = 1000000000;
struct tedgee
{
	int from, to, cap;
};
tedgee tedge[3000];
struct edgee
{
	int from, to, cap;
	edgee(int f, int t, int cap) :from(f), to(t), cap(cap)
	{}
	edgee()
	{}
};
edgee edge[300000];
int first[150000], nextt[300000],tfirst[150000];
int edgetot;
int num[60][3000];
int n, m, allamount;
int day,all;
int height[150000];
void addedge(int from, int to,int cap)
{
	nextt[edgetot] = tfirst[from];
	tfirst[from] = edgetot;
	edge[edgetot++] = edgee(from, to, cap);
	nextt[edgetot] = tfirst[to];
	tfirst[to] = edgetot;
	edge[edgetot++] = edgee(to, from, 0);
}
bool bfs(int s, int t)
{
	for (int i = 0; i < day; i++)
	{
		height[i] =-1;
		first[i] = tfirst[i];
	}
	height[num[1][0]] = 0;
	queue<int>que;
	que.push(num[1][0]);
	while (!que.empty())
	{
		int now = que.front();
		que.pop();
		for (int i = tfirst[now]; i != -1; i = nextt[i])
		{
			int to = edge[i].to;
			if (height[to] == -1&&edge[i].cap > 0)
			{
				height[to] = height[now] + 1;
				que.push(to);
			}
		}
	}
	return height[t] == -1 ? false : true;
}
int dfs(int now, int cap,int t)
{
	if (now == t)
	{
		return cap;
	}
	for (int &i = first[now]; i != -1; i = nextt[i])
	{
		int to = edge[i].to;
		if (height[to] > height[now] && edge[i].cap > 0)
		{
			int d = dfs(to, min(cap, edge[i].cap), t);
			if (d > 0)
			{
				edge[i].cap -= d;
				edge[i ^ 1].cap += d;
				return d;
			}
		}
	}
	return 0;
}
bool flow(int s, int t)
{
	while (bfs(s, t))
	{
		int d = 0;
		while ((d = dfs(s, inf, t)))
		{
			all += d;
		}
	}
	return all >= allamount;
}
bool test(int dayy)
{
	for (int i = 1; i <= n; i++)
	{
		tfirst[day] = -1;
		num[i][dayy] = day++;
		addedge(num[i][dayy-1], num[i][dayy], inf);
	}
	int s = num[1][0]; int t = num[n][dayy];
	for (int i = 0; i < m; i++)
	{
		int from = tedge[i].from; int to = tedge[i].to; int cap = tedge[i].cap;
		addedge(num[from][dayy - 1], num[to][dayy], cap);
	}
	return flow(num[1][0], num[n][dayy]);
}
int main()
{
	scanf("%d%d%d", &n, &m, &allamount);
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &tedge[i].from, &tedge[i].to,&tedge[i].cap);
	}
	for (int i = 1; i <= n; i++)
	{
		tfirst[day] = -1;
		num[i][0] = day++;
	}
	int tday = 1;
	while (!test(tday))
		tday++;
	printf("%d\n", tday);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值