我的作业部落有学习资料
Dinic 模板
#define rg register #define _ 10001 #define INF 2147483647 #define min(x,y) (x)<(y)?(x):(y) using namespace std; int n,m,s,t,record[_],num_of_edges=-1,cur[_],team[10000001],depth[_]; struct pp { int next,to,w; }edge[(_<<4)+(_<<2)]; inline int read() { rg int save=0,w=1;rg char q=getchar(); while(q<'0'||q>'9'){if(q=='-')w=-1;q=getchar();} while(q>='0'&&q<='9')save=(save<<3)+(save<<1)+q-'0',q=getchar(); return save*w; } inline void add(rg int from,rg int to,rg int ww) { edge[++num_of_edges]=(pp){record[from],to,ww}; record[from]=num_of_edges; } inline bool bfs() { rg int head=0,tail=1; for(rg int i=1;i<=n;++i)depth[i]=0;//depth[]初值为-1,免得返回出发点 depth[s]=1; team[1]=s; do { head++; rg int u=team[head]; for(rg int j=record[u];j!=-1;j=edge[j].next) { rg int to=edge[j].to; if((!depth[to])&&(edge[j].w>0)) { depth[to]=depth[u]+1; team[++tail]=to; if(to==t)return 1; } } }while(head<tail); return 0; } int dfs(rg int u,rg int flow)//找到每条路上的最小残余流量,因此需在回溯时更新每条边的流量 { if(u==t)return flow; for(rg int &j=cur[u]/*当前弧优化*/;j!=-1;j=edge[j].next) { rg int to=edge[j].to; if(depth[to]==depth[u]+1&&(edge[j].w>0)) { rg int D=dfs(to,min(flow,edge[j].w));//到终点的过程中一直在取min if(D>0) { edge[j].w-=D,edge[j^1].w+=D; return D;//每次只找一条可流通路满上(这里就不管现实中物理的联通器原理了) } } } return 0; } inline int Dinic() { rg int i,j,ans=0; while(bfs()) { for(i=1;i<=n;++i)cur[i]=record[i]; while(int now=dfs(s,INF))ans+=now; } return ans; } int main() { n=read(),m=read(),s=read(),t=read(); rg int i,j; for(i=1;i<=n;++i)record[i]=-1; for(i=1;i<=m;++i) { rg int x=read(),y=read(),ww=read(); add(x,y,ww),add(y,x,0); } printf("%d\n",Dinic()); return 0; }