Luogu 3376 模板网络最大流

Posted caterpillor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu 3376 模板网络最大流相关的知识,希望对你有一定的参考价值。

技术分享图片

#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> #define inf 0x3f3f3f3f using namespace std; int hd[10005],cnt=-1,d[10005],vis[10005]; struct Edge{ int to,vl,nxt; }edge[200005]; void add(int u,int v,int w) { cnt++; edge[cnt].to =v; edge[cnt].nxt=hd[u]; edge[cnt].vl=w; hd[u]=cnt; } queue<int> q; int s,t; int bfs() { memset(d,0,sizeof d); memset(vis,0,sizeof vis); while(q.size()) q.pop() ;//这个不写会T d[s]=1;vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=hd[u];i!=-1;i=edge[i].nxt)//边是从零开始的,因此这里可以不能是i>0 //同一条边还有容量可以流怎么办,边已经遍历完 { int v=edge[i].to; if(!vis[v] && edge[i].vl>0) { vis[v]=1; d[v]=d[u]+1; q.push(v); if(v==t)return 1; } } } return 0; } int dinic(int u,int res)// { if(u==t) return res; int sum=0; for(int i=hd[u];i!=-1;i=edge[i].nxt) { int v=edge[i].to; if(d[u]+1==d[v] && edge[i].vl>0 && res>0)// { int k=dinic(v,min(res,edge[i].vl)); //剩余流量及该路径容量的最小值 edge[i].vl-=k; edge[i^1].vl+=k; res-=k; sum+=k; } } return sum; } int n,m,u,v,w,flow,mxflow; int main() { scanf("%d%d%d%d",&n,&m,&s,&t); memset(hd,-1,sizeof hd); for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,0); } bfs(); for(int i=1;i<=n;i++) cout<<d[i]<<" "; cout<<endl; while(bfs()){ while(flow=dinic(s,inf)) mxflow+=flow; } cout<<mxflow<<endl; }

 优化:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
int hd[10005],cnt=-1,d[10005],vis[10005],cur[10005];
struct Edge{
    int to,vl,nxt;
}edge[200005];
void add(int u,int v,int w)
{
    cnt++;
    edge[cnt].to =v;
    edge[cnt].nxt=hd[u];
    edge[cnt].vl=w;
    hd[u]=cnt;
}
queue<int> q;
int s,t;
int bfs()
{
    memset(d,0,sizeof d);
    memset(vis,0,sizeof vis);
    while(q.size()) q.pop() ;//这个不写会T 
    d[s]=1;vis[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=hd[u];i!=-1;i=edge[i].nxt)//边是从零开始的,因此这里可以不能是i>0 //同一条边还有容量可以流怎么办,边已经遍历完 
        {
            int v=edge[i].to;
            if(!vis[v] && edge[i].vl>0)
            {
                vis[v]=1;
                d[v]=d[u]+1;
                q.push(v); 
                if(v==t)return 1;
            }
        }    
    }
    return 0;
}

int dinic(int u,int res)//
{
    if(u==t) return res;
    int sum=0;
    for(int i=cur[u];i!=-1;i=edge[i].nxt)
    {
        cur[u]=i;//当前弧优化,不符合的通道就不再判断了 
        int v=edge[i].to;
        if(d[u]+1==d[v] && edge[i].vl>0 && res>0)//
        {
            int k=dinic(v,min(res,edge[i].vl));    //剩余流量及该路径容量的最小值 
            if(!k) 
            {
                d[v]=0;//去掉增广完的点 
                break;
            }
            edge[i].vl-=k;
            edge[i^1].vl+=k;
            res-=k;
            sum+=k;
        }    
    }
    return sum;
}
int n,m,u,v,w,flow,mxflow;
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    memset(hd,-1,sizeof hd);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,0);
    }
//    for(int i=1;i<=n;i++)
//        cout<<d[i]<<" ";
//    cout<<endl;
    while(bfs()){
        while(flow=dinic(s,inf)) 
            mxflow+=flow;
    }
    cout<<mxflow<<endl;
}

 


以上是关于Luogu 3376 模板网络最大流的主要内容,如果未能解决你的问题,请参考以下文章

luogu P3376 网络最大流 模板

luogu P3376 模板网络最大流 模板

luogu P3376 模板网络最大流

luogu P3376 模板网络最大流

luogu3376 模板网络最大流 dinic

P3376 模板网络最大流