EK 算法 复杂度 n*m*m https://blog.youkuaiyun.com/x_y_q_/article/details/51999466
Dinic算法 复杂度 m*n*n https://www.cnblogs.com/SYCstudio/p/7260613.html
本来这道题 Dinic 和 EK 复杂度应该一样,不知道为什么 EK 0ms Dinic15ms
EK:
#include<stdio.h>
#include<memory.h>
#include<queue>
using namespace std;
const int sz = 200+10;
const int inf = 10000000+10;
int c[sz][sz];
int flow[sz];
int pre[sz];
int n,m; //有n条边 m个节点
int bfs(int sc,int dest)
{
queue<int>q;
for(int i=1;i<=m;i++)
{
pre[i]=-1;
flow[i]=0;
}
pre[sc]=sc;
flow[sc]=inf;
q.push(sc);
while(!q.empty())
{
int now = q.front();
q.pop();
for(int i=1;i<=m;i++)
{
if(pre[i]==-1 && c[now][i]>0)
{
pre[i] = now;
flow[i] = min(flow[now],c[now][i]);
if(i==dest)
{
break;
}
q.push(i);
}
}
}
if(pre[dest]==-1)
{
return -1;
}else{
return flow[dest];
}
}
int max_flow(int sc,int dest)
{
int increament ;
int rs = 0;
while((increament = bfs(sc,dest))!=-1)
{
rs = rs + increament;
int k = dest;
while(k!=sc)
{
int pp = pre[k];
c[pp][k] -= increament;
c[k][pp] += increament;
k = pre[k];
}
}
return rs;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
memset(c,0,sizeof(c));
// memset(flow,0,sizeof(flow));
// memset(pre,0,sizeof(pre));
for(int i=1;i<=n;i++)
{
int a,b,ci;
scanf("%d %d %d",&a,&b,&ci);
c[a][b] += ci;
}
printf("%d\n",max_flow(1,m));
}
return 0;
}
Dinic:
//dinic
#include<stdio.h>
#include<queue>
#include<memory.h>
#include<algorithm>
using namespace std;
const int maxn = 200+10;//顶点数
const int maxm = (200+10)*3;//边数
int Head[maxn];//每一个点的最后一条边的位置
int V[maxm];//每一条边指向的点
int W[maxm];//每一条边的权重 初始化为0
int Next[maxm];//每一条边的上一条边 初始化为-1
int depth[maxn];//记录每一个节点的层次 bfs每次初始化为0
const int inf = 1e9+7;
int cnt;//边数
//建立层次图
int bfs(int s,int t)
{
queue<int>q;
memset(depth,0,sizeof(depth));
depth[s]=1;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = Head[u] ; i!=-1 ; i=Next[i])
{
if(W[i]>0 && depth[V[i]]==0)
{
depth[V[i]]=depth[u]+1;
q.push(V[i]);
}
}
}
if(depth[t]==0)
{
return 0;
}
return 1;
}
//深搜查找增广路
int dfs(int s,int t,int flow)
{
if(s==t)
{
return flow;
}
for(int i=Head[s] ; i!=-1 ;i=Next[i])
{
if(W[i]>0 && depth[s]+1 == depth[V[i]])
{
int di = dfs(V[i],t,min(flow,W[i]));
if(di>0)
{
W[i]-=di;
W[i^1]+=di;
return di;
}
}
}
return 0;
}
//dinic算法
int dinic(int s,int t)
{
int max_flow = 0;
while(bfs(s,t))
{
int d = 0;
while(d = dfs(s,t,inf))
{
max_flow += d;
}
}
return max_flow;
}
void addEdge(int from,int to,int c)
{
Next[cnt] = Head[from];
Head[from]=cnt;
V[cnt]=to;
W[cnt]=c;
cnt++;
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
cnt = 0;
memset(Head,-1,sizeof(Head));
// memset(Next,-1,sizeof(Next));///
for(int i=1;i<=n;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
addEdge(a,b,c);
addEdge(b,a,0);
}
printf("%d\n",dinic(1,m));
}
return 0;
}
本文详细介绍了EK算法和Dinic算法的实现细节,并通过代码示例展示了两种算法在网络流问题中的应用。对比了这两种算法的复杂度及实际运行效率。
565

被折叠的 条评论
为什么被折叠?



