| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
不合并源点解法
#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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator