网络流--队列

来源:互联网 发布:南光坊天海 知乎 编辑:程序博客网 时间:2024/06/06 03:44
    //Edmonds_Karp      #include<iostream>      #include<queue>      #include<algorithm>     #include<cstring>    using namespace std;      const int N=201;      const int INF=99999999;      int n,m,sum,s,t;//s,t为始点和终点      int flow[N][N],cap[N][N],a[N],p[N];      //分别为:flow[u][v]为<u,v>流量、cap[u][v]为<u,v>容量、a[i]表示源点s到节点i的路径上的最小残留量、p[i]记录i的前驱      int min(int a,int b){return a<=b?a:b;}      void Edmonds_Karp(){        int i,u,v;        queue<int>q;//队列,用bfs找增广路          while(1){              memset(a,0,sizeof(a));//每找一次,初始化一次              a[s]=INF;              q.push(s);//源点入队              while(!q.empty()){                  u=q.front();                  q.pop();                  for(v=1;v<=m;v++){                      if(!a[v]&&flow[u][v]<cap[u][v]){                          p[v]=u;                          q.push(v);                          a[v]=min(a[u],cap[u][v]-flow[u][v]);//s-v路径上的最小残量                      }                  }                  if(u==m)break;            }              if(a[m]==0)break;//找不到增广路,则当前流已经是最大流                          sum+=a[m];//流加上              for(i=m;i!=s;i=p[i]){// //从汇点顺着这条增广路往回走                     flow[p[i]][i]+=a[m];//更新正向流量                  flow[i][p[i]]-=a[m];//更新反向流量              }          }          printf("%d\n",sum);      }      int main(){          int v,u,w;          while(scanf("%d%d",&n,&m)!=EOF){              s=1;//从1开始              t=m;//m为汇点              sum=0;//记录最大流量              memset(flow,0,sizeof(flow));//初始化              memset(cap,0,sizeof(cap));              while(n--){                  scanf("%d%d%d",&u,&v,&w);                  cap[u][v]+=w;//注意图中可能出现相同的边              }              Edmonds_Karp();          }          return 0;      }  
0 0