Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

不合并源点解法

Posted by a280920481 at 2018-12-04 23:36:10 on Problem 1149
#include <iostream>
using namespace std;


struct Edge
{
	int to;
	int cap;
	int rev;
}edge[1101][102];// edge[i][j] : 与节点 i 相连的第 j 条边, 易证 j <= 100
// [1, M] 为源点, [M + 1, M + N]为顾客节点, M + N + 1 为汇点

int deg[1101];//节点的度

int sc[1001];//源点最大流量

int ep[1001];// ep[i] : 最后一个与源点 i 连接的节点

bool connected[101][101];// connected[i][j] : 是否存在边 e = (i, j)

bool used[1101];//节点是否已被搜索

int dfs(int v, int flow);//返回当前路径最大流

int T;//汇点

int main()
{
	int M, N, A, K, B;
	Edge e;//添加边时用的临时变量

	cin >> M >> N;

	T = M + N + 1;// M + N + 1 为汇点

	for (int i = 1; i <= M; i++)
	{
		cin >> sc[i];//源点 i 的最大流量
		used[i] = true;
	}

	for (int i = 1; i <= N; i++)
	{
		cin >> A;//有 A 个源点与节点 i 相连

		for (int j = 1; j <= A; j++)
		{
			cin >> K;//与节点 i 相连的源点

			if (ep[K] && (!connected[ep[K]][i]))
			{
				connected[ep[K]][i] = true;

				//添加一条 M + ep[K] 到 M + i 的无限流量的边
				e.to = M + i;
				e.cap = 1 << 30;
				e.rev = deg[M + i];//记录反向边
				edge[M + ep[K]][deg[M + ep[K]]] = e;

				//添加一条 M + i 到 M + ep[K] 的流量为 0 的反向边
				e.to = M + ep[K];
				e.cap = 0;
				e.rev = deg[M + ep[K]];//记录反向边
				edge[M + i][deg[M + i]] = e;

				deg[M + ep[K]]++;
				deg[M + i]++;
			}

			ep[K] = i;//将最后一个与 K 相连的节点设为 i

			//添加一条 K 到 M + i 的无限流量的边
			e.to = M + i;
			e.cap = 1 << 30;
			e.rev = 101;//不需要记录反向边
			edge[K][deg[K]++] = e;
		}

		cin >> B;//节点 i 到汇点的最大流量

		//添加一条 M + i 到 T 的流量为 B 的边
		e.to = T;
		e.cap = B;
		e.rev = 101;//不需要记录反向边
		edge[M + i][deg[M + i]++] = e;
	}


	int num = M, d;

	while (num)
	{
		for (int i = M + 1; i <= T; i++)
		{
			used[i] = false;
		}

		d = dfs(num, sc[num]);
		sc[num] -= d;

		if ((!sc[num]) || (!d))
		{
			num--;
		}
	}

	// edge[T][101] 记录了汇点的流入量
	cout << edge[T][101].cap << '\n';

	return 0;
}

int dfs(int v, int flow)
{
	static int d;// d 可以循环使用

	if (v == T)
	{
		return flow;
	}

	for (int i = 0; i < deg[v]; i++)
	{
		if ((!used[edge[v][i].to]) && edge[v][i].cap)
		{
			d = edge[v][i].cap;
			if (d > flow)
			{
				d = flow;
			}

			used[edge[v][i].to] = true;
			d = dfs(edge[v][i].to, d);

			if (d)
			{
				edge[v][i].cap -= d;
				edge[edge[v][i].to][edge[v][i].rev].cap += d;
				return d;
			}
		}
	}

	return 0;
}


Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator