关于网络流的增广路算法,网上有很多详细介绍,这里是摘录的模板。详细请见:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html
1 #include<iostream> 2 #include<iomanip> 3 #include<ctime> 4 #include<climits> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<cstring> 9 #include<cstdio> 10 #include<cstdlib> 11 #include<map> 12 using namespace std; 13 typedef unsigned long long LL; 14 #define rep(i,a,b) for(int i=a;i<=b;i++) 15 #define dep(i,a,b) for(int i=a;i>=b;i--) 16 int n,m; 17 const int M=201; 18 int G[M][M];//残量网络,初始为给定的流网络 19 int road[M];//记录增广路中各点的前驱 20 int F[M];//记录增广路中到达当前点的最大流量 21 queue<int>q;//利用队列实现bfs 22 int bfs(){ 23 memset(road,-1,sizeof(road)); 24 while(!q.empty())q.pop(); 25 //默认为源点为1节点,汇点为n节点 26 q.push(1); 27 road[1]=0;F[1]=INT_MAX; 28 while(!q.empty()){ 29 int u=q.front(); 30 q.pop(); 31 if(u==n)break;//已经找到增广路,直接退出 32 rep(i,1,n){ 33 if(road[i]==-1&&G[u][i]){//当前节点未被访问,且边(u,i)在残量网络中 34 road[i]=u; 35 F[i]=min(F[u],G[u][i]); 36 q.push(i); 37 } 38 } 39 } 40 if(road[n]==-1)return -1; 41 return F[n]; 42 } 43 int main(){ 44 scanf("%d%d",&m,&n); 45 memset(G,0,sizeof(G)); 46 rep(i,1,m){ 47 int u,v; 48 scanf("%d%d",&u,&v); 49 scanf("%d",&G[u][v]); 50 } 51 52 int ans=0,add; 53 while((add=bfs())!=-1){ 54 ans+=add; 55 int now=n; 56 while(now!=1){ 57 int pre=road[now]; 58 G[pre][now]-=add;//更新残量网络中的边 59 G[now][pre]+=add;//添加反向边 60 now=pre; 61 } 62 } 63 printf("%d",ans); 64 }
应用:BZOJ1001狼抓兔子
时间: 2024-10-09 09:13:46