标签:set class 文章 using 元组 ace 重复 ddn 大致
本来先搞计算几何再搞网络流的,但是**总是发网络流的题,然后天天被信息组巨佬爆踩,所以先学一下最基本的Dinic算法吧。我也只是大致理解了流程,其实不懂也没事,只要会堆代码就好了(QAQ),所以下面只有教你如何堆代码啦(……)。
int head[],tot; struct edge{int v,w,nxt;}e[]; void addn(int u,int v,int w){ e[++tot]=(edge){v,w,head[u]}; head[u]=tot; } //存边:u->v(w)和v->u(0) addn(u,v,w); addn(v,u,0);
用cur[ ]代替变化的head[ ],dis[ ]表示到每个点到st的距离(每隔一条边距离就是1)
int bfs(int st,int ed) { //bfs建图 queue<int>que; memset(dis,-1,sizeof(dis)); dis[st]=0; que.push(st); while(!que.empty()) { int x=que.front(); que.pop(); for(int i=head[x];i;i=e[i].nxt) { int now=e[i].v; if(dis[now]==-1&&e[i].w) { que.push(now); dis[now]=dis[x]+1; } } } return dis[ed]!=-1; }
int dfs(int x,int t,int maxflow) { if(x==t) return maxflow; int ans=0; for(int i=cur[x];i;i=e[i].nxt) { int now=e[i].v; if(dis[now]!=dis[x]+1||!e[i].w||ans>=maxflow) continue; cur[x]=i; int f=dfs(now,t,min(e[i].w,maxflow-ans)); e[i].w-=f; if(i&1) e[i+1].w+=f; else e[i-1].w+=f; ans+=f; } if(!ans) dis[x]=-1; return ans; }
//dinic板子 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define INF 0x3f3f3f3f using namespace std; const int N=10000,M=100000; int n,m,tot,ss,dd,head[N+3]; struct edge{int v,w,nxt;}e[M*2+3]; int dis[N+3],cur[N+3]; void addn(int u,int v,int w){e[++tot]=(edge){v,w,head[u]};head[u]=tot;} int bfs(int st,int ed) { //bfs建图 queue<int>que; memset(dis,-1,sizeof(dis)); dis[st]=0; que.push(st); while(!que.empty()) { int x=que.front(); que.pop(); for(int i=head[x];i;i=e[i].nxt) { int now=e[i].v; if(dis[now]==-1&&e[i].w) { que.push(now); dis[now]=dis[x]+1; } } } return dis[ed]!=-1; } int dfs(int x,int t,int maxflow) { if(x==t) return maxflow; int ans=0; for(int i=cur[x];i;i=e[i].nxt) { int now=e[i].v; if(dis[now]!=dis[x]+1||!e[i].w||ans>=maxflow) continue; cur[x]=i; int f=dfs(now,t,min(e[i].w,maxflow-ans)); e[i].w-=f; if(i&1) e[i+1].w+=f; else e[i-1].w+=f; ans+=f; } if(!ans) dis[x]=-1; return ans; } int Dinic(int st,int ed) { int ans=0; while(bfs(st,ed)) { memcpy(cur,head,sizeof(head)); int k; // ans+=dfs(st,ed,INF); while(k=dfs(st,ed,INF)) ans+=k; } return ans; } int main() { scanf("%d %d %d %d",&n,&m,&ss,&dd); for(int i=1;i<=m;i++) { int u,v,w; scanf("%d %d %d",&u,&v,&w); addn(u,v,w); addn(v,u,0); } cout<<Dinic(ss,dd); return 0; }
注意:题目不同,m和n的大小也不同,记得要更改呀~
标签:set class 文章 using 元组 ace 重复 ddn 大致
原文地址:https://www.cnblogs.com/mm-puppy-lyt/p/mm-puppy-wllzdlDinic.html