【網絡流】【模板】luogu P3376 網絡最大流

LinkLink

LuoguLuogu P3376P3376

DescriptionDescription

如題,給出一個網絡圖,以及其源點和匯點,求出其網絡最大流。

InputInput

第一行包含四個正整數N、M、S、T,分別表示點的個數、有向邊的個數、源點序號、匯點序號。

接下來M行每行包含三個正整數ui、vi、wi,表示第i條有向邊從ui出發,到達vi,邊權爲wi(即該邊最大流量爲wi)

OutputOutput

一行,包含一個正整數,即爲該網絡的最大流。

SampleSample InputInput

4 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 40

SampleSample OutputOutput

50

HintHint

時空限制:1000ms,128M

數據規模:

對於30%的數據:N<=10,M<=25

對於70%的數據:N<=200,M<=1000

對於100%的數據:N<=10000,M<=100000

樣例說明:

題目中存在3條路徑:

4–>2–>3,該路線可通過20的流量

4–>3,可通過20的流量

4–>2–>1–>3,可通過10的流量(邊4–>2之前已經耗費了20的流量)

故流量總計20+20+10=50。輸出50。

TrainTrain ofof ThoughtThought

DinicDinic算法,每次用bfsbfs求出增廣路,然後用dfsdfs增廣就好了

增廣路:

CodeCode

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

const int inf = 1e9;
int t, n, m, s, tt, ans;
int dis[10005], h[200005];

struct node
{
	int y, w, op, next;
}g[200005];

void add(int x, int y, int w)
{
	g[++tt] = (node){y, w, tt + 1, h[x]}; h[x] = tt;//連正向邊
	g[++tt] = (node){x, 0, tt - 1, h[y]}; h[y] = tt;//連反向邊 
}

bool bfs()
{
	queue<int>Q;
	for (int i = 1; i <= n; ++i) dis[i] = inf;
	dis[s] = 0; Q.push(s);
	while (Q.size()) { 
		int x = Q.front(); Q.pop();
		for (int i = h[x]; i; i = g[i].next)
		{
			int y = g[i].y;
			if (dis[y] > dis[x] + 1 && g[i].w)
			{
				dis[y] = dis[x] + 1;//尋找增廣路
				Q.push(y);
				if (y == t) return 1;
			}
		}
	} 
	return 0;
}

int dfs(int x, int maxf)
{
	if (x == t) return maxf;
	int ret = 0;//表示當前點的流量
	for (int i = h[x]; i; i = g[i].next)
	{
		int y = g[i].y;
		if (g[i].w && dis[y] == dis[x] + 1) {
			int xx = dfs(y, min(g[i].w, maxf - ret));//按照增廣路增廣
			if (!xx) dis[y] = -1;
			g[i].w -= xx; //正向邊的殘餘流量減去當前流量
			g[g[i].op].w += xx;//反向邊的可流量就加上這一流量
			ret += xx;//加入總流量
			if (ret == maxf) break;
		}
	}
	return ret;
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	for (int i = 1; i <= m; ++i)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		add(u, v, w);//連邊
	} 
	while (bfs())
		ans += dfs(s, inf);
	printf("%d", ans);
}
發佈了224 篇原創文章 · 獲贊 35 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章