网络流常用算法

本文介绍了一种结合广度优先搜索(BFS)与深度优先搜索(DFS)算法解决最大流问题的方法。通过使用BFS寻找增广路径,并利用DFS更新流量,实现高效的求解过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.BFS+DFS

int c[201][201],pre[201],queue[201],dis[201];  //c为流地图
bool vis[201];
int n,m,ans;
inline 
int find_min(int a,int b)
{
    
return a<b?a:b;
}
void dfs(int s)  //s为开头节点
{
    
if (!c[pre[s]][s] && s!=1return ;
    
if (s==n)
    {
        
int i,flow=0xFFFFFFF;
        i
=n;
        
while (i!=1)
        {
            flow
=find_min(flow,c[pre[i]][i]);
            i
=pre[i];
        }
        ans
+=flow;
        i
=n;
        
while (i!=1)
        {
            c[pre[i]][i]
-=flow;
            c[i][pre[i]]
+=flow;
            i
=pre[i];
        }
    }
    
for (int i=1;i<=n;i++)
        
if (c[pre[s]][s]>0 || s==1)
            
if (c[s][i]>0 && dis[i]==dis[s]+1)
            {
                pre[i]
=s; dfs(i);
            }
}
bool bfs()  //如果还存在增广路
{
    
int head,tail,now;
    
for (int i=1;i<=n;i++)
    {
        dis[i]
=0; vis[i]=false;
    }
    queue[
1]=1; vis[1]=true;
    head
=tail=1;
    
while (head<=tail)
    {
        now
=queue[head];
        
for (int i=1;i<=n;i++)
            
if (!vis[i] && c[now][i]>0)
            {
                vis[i]
=true;
                tail
++; queue[tail]=i;
                dis[i]
=dis[now]+1;
            }
        head
++;
    }
    
return vis[n];
}

执行:while(bfs())dfs(开头节点编号)

2.纯BFS

int c[201][201],pre[201],queue[201];
bool vis[201];
int n,m,ans;
inline 
int find_min(int a,int b)
{
    
return a<b?a:b;
}
void change()
{
    
int i,flow=0xFFFFFFF;
    i
=n;
    
while (i!=1)
    {
        flow
=find_min(flow,c[pre[i]][i]);
        i
=pre[i];
    }
    ans
+=flow;
    i
=n;
    
while (i!=1)
    {
        c[pre[i]][i]
-=flow;
        c[i][pre[i]]
+=flow;
        i
=pre[i];
    }
}
bool bfs()
{
    
for (int i=1;i<=n;i++)
    {
        vis[i]
=false; pre[i]=0;
    }
    
int head=1,tail=1,now;
    vis[
1]=true; queue[1]=true;
    
while (head<=tail)
    {
        now
=queue[head];
        
for (int i=1;i<=n;i++)
            
if (!vis[i] && c[now][i]>0)
            {
                vis[i]
=true;
                tail
++;
                queue[tail]
=i; pre[i]=now;
            }
        head
++;
    }
    
return vis[n];
}

执行:while(bfs())change()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值