hdu 3549 最大流入门

   
   
   
   
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
题意 :  给n个点,m条边,和边的容量 。求第一个顶点到最后一个顶点的的最大流  ; 用最简单的 Ford-Fulkerson求最大流;
依次找增光路,知道找不到一条从s到 t 的增光路,此时即得到最大流   ;  
#include<cstdio> #include<cstring> //#include<M> #include<vector> #include<cmath> #include<cstdlib> #include<stack> #include<queue> #include <iomanip> #include<iostream> #include<algorithm> using namespace std ; const int N=1005; int pre[N];       //保存增广路径上的点的前驱顶点 bool vis[N]; int M[N][N];    //残留网络容量, int s,t;          //s为源点,t为汇点 int n,m; bool BFS()        //找增广路 {     int i,cur;     queue<int>Q;     memset(pre,0,sizeof(pre));     memset(vis,0,sizeof(vis));     vis[s]=true;    Q.push(s);     while(!Q.empty())     {         cur=Q.front();         Q.pop();         if(cur==t) return true;       //如果已达到汇点t,表明已经找到一条增广路径,返回true.         for(i=1;i<=n;i++)         {             if(!vis[i]&&M[cur][i])  //只有残留容量大于0时才存在边,可增流量为0,说明饱和了。              {                 Q.push(i);                 pre[i]=cur;                 vis[i]=true;             }         }     }     return false; } int Max_Flow() {     int i,ans=0;     while(true)     {         if(!BFS()) return ans;     //如果找不到增广路径就返回。说明找到了最大流          int Min=999999999;         for(i=t;i!=s;i=pre[i])     //通过pre[]数组查找增广路径上的边,求出残留容量的最小值。             Min=min(Min,M[pre[i]][i]);         for(i=t;i!=s;i=pre[i])         {             M[pre[i]][i]-=Min;       //可修改流量减少              M[i][pre[i]]+=Min;      //反向流量增加          }         ans+=Min;                  //没找到一条增光路,累加流量      } } int main() {     int T,k=1;     int u,v,c;     scanf("%d",&T);     while(T--)     {         scanf("%d%d",&n,&m);         s=1; t=n;         memset(M,0,sizeof(M));         while(m--)         {             scanf("%d%d%d",&u,&v,&c);             M[u][v]+=c;  //初始化u->v ,可修改流量为c ,反向M[v][u],即为当前流量。等同残留网络中的         }         printf("Case %d: %d\n",k++,Max_Flow());     }     return 0; }

你可能感兴趣的:(hdu 3549 最大流入门)