先来一个队长的矩阵SAP #define M 1000 int maze[M][M]; int gap[M],dis[M],pre[M],cur[M]; int sap(int s,int t,int nodenum) { CC(cur,0);CC(dis,0);CC(gap,0); int u = pre[s] = s,maxflow = 0,aug = -1; gap[0] = nodenum; while(dis[s] < nodenum) { loop: FOR(v,cur[u],nodenum) if(maze[u][v] && dis[u] == dis[v] + 1) { checkmin(aug,maze[u][v]); pre[v] = u; u = cur[u] = v; if(v == t) { maxflow += aug; for(u = pre[u];v != s;v = u,u = pre[u]) { maze[u][v] -= aug; maze[v][u] += aug; } aug = -1; } goto loop; } int mindis= nodenum-1; FF(v,nodenum) if(maze[u][v] && mindis> dis[v]) { cur[u] = v; mindis= dis[v]; } if((--gap[dis[u]])== 0) break; gap[dis[u] = mindis+1] ++; u = pre[u]; } return maxflow; } 仰慕sha崽。。吼吼 接下来“自己”的模板(其实也是参考别人的,改改变量名~) 静态邻接表SAP #define N 2505 #define M 20000 struct Graph { struct node { int v,next,flow; node(){}; node(int a,int b,int c):next(a),v(b),flow(c){}; }E[M*2]; int pre[N]; int head[N]; int cur[N]; int dis[N]; int NV,NE; int gap[N]; void init(int n) { memset(head,-1,sizeof(head)); NE=0; NV=n; } void insert(int u,int v,int w) { E[NE]=node(head[u],v,w); head[u]=NE++; E[NE]=node(head[v],u,0); head[v]=NE++; } int SAP(int s,int t) { memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); for(int i=0;i<NV;i++) cur[i]=head[i]; int u=pre[s]=s; int maxflow=0,aug=INT_MAX; gap[0]=NV; while(dis[s]<NV) { loop: for(int &i=cur[u];i!=-1;i=E[i].next) { int v=E[i].v; if(E[i].flow&&dis[u]==dis[v]+1) { if(aug>E[i].flow) aug=E[i].flow; pre[v]=u; u=v; if(v==t) { maxflow+=aug; for(u=pre[u];v!=s;v=u,u=pre[u]) { E[cur[u]].flow -= aug; E[cur[u]^1].flow += aug; } aug = INT_MAX; } goto loop; } } int mindis=NV; for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v; if(E[i].flow&&mindis>dis[v]) { cur[u]=i; mindis=dis[v]; } } if(--gap[dis[u]]==0) break; gap[dis[u]=mindis+1]++; u=pre[u]; } return maxflow; } }G; 静态邻接表EK #define N 201 #define M 201 struct Graph { struct node { int v,next,w; node(){}; node(int a,int b,int c):next(a),v(b),w(c){}; }E[M*2]; int pre[N]; int head[N]; int path[N]; int NV,NE; void init(int n) { memset(head,-1,sizeof(head)); NE=0; NV=n; } void insert(int u,int v,int w) { E[NE]=node(head[u],v,w); head[u]=NE++; } int EK(int s,int t) { int maxflow=0; while(true) { queue<int> q; memset(pre,-1,sizeof(pre)); q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v; if(pre[v]==-1&&E[i].w>0) { pre[v]=u; q.push(v); path[v]=i; } } if(pre[t]!=-1) break; } if(pre[t]==-1) break; int Min=INT_MAX; for(int v=t;v!=s;v=pre[v]) { if(E[path[v]].w<Min) Min=E[path[v]].w; } for(int v=t;v!=s;v=pre[v]) { E[path[v]].w-=Min; E[path[v]^1].w+=Min; } maxflow+=Min; } return maxflow; } }G; 静态邻接表 最小费用最大流 struct Graph { struct node { int v,next,w,flow; node(){}; node(int a,int b,int c,int d){ next=a;v=b;w=c;flow=d; } }E[M]; int head[N]; int pre[N]; int dis[N]; bool h[N]; int path[N]; int NE,NV; void init(int n) { NE=0; NV=n; memset(head,-1,sizeof(head)); } void insert(int u,int v,int w,int flow) { E[NE]=node(head[u],v,w,flow); head[u]=NE++; E[NE]=node(head[v],u,-w,0); head[v]=NE++; } bool update(int u,int v,int w) { if(dis[u]+w<dis[v]) { dis[v]=dis[u]+w; return true; } return false; } bool spfa() { memset(pre,-1,sizeof(pre)); memset(h,0,sizeof(h)); memset(dis,0x3f,sizeof(dis)); dis[beg]=0; queue<int> q; q.push(beg); while(!q.empty()) { int u=q.front(); q.pop(); h[u]=0; for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v; if(E[i].flow>0&&update(u,v,E[i].w)) { pre[v]=u; path[v]=i; if(!h[v]) { h[v]=1; q.push(v); } } } } if(pre[end]==-1) return false; return true; } int mincost_maxflow() { int flow=0; int ans=0; while(spfa()) { int Min=INT_MAX; for(int i=end;i!=beg;i=pre[i]) if(Min>E[path[i]].flow) Min=E[path[i]].flow; for(int i=end;i!=beg;i=pre[i]) { E[path[i]].flow-=Min; E[path[i]^1].flow+=Min; } flow+=Min; ans+=dis[end]; } if(flow!=(NV-1)/2) return -1; return ans; } }G;