码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu 3376 【模板】网络最大流

时间:2018-06-26 20:46:29      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:image   nbsp   alt   res   模板   set   string   iostream   ++   

技术分享图片

#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 【模板】网络最大流

标签:image   nbsp   alt   res   模板   set   string   iostream   ++   

原文地址:https://www.cnblogs.com/caterpillor/p/9230946.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!