zoukankan      html  css  js  c++  java
  • hdu3549网络流之最大流

    Ford-Fulkerson方法:dfs实现

    dfs  140ms

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cassert>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pi acos(-1)
    #define ll long long
    #define mod 10007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    const double g=10.0,eps=1e-9;
    const int N=50+5,maxn=20+5,inf=999999;
    
    int t,n,m;
    int vis[maxn];//判断是否访问过
    int c[maxn][maxn];//邻接矩阵存图
    int dfs(int u,int low)//深搜找增广路
    {
        int i,flow;
        if(u==t)return low;//到达汇点
        if(vis[u])return 0;//节点访问过
        vis[u]=1;
        for(i=1;i<=n;i++)
            if(c[u][i]&&(flow=dfs(i,low<c[u][i]?low:c[u][i])))
            {
                c[u][i]-=flow;
                c[i][u]+=flow;
                return flow;
            }
        return 0;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
     //   cout<<setiosflags(ios::fixed)<<setprecision(2);
        int T,cnt=0;
        cin>>T;
        while(T--){
            cin>>n>>m;
            memset(c,0,sizeof(c));
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=m;i++)
            {
                int u,v,w;
                cin>>u>>v>>w;
                c[u][v]+=w;
            }
            t=n;//t是汇点
            int maxflow=0,flow;
            while(flow=dfs(1,inf))//当增广路还存在时
            {
               /* for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=n;j++)
                        cout<<c[i][j]<<" ";
                    cout<<endl;
                }*/
                maxflow+=flow;
                memset(vis,0,sizeof(vis));
            }
            cout<<"Case "<<++cnt<<": "<<maxflow<<endl;
        }
        return 0;
    }
    View Code

    Edmonds_Karp算法:bfs实现

    bfs 156ms

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cassert>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pi acos(-1)
    #define ll long long
    #define mod 10007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    const double g=10.0,eps=1e-9;
    const int N=50+5,maxn=20+5,inf=999999;
    
    int t,n,m,pre[N];
    bool vis[maxn];//判断是否访问过
    int c[maxn][maxn];//邻接矩阵存图
    bool bfs()//判断是否存在增广路,并求出
    {
        memset(vis,0,sizeof vis);
        memset(pre,0,sizeof pre);
        vis[1]=1;
        queue<int>q;
        q.push(1);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            if(x==t)return 1;
            for(int i=1;i<=n;i++)
            {
                if(!vis[i]&&c[x][i])
                {
                    q.push(i);
                    pre[i]=x;//记录前驱
                    vis[i]=1;
                }
            }
        }
        return 0;
    }
    int max_flow()
    {
        int ans=0;
        while(1){
            if(!bfs())return ans;//找不到增广路了
            int minn=999999;
            for(int i=t;i!=1;i=pre[i])
                minn=min(minn,c[pre[i]][i]);//找出增广路中最小的节点
            for(int i=t;i!=1;i=pre[i])
            {
                c[pre[i]][i]-=minn;//更新残余网络
                c[i][pre[i]]+=minn;
            }
            ans+=minn;
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
     //   cout<<setiosflags(ios::fixed)<<setprecision(2);
        int k,cnt=0;
        cin>>k;
        while(k--){
            cin>>n>>m;
            memset(c,0,sizeof(c));
            for(int i=1;i<=m;i++)
            {
                int u,v,w;
                cin>>u>>v>>w;
                c[u][v]+=w;
            }
            t=n;//t是汇点
            cout<<"Case "<<++cnt<<": "<<max_flow()<<endl;
        }
        return 0;
    }
    View Code

     dinic算法:dfs+bfs实现

    171ms(我可能用的是假的dinic,居然这么慢,可能数据比较弱)

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cassert>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pi acos(-1)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    const double g=10.0,eps=1e-9;
    const int N=100+10,maxn=16,inf=9999999;
    
    int n,s,t;//超级源超级汇
    int v[N][N],dis[N];
    bool bfs()
    {
        memset(dis,-1,sizeof dis);
        queue<int>q;
        q.push(s);
        dis[s]=0;
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=1;i<=n;i++)
            {
                if(v[x][i]&&dis[i]==-1)
                {
                    dis[i]=dis[x]+1;
                    q.push(i);
                }
            }
        }
        if(dis[t]==-1)return 0;
        return 1;
    }
    int dfs(int x,int mx)
    {
        int a;
        if(x==t)return mx;
        for(int i=1;i<=n;i++)
        {
            if(v[x][i]>0&&dis[i]==dis[x]+1&&(a=dfs(i,min(mx,v[x][i]))))
            {
                v[x][i]-=a;
                v[i][x]+=a;
                return a;
            }
        }
        return 0;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int k,m,cnt=0;
        cin>>k;
        while(k--){
            cin>>n>>m;
            memset(v,0,sizeof v);
            while(m--){
                int a,b,c;
                cin>>a>>b>>c;
                v[a][b]+=c;
            }
            int ans=0,flow;
            s=1,t=n;
            while(bfs()){
                while(flow=dfs(s,inf))ans+=flow;
            }
            cout<<"Case "<<++cnt<<": "<<ans<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    google
    学习Linux第六天
    对比教学大纲
    周 记
    《世界是数字的》读后感
    《我是一只IT小小鸟》读后感
    前端小知识
    JavaScript 执行机制
    执行栈和任务队列
    支付宝前端员工培训手册
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/6885103.html
Copyright © 2011-2022 走看看