洛谷 P3376 【模板】网络最大流 题解
今天学了网络最大流,EK 和 Dinic 主要就是运用搜索求增广路,Dinic 相当于 EK 的优化,先用bfs求每个点的层数,再用dfs寻找并更新那条路径上的值。
EK 算法
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #define maxn 1000001 7 #define INF 2147483647 8 using namespace std; 9 int cnt=1,head[maxn]; 10 int dis[maxn],vis[maxn],flow[maxn],last[maxn],maxflow; 11 struct node 12 { 13 int u,v,w,nex; 14 }edge[maxn]; 15 queue<int>q; 16 int S,T,n,m; 17 inline int read() 18 { 19 int x=0; 20 bool f=1; 21 char c=getchar(); 22 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 23 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 24 if(f) return x; 25 return 0-x; 26 } 27 inline void add(int x,int y,int z) 28 { 29 cnt++; 30 edge[cnt].u=x; 31 edge[cnt].v=y; 32 edge[cnt].w=z; 33 edge[cnt].nex=head[x]; 34 head[x]=cnt; 35 } 36 inline bool bfs(int S,int T) 37 { 38 for(int i=1;i<=n;i++) 39 { 40 last[i]=0; 41 vis[i]=-1; 42 } 43 q.push(S); 44 dis[S]=0; 45 vis[S]=1; 46 flow[S]=INF; 47 while(!q.empty()) 48 { 49 int u=q.front(); 50 q.pop(); 51 vis[u]=0; 52 for(int i=head[u];i!=-1;i=edge[i].nex) 53 { 54 int v=edge[i].v; 55 if(edge[i].w>0&&vis[v]==-1) 56 { 57 flow[v]=min(flow[u],edge[i].w); 58 last[v]=i; 59 q.push(v); 60 vis[v]=0; 61 } 62 } 63 } 64 if(vis[T]!=-1)return true; 65 return false; 66 } 67 inline void update(int S,int T) 68 { 69 int now=T; 70 while(now!=S) 71 { 72 int i=last[now]; 73 edge[i].w-=flow[T]; 74 edge[i^1].w+=flow[T]; 75 now=edge[i].u; 76 } 77 maxflow+=flow[T]; 78 } 79 inline void EK() 80 { 81 82 maxflow=0; 83 while(bfs(S,T)==true) 84 { 85 update(S,T); 86 } 87 } 88 int main() 89 { 90 memset(head,-1,sizeof(head)); 91 n=read();m=read();S=read();T=read(); 92 for(int i=1;i<=m;i++) 93 { 94 int x,y,z; 95 x=read();y=read();z=read(); 96 add(x,y,z);add(y,x,0); 97 } 98 EK(); 99 printf("%d",maxflow); 100 return 0; 101 }
Dinic 算法
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #define maxn 1000001 7 #define INF 2147483647 8 using namespace std; 9 int cnt=1,head[maxn],level[maxn]; 10 struct node 11 { 12 int u,v,w,nex; 13 }edge[maxn]; 14 queue<int> q; 15 int S,T,n,m; 16 inline int read() 17 { 18 int x=0; 19 bool f=1; 20 char c=getchar(); 21 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 22 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 23 if(f) return x; 24 return 0-x; 25 } 26 inline void write(int x) 27 { 28 if(x<0){putchar('-');x=-x;} 29 if(x>9)write(x/10); 30 putchar(x%10+'0'); 31 } 32 inline void add(int x,int y,int z) 33 { 34 cnt++; 35 edge[cnt].u=x; 36 edge[cnt].v=y; 37 edge[cnt].w=z; 38 edge[cnt].nex=head[x]; 39 head[x]=cnt; 40 } 41 inline bool bfs() 42 { 43 memset(level,-1,sizeof(level)); 44 level[S]=0; 45 q.push(S); 46 while(!q.empty()) 47 { 48 int from=q.front(); 49 q.pop(); 50 for(int i=head[from];i!=-1;i=edge[i].nex) 51 { 52 int to=edge[i].v; 53 if(edge[i].w>0&&level[to]==-1) 54 { 55 level[to]=level[from]+1; 56 q.push(to); 57 } 58 } 59 } 60 if(level[T]!=-1)return true; 61 return false; 62 } 63 inline int dfs(int u,int flow) 64 { 65 if(u==T)return flow; 66 int ret=flow; 67 for(int i=head[u];i!=-1;i=edge[i].nex) 68 { 69 if(ret<=0)break; 70 int to=edge[i].v; 71 if(edge[i].w>0&&level[u]+1==level[to]) 72 { 73 int k=dfs(to,min(edge[i].w,ret)); 74 ret-=k; 75 edge[i].w-=k; 76 edge[i^1].w+=k; 77 } 78 } 79 return flow-ret; 80 } 81 inline int dinic() 82 { 83 int ans=0; 84 while(bfs()==true)ans+=dfs(S,INF); 85 return ans; 86 } 87 int main() 88 { 89 memset(head,-1,sizeof(head)); 90 n=read();m=read();S=read();T=read(); 91 for(int i=1;i<=m;i++) 92 { 93 int x,y,z; 94 x=read();y=read();z=read(); 95 add(x,y,z); 96 add(y,x,0); 97 } 98 int res=dinic(); 99 write(res); 100 return 0; 101 }
请各位大佬斧正(反正我不认识斧正是什么意思)