【網絡流基礎模板】
阿新 • • 發佈:2017-12-01
oid 最大 建立 sizeof front 最大匹配 queue ext style
//網絡流dinic //最大流=最小割 //基本建模 //建源匯,向每個點分別連所限制的邊權,題目所給的邊連inf int cnt=1; inline void insert(int u,int v,int w) { e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; e[cnt].f=w; } inline void insert(int u,int v,int w) { insert1(u,v,w); insert1(v,w,0); } inline int dfs(int now,int f) {if(now==t) return f; for(int i=head[now];i && f;i=e[i].next) { if(e[i].f && dep[e[i].to]==dep[now]+1) { int d=dfs(e[i].to,min(e[i].f,f)); f-=d;ret+=d;e[i].f-=d;e[i^1].f+=d; } } if(!ret) dep[now]=-1; return ret; } inlinebool bfs() { memset(dep,0,sizeof(dep)); q.push(s),dep[s]=1; queue<int> q; while(!q.empty()) { int now=q.front();q.pop(); for(int i=head[now];i;i=e[i].next) if(e[i].f && !dep[e[i].to]) dep[e[i].to]=dep[now]+1,q.push(e[i].to); }return dep[t]; } inline int dinic() { int ret=0; while(bfs()) ret+=dfs(s,1e9+7); return ret; } //二分圖 //建立超級源匯,連邊權為1,最大流 //最大匹配=最大流 //最大匹配=最小頂點覆蓋 //最大點獨立集=最小邊覆蓋 //最大匹配+最小邊覆蓋=最大點獨立集+最小頂點覆蓋=|V| //最大權閉合子圖 //正點權和-最小割 //二分圖點權最大點獨立集 //點權和-最小割 //點限制的網絡流 //拆點x0為x1->x2邊權為x0的點限制 //費用流 inline int dfs(int now,int f) { if(now==t) { ans+=f*dis[t]; return f; } mark[now]=1; int ret=0; for(int i=head[now];i && f;i=e[i].next) { if(e[i].f && dis[now]+e[i].cost==dis[e[i].to] && !mark[e[i].to]) { int d=dfs(e[i].to,min(f,e[i].f)); e[i].f-=d; e[i^1].f+=d; ret+=d; f-=d; } } return ret; } inline bool spfa() { for(int i=0;i<=n+1;i++) dis[i]=inf; memset(vis,0,sizeof(vis)); memset(mark,0,sizeof(mark)); q.push(s);vis[s]=1;dis[s]=0; while(!q.empty()) { int now=q.front();q.pop();vis[now]=0; for(int i=head[now];i;i=e[i].next) { if(e[i].f && dis[now]+e[i].cost<dis[e[i].to]) { dis[e[i].to]=dis[now]+e[i].cost; if(!vis[e[i].to]) { q.push(e[i].to); vis[e[i].to]=1; } } } } return dis[t]<inf; } inline void insert(int u,int v,int f,int w) { insert1(u,v,f,w); insert1(v,u,0,-w); } inline int dinic() { ans=0; while(spfa()) dfs(s,inf); return ans; } //建圖才是最難滴
【網絡流基礎模板】