• HDU1532(最大流模版题ek/dinic/isap)


    就是由于下大雨的时候约翰的农场就会被雨水给淹没,无奈下约翰不得不修建水沟,而且是网络水沟,并且聪明的约翰还控制了水的流速,本题就是让你求出最大流速,无疑要运用到求最大流了。题中N为水沟数,M为水沟的顶点,接下来Si,Ei,Ci分别是水沟的起点,终点以及其容量。求源点1到终点M的最大流速。

    ek:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    using namespace std;
    #define M 205
    #define inf 1e8
    int n,m,a,b,c,g[M][M],flow[M],pre[M];
    bool vis[M];
    int bfs()
    {
        memset(vis,false,sizeof(vis));
        memset(pre,-1,sizeof(pre));
        for(int i=1;i<=n;i++)
            flow[i]=inf;
        vis[1]=true;
        queue<int>q;
        q.push(1);
        while(!q.empty())
        {
            int p=q.front();
            q.pop();
            for(int i=1;i<=n;i++)
            {
                if(!vis[i]&&g[p][i]>0)
                {
                    vis[i]=true;
                    flow[i]=min(flow[p],g[p][i]);
                    pre[i]=p;
                    q.push(i);
                }
            }
        }
        if(!vis[n]||n==1) return -1;
        return flow[n];
    }
    int ek()
    {
        int maxflow=0,d,res,temp;
        while((d=bfs())!=-1)
        {
            maxflow+=d;
            temp=n;
            while(temp!=1)
            {
                res=pre[temp];
                g[res][temp]-=d;
                g[temp][res]+=d;
                temp=res;
            }
        }
        return maxflow;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&m,&n))
        {
            memset(g,0,sizeof(g));
            while(m--)
            {
                scanf("%d%d%d",&a,&b,&c);
                g[a][b]+=c;
            }
            printf("%d
    ",ek());
        }
        return 0;
    }

     dinic:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    using namespace std;
    #define M 205
    #define inf 1e8
    int n,m,dis[M],r,cur[M];
    struct edge
    {
        int u,v,cap;
        edge(){}
        edge(int a,int b,int c){u=a;v=b;cap=c;}
    }eg[M*2];
    vector<int>g[M];
    void addedge(int a,int b,int c)
    {
        g[a].push_back(r);
        eg[r++]=edge(a,b,c);
        g[b].push_back(r);
        eg[r++]=edge(b,a,0);
    }
    bool bfs()
    {
        memset(dis,0,sizeof(dis));
        dis[1]=1;
        queue<int>q;
        q.push(1);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0;i<g[x].size();i++)
            {
                edge &e=eg[g[x][i]];
                if(!dis[e.v]&&e.cap>0)
                {
                    dis[e.v]=dis[x]+1;
                    q.push(e.v);
                }
            }
        }
        return dis[n];
    }
    int dfs(int x,int low)
    {
        if(x==n||!low) return low;
        int p;
        for(int i=cur[x];i<g[x].size();i++)
        {
            cur[x]=i;
            edge &e=eg[g[x][i]];
            if(e.cap>0&&dis[e.v]==dis[x]+1&&(p=dfs(e.v,min(low,e.cap))))
            {
                e.cap-=p;
                eg[g[x][i]^1].cap+=p;
                return p;
            }
        }
        return 0;
    }
    void dinic()
    {
        int ans=0,now;
        while(bfs())
        {
            memset(cur,0,sizeof(cur));
            while(now=dfs(1,inf)) ans+=now;
        }
        printf("%d
    ",ans);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&m,&n))
        {
            int a,b,c;
            r=0;
            for(int i=1;i<=n;i++)
                g[i].clear();
            while(m--)
            {
                scanf("%d%d%d",&a,&b,&c);
                addedge(a,b,c);
            }
            dinic();
        }
        return 0;
    }

     isap:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    #include <limits.h>
    using namespace std;
    #define inf 1e8
    #define maxm 400000
    #define maxn 1100
    int head[maxn],eid;
    int dis[maxn];//残量网络中节点i到汇点t的最短距离
    int num[maxn];//和t的最短距离等于i的节点数量
    int cur[maxn];//当前弧下标
    int pre[maxn];//可增广路上的上一条弧的编号
    struct node
    {
        int v,cap,next;
    } edge[maxm];
    void add(int u,int v,int cap)
    {
        edge[eid].v=v;
        edge[eid].cap=cap;
        edge[eid].next=head[u];
        head[u]=eid++;
        edge[eid].v=u;
        edge[eid].cap=0;
        edge[eid].next=head[v];
        head[v]=eid++;
    }
    void bfs(int source,int sink)//预处理,利用反向BFS,更新dis数组
    {
        queue<int>q;
        while(!q.empty()) q.pop();
        memset(num,0,sizeof(num));
        memset(dis,-1,sizeof(dis));
        q.push(sink);
        dis[sink]=0;
        num[0]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u]; i!=-1; i=edge[i].next)
            {
                int v=edge[i].v;
                if(dis[v]==-1)
                {
                    dis[v]=dis[u]+1;//找允许弧
                    num[dis[v]]++;
                    q.push(v);
                }
            }
        }
    }
    int isap(int source,int sink,int n)//n为残量网络中的节点到汇点的最大距离,通常节点的个数,即上限
    {
        memcpy(cur,head,sizeof(cur));
        int flow=0,u=pre[source]=source;
        bfs(source,sink);//更新dis数组
        while(dis[source]<n)
        {
            if(u==sink)
            {
                int df=inf,pos;
                for(int i=source;i!=sink;i=edge[cur[i]].v)//追踪增广路路径,最小残量df
                {
                    if(df>edge[cur[i]].cap)
                    {
                        df=edge[cur[i]].cap;
                        pos=i;
                    }
                }
                for(int i=source;i!=sink;i=edge[cur[i]].v)//更新流量
                {
                    edge[cur[i]].cap-=df;
                    edge[cur[i]^1].cap+=df;
                }
                flow+=df;
                u=pos;
            }
            int st;
            for(st=cur[u];st!=-1;st=edge[st].next)//从当前弧开始查找允许弧
                if(dis[edge[st].v]+1==dis[u]&&edge[st].cap)//找到允许弧跳出
                    break;
            if(st!=-1)
            {
                cur[u]=st;
                pre[edge[st].v]=u;
                u=edge[st].v;
            }
            else
            {
                if((--num[dis[u]])==0) break;//GAP优化,出现断层结束
                int mind=n;
                for(int id=head[u];id!=-1;id=edge[id].next)//retreat操作:更新dis数组
                {
                    if(mind>dis[edge[id].v]&&edge[id].cap)
                    {
                        cur[u]=id;//修改标号的同时修改当前弧
                        mind=dis[edge[id].v];
                    }
                }
                dis[u]=mind+1;
                num[dis[u]]++;
                if(u!=source) u=pre[u];// 回溯继续寻找允许弧
            }
        }
        return flow;
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        eid=0;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n,m,a,b,c;
        while(~scanf("%d%d",&m,&n))
        {
            init();
            while(m--)
            {
                scanf("%d%d%d",&a,&b,&c);
                add(a,b,c);
            }
            printf("%d
    ",isap(1,n,n));
        }
        return 0;
    }
  • 相关阅读:
    SQL语句中----删除表数据drop、truncate和delete的用法
    input绑定ng-model报错
    angular中使用promise
    js增删改除
    jQuery入门简记(增删改搜)
    ajax封装与兼容
    MySQL遇到check the manual that corresponds to your MySQL server version for the right syntax错误
    深入理解Java中的final关键字
    ubuntu设置samba
    设计模式之单例模式
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/4761443.html
Copyright © 2020-2023  润新知