模板 网络流 dinic
我承认我是渣。。。至今看不懂dinic。。。先拿来用用,说不定哪一天早上睡醒了我TM顿悟了!!代码搞起。。。
#include <iostream> #include<cstdio> #include<cstring> #include<queue> #include <vector> #include<algorithm> #define INF 0xfffffff using namespace std; const int N=100005; const int M=100005; struct Edge{//邻接表 int to,next,cap; Edge(){}; Edge(int _next,int _to,int _cap){ next=_next;to=_to;cap=_cap; } }e[M*4]; int head[N],tol,dep[N]; int q[M]; void init()//初始化 { tol=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int f)//增加边,其中偶数为正向边,奇数为反向边。 { e[tol]=Edge(head[u],v,f);head[u]=tol++; e[tol]=Edge(head[v],u,0);head[v]=tol++; } bool bfs(int s,int t) { memset(dep,-1,sizeof(dep));//初始化层次数 int front=0,rear=0; dep[s]=0;q[rear++]=s; while(front!=rear) { int u=q[front++]; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(dep[v]==-1&&e[i].cap) { q[rear++]=v,dep[v]=dep[u]+1; if(v==t)return true; } } } return false; } int dinic(int s,int t) { int top; int res=0; int S[N],cur[N]; while(bfs(s,t)) { memcpy(cur,head,sizeof(head)); int u=s;top=0; while(1) { if(u==t) { int Min=INF,loc; for(int i=0;i<top;i++) if(Min>e[S[i]].cap) Min=e[S[i]].cap,loc=i; for(int i=0;i<top;i++) e[S[i]].cap-=Min,e[S[i]^1].cap+=Min; res+=Min;top=loc; u=e[S[top]^1].to; } for(int i=cur[u];i!=-1;cur[u]=i=e[i].next) if(e[i].cap&&dep[u]+1==dep[e[i].to])break; if(cur[u]!=-1) S[top++]=cur[u],u=e[cur[u]].to; else { if(top==0)break; dep[u]=-1;u=e[S[--top]^1].to; } } } return res; } //int main中,需要先用init进行初始化。若为无向,则需要加一次反向边的add函数。若城市编号从0开始,需+1.
//对于多源多汇的题目,则创建一个源点和汇点,将所有源点汇点汇聚在这两个点。