zoukankan      html  css  js  c++  java
  • 最大流问题

    给你一个图,图中有多少个顶点、点与点之间的距离(边长)告诉你,求从S点到T点的最大流量是多少?

    Sample Input
    2
    3 2
    1 2 1
    2 3 1
    3 3
    1 2 1
    2 3 1
    1 3 1
     
    Sample Output
    Case 1: 1
    Case 2: 2
     
    #include<cstdio>
    #include<cstring>
    #include<climits>
    
    using namespace std;
    
    #define N 90005
    #define M 4000005
    #define INF INT_MAX
    
    int s,t,num,pre[N],dis[N],gap[N],head[N],cur[N];
    
    struct node
    {
         int u,v,w;
         int next;
    }e[M];
    
    inline void add(int u,int v,int w)
    {
         e[num].u=u;
         e[num].v=v;
         e[num].w=w;
         e[num].next=head[u];
         head[u]=num++;
    }
    
    inline void addedge(int u,int v,int w)
    {
         add(u,v,w);
         add(v,u,0);
    }
    
    inline int max(int a,int b)
    {
        return a>b?a:b;
    }
    
    inline int min(int a,int b)
    {
        return a<b?a:b;
    }
    
    int isap(int s,int t,int n)
    {
         int top,mindis,maxflow=0,v,i,aug;
         bool flag;
         for(i=0;i<=n;i++)
         {
             cur[i]=head[i];
             gap[i]=dis[i]=0;
         }
         top=pre[s]=s;
         aug=INF;
    
         while(dis[s]<n)
         {
             flag=0;
             for(i=cur[top];i!=-1;i=e[i].next)
             {
                 v=e[i].v;
                 if(e[i].w>0&&dis[top]==dis[v]+1)
                 {
                     flag=1;
                    break;
                 }
             }
             if(flag)
             {
                 pre[v]=top;
                 cur[top]=i;
                 aug=min(aug,e[i].w);
                 top=v;
                 if(top==t)
                 {
                     while(top!=s)
                     {
                         top=pre[top];
                         e[cur[top]].w-=aug;
                         e[cur[top]^1].w+=aug;
                     }
                     top=s;
                     maxflow+=aug;
                     aug=INF;
                 }
             }
             else
             {
                 if(--gap[dis[top]]==0)
                    break;
                  mindis=n;
                 cur[top]=head[top];
                 for(i=head[top];i!=-1;i=e[i].next)
                 {
                     v=e[i].v;
                     if(e[i].w>0&&dis[v]+1<mindis)
                     {
                         mindis=dis[v]+1;
                         cur[top]=i;
                     }
                 }
                 dis[top]=mindis;
                 gap[mindis]++;
                 if(top!=s)
                     top=pre[top];
             }
         }
         return maxflow;
    }
    
    void init()
    {
         num=0;
         memset(head,-1,sizeof(head));
    }
    
    int main()
    {
         int nodenum,m,n,test;
         scanf("%d",&test);
         for(int ii=1;ii<=test;ii++)
         {
             scanf("%d%d",&n,&m);
             init();
             while(m--)
             {
                 int u,v,w;
                 scanf("%d%d%d",&u,&v,&w);
                 addedge(u,v,w);
    
             }
            //source=1,sink=n,nodenum=n;
             int res=isap(1,n,n);
             printf("Case %d: %d
    ",ii,res);
         }
         return 0;
    }
    

      另一种方法:

     #include <iostream>
     #include <queue>
      using namespace std;
      
      const int N = 210;
      const int INF = 0x7FFFFFFF;
      int n,m,map[N][N],path[N],flow[N],start,end;
      queue<int> q;
      
    int bfs(){
         int i,t;
         while(!q.empty()) q.pop();
         memset(path,-1,sizeof(path));
         path[start]=0,flow[start]=INF;
         q.push(start);
         while(!q.empty()){
             t=q.front();
            q.pop();
            if(t==end) break;
            for(i=1;i<=m;i++){
                 if(i!=start && path[i]==-1 && map[t][i]){
                     flow[i]=flow[t]<map[t][i]?flow[t]:map[t][i];
                     q.push(i);
                    path[i]=t;
                 }
             }
         }
         if(path[end]==-1) return -1;
         return flow[m];                   //一次遍历之后的流量增量
     }
     int Edmonds_Karp(){
         int max_flow=0,step,now,pre;
         while((step=bfs())!=-1){          //找不到增路径时退出
             max_flow+=step;
             now=end;
             while(now!=start){
                 pre=path[now];
                 map[pre][now]-=step;      //更新正向边的实际容量
                 map[now][pre]+=step;      //添加反向边
                 now=pre;
             }
         }
         return max_flow;
     }
     int main(){
         int i,u,v,cost;
         while(scanf("%d %d",&m,&n)!=EOF){
    		 if(!n&&!m)
    			 return 0 ;
             memset(map,0,sizeof(map));
             for(i=0;i<n;i++){
                 scanf("%d %d %d",&u,&v,&cost);
                 map[u][v]+=cost;           //not just only one input
             }
             start=1,end=m;
    		 printf("%d
    ",Edmonds_Karp());
         }
         return 0;
     }
    

      

  • 相关阅读:
    【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
    【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)
    【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)
    【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)
    【原创】Chrome最新版(53-55)再次爆出BUG!
    AppBox v6.0中实现子页面和父页面的复杂交互
    FineUI(开源版)v6.0中FState服务器端验证的实现原理
    【已更新】【原创】Chrome53 最新版惊现无厘头卡死 BUG!
    FineUI(专业版)v3.2.0 发布(ASP.NET UI控件库)!
    FineUI(专业版)v3.1发布(ASP.NET控件库)!
  • 原文地址:https://www.cnblogs.com/scottding/p/3642151.html
Copyright © 2011-2022 走看看