题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289
5 6 5 3 5 2 3 4 12 1 5 5 4 2 3 2 4 4 3 2 1
3
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 3017;//点数的最大值 const int MAXM = 100017;//边数的最大值 const int INF = 0x3f3f3f3f; struct Edge { int to, cap, flow; int next; }edge[MAXM];//注意是MAXM int tol; int head[MAXN]; int dep[MAXN],pre[MAXN],cur[MAXN]; int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y void init() { tol = 0; memset(head,-1,sizeof (head)); } //加边,单向图三个参数,双向图四个参数 void addedge (int u,int v,int w,int rw=0) { edge[tol].to = v;edge[tol].cap = w; edge[tol].next = head[u]; edge[tol].flow = 0; head[u] = tol++; edge[tol].to = u;edge[tol].cap = rw; edge[tol]. next = head[v]; edge[tol].flow = 0;head[v]=tol++; } //输入参数:起点、终点、点的总数 //点的编号没有影响,只要输入点的总数 int sap(int start,int end, int N) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u = start; pre[u] = -1; gap[0] = N; int ans = 0; int i; while(dep[start] < N) { if(u == end) { int Min = INF; for( i = pre[u];i != -1; i = pre[edge[i^1]. to]) { if(Min > edge[i].cap - edge[i]. flow) Min = edge[i].cap - edge[i].flow; } for( i = pre[u];i != -1; i = pre[edge[i^1]. to]) { edge[i].flow += Min; edge[i^1].flow -= Min; } u = start; ans += Min; continue; } bool flag = false; int v; for( i = cur[u]; i != -1;i = edge[i].next) { v = edge[i]. to; if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = pre[v] = i; break; } } if(flag) { u = v; continue; } int Min = N; for( i = head[u]; i != -1; i = edge[i]. next) { if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } } gap[dep[u]]--; if(!gap[dep[u]]) return ans; dep[u] = Min+1; gap[dep[u]]++; if(u != start) u = edge[pre[u]^1].to; } return ans; } int main() { int n,m; int a,b; int c,s,t; int i; while(scanf("%d%d",&n,&m)!=EOF) { init();//初始化 scanf("%d%d",&s,&t);//源点,汇点 int w; // int ds = 0, dt = 2*n+1;//超级源点,超级汇点,初始化 for(i = 1; i <= n; i++) { scanf("%d",&w);//每个顶点的值 addedge(i,i+n,w,0);//对于每个节点id,拆成 id 和 id+n 两个点 } for(i = 1; i <= m; i++)//边数 { scanf("%d%d",&a,&b); addedge(a+n,b,INF,0); addedge(b+n,a,INF,0); } // addedge(ds,s,INF,0);//添加超级源点 // addedge(t+n,dt,INF,0);//添加超级汇点 // int ans = sap(ds, dt, 2*(n+1));// 总节点数的变化 int ans = sap(s, t+n, 2*n); printf("%d\n",ans); } return 0; }
hdu 4289 Control(网络流 最大流+拆点)(模板),布布扣,bubuko.com
hdu 4289 Control(网络流 最大流+拆点)(模板)
原文地址:http://blog.csdn.net/u012860063/article/details/38460899