poj 1273 最大流 基础题 (内有最详细的最大流分析,很好入门)

来源:互联网 发布:uboot 源码 编辑:程序博客网 时间:2024/06/07 13:03
详细的最大流基础:http://course.cug.edu.cn/cugFirst/operational_research/main/charpter7/p4.htm#                       http://www.cppblog.com/mythit/archive/2009/04/19/80470.aspx(里边有点小错误,很明显,但解释的通俗易懂)#include <cstdio>      #include <cstdlib>      #include <iostream>      #include <string.h>      #include <queue>      #include <limits.h>      #define MAX 250      using namespace std;      int cap[MAX][MAX];      int m;      int EKarp(int s,int t)      {          queue<int> Q;          int flow[MAX][MAX],a[MAX],u,v,f,pre[MAX];          f = 0;          memset(flow,0,sizeof(flow));          while(1)          {              Q.push(s);              memset(a,0,sizeof(a));              a[s] = INT_MAX;  ///a[i]存储的是源点s到节点i的路径上的最小残留量,因为a[i]总是整数.于是可用它来替代标记数组            while( !Q.empty() )              {                  u = Q.front();                  Q.pop();                  for(v=1; v<=m; v++)                      if( !a[v] && cap[u][v] > flow[u][v] )                      {                          Q.push(v);                          a[v] = a[u] < cap[u][v] - flow[u][v] ? a[u] : cap[u][v] - flow[u][v];  //增广路径最小的残留容量                        pre[v] = u;                      }              }              if( a[t] == 0 )  //没有了增广路径,就停止了                break;              for(u=t; u!=s; u=pre[u])              {                  flow[pre[u]][u] += a[t];  //正向流增加                flow[u][pre[u]] -= a[t];  //反向流减少            }              f += a[t];          }          return f;      }      int main()      {          int from,to,c,n,ans;          while( scanf("%d%d",&n,&m) != EOF )          {              memset(cap,0,sizeof(cap));              while( n-- )              {                  scanf("%d%d%d",&from,&to,&c);                  cap[from][to] += c;  //注意,不一定只有一条边,每两点间            }              ans = EKarp(1,m);              printf("%d\n",ans);          }      system("pause");     return 0;      }  


原创粉丝点击