最大流 费用流 Dinic && ISAP
Dinic:
int vis[MAXN], d[MAXN]; bool bfs(cint s, cint t){ queue<int> q; q.push(s); memset(vis, 0, sizeof(vis)); d[s]=0; vis[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=h[u]; i!=-1; i=e[i].nxt){ int v=e[i].v, cap=e[i].cap, ef=e[i].flow; if(!vis[v] && cap>ef){ d[v]=d[u]+1; vis[v]=1; q.push(v); } } } return vis[t]==1; } int cur[MAXN]; int dfs(int u, int a, cint &t){ if(u==t || !a) return a; int f, flow=0; for(int &i=cur[u]; i!=-1; i=e[i].nxt){ int v=e[i].v, cap=e[i].cap, ef=e[i].flow; if(d[v]==d[u]+1 && (f=dfs(v, MIN(a, cap-ef), t))>0){ //注意>0不要放错地方了,会WA的。。。 flow+=f; e[i].flow+=f; e[i^1].flow-=f; a-=f; if(!a) break; } } return flow; } int Dinic(cint s, cint t, cint n){ int i, flow=0; while(bfs(s, t)){ for(i=0; i<n; i++) cur[i]=h[i]; flow+=dfs(s, INF, t); } return flow; }
ISAP:
int cur[MAXN], d[MAXN]; bool done[MAXN]; void bfs(int t){ //reverse bfs queue<int> q; memset(done, 0, sizeof(done)); done[t]=true; d[t]=0; q.push(t); while(!q.empty()){ int u=q.front(); q.pop(); for(int i=h[u]; i!=-1; i=e[i].nxt){ int v=e[i^1].u, flow=e[i^1].flow, cap=e[i^1].cap; //attention 'u' if(cap>flow && !done[v]){ done[v]=true; d[v]=d[u]+1; q.push(v); } } } } int num[MAXN], p[MAXN]; int Augment(int s, int t){ //similar to Edmonds-Karp int u=t, a=INF; while(u!=s){ a=MIN(a, e[p[u]].cap-e[p[u]].flow); u=e[p[u]].u; } for(u=t; u!=s; u=e[p[u]].u){ e[p[u]].flow+=a; e[p[u]^1].flow-=a; } return a; } int isap(int s, int t){ int flow=0, i; bfs(t); memset(num, 0, sizeof(num)); for(i=0; i<t+1; i++) num[d[i]]++; int u=s; for(i=0; i<t+1; i++) cur[i]=h[i]; while(d[s]<t+1){ if(u==t){ flow+=Augment(s, t); u=s; } bool ok=false; for(int i=cur[u]; i!=-1; i=e[i].nxt){ //advance int v=e[i].v, flow=e[i].flow, cap=e[i].cap; if(cap>flow && d[u]==d[v]+1){ ok=true; p[v]=i; cur[u]=i; u=v; break; } } if(!ok){ //retreat int tmp=t; for(int i=h[u]; i!=-1; i=e[i].nxt) if(e[i].cap>e[i].flow) tmp=MIN(tmp, d[e[i].v]); if(--num[d[u]]==0) break; //gap improvement num[d[u]=tmp+1]++; cur[u]=h[u]; if(u!=s) u=e[p[u]].u; } } return flow; }
费用流:
int d[MAXN], p[MAXN], inq[MAXN]; int a[MAXN]; void mcmf(cint s, cint t, cint n, int &mincst, int &maxflow){ mincst=maxflow=0; while(1){ queue<int> q; q.push(s); memset(inq, 0, sizeof(inq)); for(int i=0; i<n; i++) d[i]=INF; inq[s]=1; d[s]=0; a[s]=INF; while(!q.empty()){ int u=q.front(); q.pop(); inq[u]=0; for(int i=h[u]; i!=-1; i=e[i].nxt){ int v=e[i].v, cap=e[i].cap, ef=e[i].flow, cst=e[i].cst; if(d[v]>d[u]+cst && cap>ef){ d[v]=d[u]+cst; a[v]=MIN(a[u], cap-ef); p[v]=i; if(!inq[v]) q.push(v), inq[v]=1; } } } if(d[t]==INF) break; maxflow+=a[t]; mincst+=a[t]*d[t]; for(int u=t; u!=s; u=e[p[u]].u){ e[p[u]].flow+=a[t]; e[p[u]^1].flow-=a[t]; } } }