dinic模板
procedure addedge(u,v,cap:longint); begin sid[tot].u:=u; sid[tot].v:=v; sid[tot].cap:=cap; sid[tot].next:=nd[u]; nd[u]:=tot; inc(tot); sid[tot].u:=v; sid[tot].v:=u; sid[tot].cap:=0; sid[tot].next:=nd[v]; nd[v]:=tot; inc(tot); end;
function bfs:boolean; var i,head,tail,u,p:longint; begin for i:=0 to n*m+1 do dep[i]:=-1; dep[0]:=0; head:=1;tail:=1;dl[1]:=0; while head<=tail do begin u:=dl[head]; p:=nd[dl[head]]; while p<>-1 do begin if (sid[p].cap>0) and (dep[sid[p].v]=-1) then begin dep[sid[p].v]:=dep[u]+1; if sid[p].v=n*m+1 then exit(true); inc(tail); dl[tail]:=sid[p].v; end; p:=sid[p].next; end; inc(head); end; exit(false); end; function dinic:longint; var top,i,u,mi,last:longint; begin dinic:=0; while bfs do begin fillchar(stack,sizeof(stack),0); top:=0; for i:=0 to n*m+1 do cur[i]:=nd[i]; u:=0; while true do begin if u=n*m+1 then begin mi:=maxlongint; for i:=1 to top do begin if sid[stack[i]].cap<mi then begin last:=i; mi:=sid[stack[i]].cap; end; end; for i:=1 to top do begin dec(sid[stack[i]].cap,mi); inc(sid[stack[i] xor 1].cap,mi); end; top:=last-1; dinic:=dinic+mi; u:=sid[stack[last]].u; end; while cur[u]<>-1 do begin if (dep[sid[cur[u]].v]=dep[u]+1) and (sid[cur[u]].cap<>0) then break else cur[u]:=sid[cur[u]].next; end; if cur[u]=-1 then begin if u=0 then break; dep[u]:=-1; u:=sid[stack[top]].u; dec(top); end else begin inc(top); stack[top]:=cur[u]; u:=sid[cur[u]].v; end; end; end; end;
最大流=最小割=正点权和-最大闭合权图
其中求最大闭合权图时,源点向所有点权为正的点连容量为点权的边,所有点权为负的点向汇点连容量为点权绝对值的边
表示约束关系的边容量为无穷大,i前必须做j,i连向j
-----------------------------------------------------------------------------------------------
void addedge2(int u,int v,int cap){ sid[cnt].next=nd[u];sid[cnt].des=v;sid[cnt].cap=cap;nd[u]=cnt;sid[cnt].fr=u;cnt++; sid[cnt].next=nd[v];sid[cnt].des=u;sid[cnt].cap=0;nd[v]=cnt;sid[cnt].fr=v;cnt++; } int bfs(){ memset(dep,-1,sizeof(dep)); int head=1,tail=1; dep[sor]=0;dl[head]=sor; while (head<=tail){ for (int p=nd[dl[head]];p!=-1;p=sid[p].next) if ((dep[sid[p].des]==-1)&&(sid[p].cap)) dep[sid[p].des]=dep[dl[head]]+1,dl[++tail]=sid[p].des; head++; } if (dep[tar]==-1) return(0);else return(1); } int dinic(){ int maxflow=0; while (bfs()){ for (int i=0;i<=tar;i++) cur[i]=nd[i]; int u=sor,top=0; while(1){ if (u==tar){ int mi=1e9,last; for (int i=1;i<=top;i++) if (sid[sta[i]].cap<mi) {mi=sid[sta[i]].cap;last=i;} for (int i=1;i<=top;i++) sid[sta[i]].cap-=mi,sid[sta[i]^1].cap+=mi; u=sid[sta[last]].fr;cur[u]=sid[cur[u]].next;top=last-1; maxflow+=mi; continue; } while((cur[u]!=-1)&&((sid[cur[u]].cap==0)||(dep[sid[cur[u]].des]!=dep[u]+1))) cur[u]=sid[cur[u]].next; if (cur[u]!=-1){sta[++top]=cur[u];u=sid[cur[u]].des;continue;} else{ if (u==sor) break; dep[u]=-1; u=sid[sta[top--]].fr; continue; } } } return(maxflow); }