| ||||||||||
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