zoukankan      html  css  js  c++  java
  • 最大流最小割入门题

    Dinic板子:

    const int tmax=1e4+5,inf_int=1e9+5;
    
    struct edge{
        int to,cap,rev;
    };
    
    vector<edge> G[tmax];
    int level[tmax]; 
    int iter[tmax];  
    
    void addedge(int from,int to,int cap)
    {
        G[from].push_back((edge){to,cap,G[to].size()});
        G[to].push_back((edge){from,0,G[from].size()-1});
    }
    
    void bfs(int s)
    {
        memset(level,-1,sizeof(level));
        queue<int> que;
        level[s]=0;
        que.push(s);
        while(!que.empty())
        {
            int v=que.front();
            que.pop();
            for(int i=0;i<G[v].size();i++)
            {
                edge &e=G[v][i];
                if(e.cap>0&&level[e.to]<0)
                {
                    level[e.to]=level[v]+1;
                    que.push(e.to);
                }
            }
        }
    }
    
    int dfs(int v,int t,int f)
    {
        if(v==t) return f;
        for(int &i=iter[v];i<G[v].size();i++)
        {
            edge &e=G[v][i];
            if(e.cap>0&&level[v]<level[e.to])
            {
                int d=dfs(e.to,t,min(f,e.cap));
                if(d>0)
                {
                    e.cap-=d;
                    G[e.to][e.rev].cap+=d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    int Dinic(int s,int t)
    {
        int flow=0;
        while(1)
        {
            bfs(s);
            if(level[t]<0) return flow;
            memset(iter,0,sizeof(iter));
            int f;
            while((f=dfs(s,t,inf_int))>0)
                flow+=f;
        }
    }
    View Code

    Dijkstra+Heap板子:

    const int tmax=1e4+5,inf_int=1e9+5;
    
    ll dis1[tmax], dis2[tmax];
    
    struct node 
    {
        ll d;
        int x;
        bool operator<(const node &b)const
        {
            return d>b.d;
        }
    };
    
    vector<Pii> GG[tmax];
    priority_queue<node> Q;
    bool vis[tmax];
    void dijk(int s,ll *d)
    {
        int i,u,v,w,len;
        node tmp;
        memset(vis,0,sizeof(vis));
        for(i=1;i<=n;i++) d[i]=inf;
        d[s]=0;
        Q.push((node){0,s});
        while(!Q.empty())
        {
            tmp=Q.top();
            Q.pop();
            u=tmp.x;
            if(vis[u]) continue;
            vis[u]=true;
            len=GG[u].size();
            for(i=0;i<len;i++)
            {
                v=GG[u][i].first;
                w=GG[u][i].second;
                if(d[v]>d[u]+w)
                {
                    d[v]=d[u]+w;
                    Q.push((node){d[v],v});
                }
            }
        }
        return;
    }
    View Code

    HDU 3416

    题意:给出一个图,有多少个边不重复的最短路。

    题解:先跑最短路,找出从start到end的所有最短路,先跑正向在跑反向,如果dis1[u]+cost[i]+dist2[v]==dis1[n],即可判断该边是否在最短路上。

       把最短上的边构图(cap=1)跑最大流即可.

    #include <bits/stdc++.h>
    #define Pii pair<int,int>
    using namespace std;
    typedef long long ll;
    const ll inf=1e16;
    const int tmax=2e5+5,inf_int=1e9+5;
    
    int n, m, u[tmax], v[tmax], c[tmax];
    ll dis1[tmax], dis2[tmax];
    
    struct node 
    {
        ll d;
        int x;
        bool operator<(const node &b)const
        {
            return d>b.d;
        }
    };
    
    vector<Pii> GG[tmax];
    priority_queue<node> Q;
    bool vis[tmax];
    void Dijk(int s,ll *d)
    {
        int i,u,v,w,len;
        node tmp;
        memset(vis,0,sizeof(vis));
        for(i=1;i<=n;i++) d[i]=inf;
        d[s]=0;
        Q.push((node){0,s});
        while(!Q.empty())
        {
            tmp=Q.top();
            Q.pop();
            u=tmp.x;
            if(vis[u]) continue;
            vis[u]=true;
            len=GG[u].size();
            for(i=0;i<len;i++)
            {
                v=GG[u][i].first;
                w=GG[u][i].second;
                if(d[v]>d[u]+w)
                {
                    d[v]=d[u]+w;
                    Q.push((node){d[v],v});
                }
            }
        }
        return;
    }
    
    struct edge{
        int to,cap,rev;
    };
    
    vector<edge> G[tmax];
    int level[tmax]; 
    int iter[tmax];  
    
    void addedge(int from,int to,int cap)
    {
        G[from].push_back((edge){to,cap,G[to].size()});
        G[to].push_back((edge){from,0,G[from].size()-1});
    }
    
    void bfs(int s)
    {
        memset(level,-1,sizeof(level));
        queue<int> que;
        level[s]=0;
        que.push(s);
        while(!que.empty())
        {
            int v=que.front();
            que.pop();
            for(int i=0;i<G[v].size();i++)
            {
                edge &e=G[v][i];
                if(e.cap>0&&level[e.to]<0)
                {
                    level[e.to]=level[v]+1;
                    que.push(e.to);
                }
            }
        }
    }
    
    int dfs(int v,int t,int f)
    {
        if(v==t) return f;
        for(int &i=iter[v];i<G[v].size();i++)
        {
            edge &e=G[v][i];
            if(e.cap>0&&level[v]<level[e.to])
            {
                int d=dfs(e.to,t,min(f,e.cap));
                if(d>0)
                {
                    e.cap-=d;
                    G[e.to][e.rev].cap+=d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    int Dinic(int s,int t)
    {
        int flow=0;
        while(1)
        {
            bfs(s);
            if(level[t]<0) return flow;
            memset(iter,0,sizeof(iter));
            int f;
            while((f=dfs(s,t,inf_int))>0)
                flow+=f;
        }
    }
    
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        int T;
        for(cin>>T; T--; )
        {
            cin>>n>>m;
            for(int i=1; i<=m; i++)
            {
                cin>>u[i]>>v[i]>>c[i];
                GG[u[i]].push_back(Pii(v[i],c[i]));
            }
            int A, B; 
            cin>>A>>B;
            Dijk(A, dis1);
            for(int i=1; i<=n; i++)
                GG[i].clear();
            for(int i=1; i<=m; i++)
                GG[v[i]].push_back(Pii(u[i],c[i]));
            Dijk(B, dis2);
            for(int i=1; i<=m; i++)
            {
                if(dis1[u[i]]+c[i]+dis2[v[i]]==dis1[B])
                    addedge(u[i],v[i],1);
            }
            cout<<Dinic(A,B)<<endl;
            for(int i=1; i<=n; i++)
            {
                G[i].clear(); GG[i].clear();
            }
        }
        return 0;
    }
    View Code

    HDU 6532

    题意:给出一个图,求至少删除多少边权后能够最短路长度增加(删除后不联通可以)

    题解:以最短路上的边构图,跑一下最小割即可。

    #include <bits/stdc++.h>
    #define Pii pair<int,int>
    using namespace std;
    typedef long long ll;
    const ll inf=1e16;
    const int tmax=1e4+5,inf_int=1e9+5;
    
    int n, m, u[tmax], v[tmax], c[tmax];
    ll dis1[tmax], dis2[tmax];
    
    struct node 
    {
        ll d;
        int x;
        bool operator<(const node &b)const
        {
            return d>b.d;
        }
    };
    
    vector<Pii> GG[tmax];
    priority_queue<node> Q;
    bool vis[tmax];
    void Dijk(int s,ll *d)
    {
        int i,u,v,w,len;
        node tmp;
        memset(vis,0,sizeof(vis));
        for(i=1;i<=n;i++) d[i]=inf;
        d[s]=0;
        Q.push((node){0,s});
        while(!Q.empty())
        {
            tmp=Q.top();
            Q.pop();
            u=tmp.x;
            if(vis[u]) continue;
            vis[u]=true;
            len=GG[u].size();
            for(i=0;i<len;i++)
            {
                v=GG[u][i].first;
                w=GG[u][i].second;
                if(d[v]>d[u]+w)
                {
                    d[v]=d[u]+w;
                    Q.push((node){d[v],v});
                }
            }
        }
        return;
    }
    
    struct edge{
        int to,cap,rev;
    };
    
    vector<edge> G[tmax];
    int level[tmax]; 
    int iter[tmax];  
    
    void addedge(int from,int to,int cap)
    {
        G[from].push_back((edge){to,cap,G[to].size()});
        G[to].push_back((edge){from,0,G[from].size()-1});
    }
    
    void bfs(int s)
    {
        memset(level,-1,sizeof(level));
        queue<int> que;
        level[s]=0;
        que.push(s);
        while(!que.empty())
        {
            int v=que.front();
            que.pop();
            for(int i=0;i<G[v].size();i++)
            {
                edge &e=G[v][i];
                if(e.cap>0&&level[e.to]<0)
                {
                    level[e.to]=level[v]+1;
                    que.push(e.to);
                }
            }
        }
    }
    
    int dfs(int v,int t,int f)
    {
        if(v==t) return f;
        for(int &i=iter[v];i<G[v].size();i++)
        {
            edge &e=G[v][i];
            if(e.cap>0&&level[v]<level[e.to])
            {
                int d=dfs(e.to,t,min(f,e.cap));
                if(d>0)
                {
                    e.cap-=d;
                    G[e.to][e.rev].cap+=d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    int Dinic(int s,int t)
    {
        int flow=0;
        while(1)
        {
            bfs(s);
            if(level[t]<0) return flow;
            memset(iter,0,sizeof(iter));
            int f;
            while((f=dfs(s,t,inf_int))>0)
                flow+=f;
        }
    }
    
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        int T;
        for(cin>>T; T--; )
        {
            cin>>n>>m;
            for(int i=1; i<=m; i++)
            {
                cin>>u[i]>>v[i]>>c[i];
                GG[u[i]].push_back(Pii(v[i], c[i]));
            }
            Dijk(1, dis1);
            for(int i=1; i<=n; i++)
                GG[i].clear();
            for(int i=1; i<=m; i++)
                GG[v[i]].push_back(Pii(u[i],c[i]));
            Dijk(n,dis2);
            for(int i=1; i<=m; i++)
            {
                if(dis1[u[i]]+c[i]+dis2[v[i]]==dis1[n])
                    addedge(u[i],v[i],c[i]);
            }
            cout<<Dinic(1,n)<<endl;
            for(int i=1; i<=n; i++)
            {
                G[i].clear(); GG[i].clear();
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    谈一谈循环的性能提升
    Web前端性能优化的9大问题
    随机获取一种颜色值的三种方法
    ES6还是ES2015?
    history.back(-1)和history.go(-1)的区别
    关于overflow-y:scroll ios设备不流畅的问题
    前端如何压缩图片
    【转】理解JavaScript之闭包
    关于如何给数字排序
    本地缓存localstorage使用
  • 原文地址:https://www.cnblogs.com/Yokel062/p/11322756.html
Copyright © 2011-2022 走看看