标签:dir pop turn bsp std nbsp rect 反向 直接
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=0x3f3f3f3f; 4 const int maxn=1005; 5 struct edge{int to,cap,rev;};//指向节点to,边容量是cap,rev是记录为当前邻接点to反向边的编号 6 vector<edge> G[maxn];//邻接表,G[i][j]表示节点i连接的第j条边包含的所有信息 7 int t,n,m,x,y,c,level[maxn];//level数组在bfs时为分层图所用 8 void add_edge(int from,int to,int cap){//向图中增加一条从s到t容量为cap的边 9 G[from].push_back((edge){to,cap,G[to].size()}); 10 G[to].push_back((edge){from,0,G[from].size()-1}); 11 } 12 //通过bfs给图分层次 13 void bfs(int s){ 14 memset(level,-1,sizeof(level));//刚开始每个节点的层次置为-1 15 queue<int> que;//队列实现bfs 16 level[s]=0;//源点s为第0层 17 que.push(s); 18 while(!que.empty()){//给图分层 19 int v=que.front();que.pop(); 20 for(size_t i=0;i<G[v].size();++i){//遍历节点v与之相连的每条边 21 edge &e=G[v][i];//取出与节点v相连的第i条边 22 if(e.cap>0&&level[e.to]<0){//如果边残余流量大于0,且节点e.to还未分层 23 level[e.to]=level[v]+1;//节点e.to的层次为指向它的节点v所在层次数加1 24 que.push(e.to); 25 } 26 } 27 } 28 } 29 //通过dfs寻找最短增广路 30 int dfs(int v,int t,int f){//v->t,当前流量是f 31 if(v==t)return f;//如果当前节点v为本身,则直接返回当前的流量值 32 for(size_t i=0;i<G[v].size();++i){//遍历节点v与之相连的每条边 33 edge &e=G[v][i];//取出与节点v相连的第i条边 34 if(e.cap>0 && level[v]<level[e.to]){//如果该边残流量大于0,且邻接点e.to是v的下一级,就增广下去 35 int d=dfs(e.to,t,min(f,e.cap));//维护增广路径上的最小容量:s-->t,最小容量为d 36 if(d>0){//回溯时如果增广路径上的最小容量大于0,说明找到了增广路径,将增广路径上的每条边减去最小可流量 37 e.cap-=d;//正向边减去最小流量 38 G[e.to][e.rev].cap+=d;//反向边加上最小流量 39 return d;//回溯到上一层,返回当前增广路径上的最小容量;当回到源点S时,继续查找是否还有增广路径 40 } 41 } 42 } 43 return 0;//否则说明没有增广路,返回当前的最小的流量为0 44 } 45 //Dinic算法实现最大流,每个阶段执行完一次bfs分层之后,只需查找当前层次图中是否还增广路径即可 46 int max_flow(int s,int t){ 47 int flow=0; 48 while(1){ 49 bfs(s);//每个阶段先bfs将图分层标记 50 if(level[t]<0)return flow;//如果分层之后,终点t的层次小于0,即没有被分层,说明已没有增广路了,直接返回当前最大流量 51 int f=dfs(s,t,INF); 52 while(f>0){//在该层次图中找到增广路的最小流量 53 flow+=f;//先将其流量相加 54 f=dfs(s,t,INF);//然后循环找该层次图中是否还有增广路径 55 } 56 } 57 } 58 int main(){ 59 while(~scanf("%d",&t)){ 60 for(int cas=1;cas<=t;++cas){ 61 scanf("%d%d",&n,&m); 62 for(int i=0;i<=n;++i)G[i].clear(); 63 while(m--){ 64 scanf("%d%d%d",&x,&y,&c); 65 add_edge(x,y,c); 66 } 67 printf("Case %d: %d\n",cas,max_flow(1,n)); 68 } 69 } 70 return 0; 71 }
题解报告:hdu 3549 Flow Problem(最大流入门)
标签:dir pop turn bsp std nbsp rect 反向 直接
原文地址:https://www.cnblogs.com/acgoto/p/9845914.html