zoukankan      html  css  js  c++  java
  • poj 1459 多源多汇点最大流

    Sample Input

    2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20
    7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7
             (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5
             (0)5 (1)2 (3)2 (4)1 (5)4

    7个点包括电站和用户,2个电站,3个用户,13条边,输入13条边,输入2个电站,输入3个用户

    
    

    Sample Output

    15
    6


    增加一个源点一个汇点即可
      1 /*
      2 POJ 1459
      3 */
      4 
      5 #include<stdio.h>
      6 #include<string.h>
      7 #include<queue>
      8 #include<algorithm>
      9 #include<iostream>
     10 using namespace std;
     11 //****************************************************
     12 //最大流模板
     13 //初始化:g[][],start,end
     14 //******************************************************
     15 const int MAXN=110;
     16 const int INF=0x3fffffff;
     17 int g[MAXN][MAXN];//存边的容量,没有边的初始化为0
     18 int path[MAXN],flow[MAXN],start,end;
     19 int n;//点的个数,编号0-n.n包括了源点和汇点。
     20 
     21 queue<int>q;
     22 int bfs()
     23 {
     24     int i,t;
     25     while(!q.empty())q.pop();//把清空队列
     26     memset(path,-1,sizeof(path));//每次搜索前都把路径初始化成-1
     27     path[start]=0;
     28     flow[start]=INF;//源点可以有无穷的流流进
     29     q.push(start);
     30     while(!q.empty())
     31     {
     32         t=q.front();
     33         q.pop();
     34         if(t==end)break;
     35         //枚举所有的点,如果点的编号起始点有变化可以改这里
     36         for(i=0;i<=n;i++)
     37         {
     38             if(i!=start&&path[i]==-1&&g[t][i])
     39             {
     40                 flow[i]=flow[t]<g[t][i]?flow[t]:g[t][i];
     41                 q.push(i);
     42                 path[i]=t;
     43             }
     44         }
     45     }
     46     if(path[end]==-1)return -1;//即找不到汇点上去了。找不到增广路径了
     47     return flow[end];
     48 }
     49 int Edmonds_Karp()
     50 {
     51     int max_flow=0;
     52     int step,now,pre;
     53     while((step=bfs())!=-1)
     54     {
     55         max_flow+=step;
     56         now=end;
     57         while(now!=start)
     58         {
     59             pre=path[now];
     60             g[pre][now]-=step;
     61             g[now][pre]+=step;
     62             now=pre;
     63         }
     64     }
     65     return max_flow;
     66 }
     67 int main()//多源多汇点,在前面加个源点,后面加个汇点,转成单源单汇点
     68 {
     69     //freopen("in.txt","r",stdin);
     70     //freopen("out.txt","w",stdout);
     71     int np,nc,m;
     72     int u,v,z;
     73     while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
     74     {
     75         memset(g,0,sizeof(g));
     76         while(m--)
     77         {
     78             while(getchar()!='(');
     79             scanf("%d,%d)%d",&u,&v,&z);
     80             u++;v++;
     81             g[u][v]=z;
     82         }
     83         while(np--)
     84         {
     85             while(getchar()!='(');
     86             scanf("%d)%d",&u,&z);
     87             u++;
     88             g[0][u]=z;
     89         }
     90         while(nc--)
     91         {
     92             while(getchar()!='(');
     93             scanf("%d)%d",&u,&z);
     94             u++;
     95             g[u][n+1]=z;
     96         }
     97         n++;
     98         start=0;
     99         end=n;
    100         printf("%d
    ",Edmonds_Karp());
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    [NOI2015]程序自动分析
    D-query(莫队)
    小B的询问
    组合的输出 (dfs+记忆化)
    组合的输出 (dfs+记忆化)
    5719: 集合的划分(dfs)
    Search for a range, 在一个可能有重复元素的有序序列里找到指定元素的起始和结束位置
    Find Min In Rotated Sorted Array2,包含重复数字的反转序列找最小值。
    Find Min In Rotated Sorted Array,寻找反转序列中最小的元素。
    Search In Rotated SortedArray2, 有重复数据的反转序列。例如13111.
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4284779.html
Copyright © 2011-2022 走看看