最大流

还是比较好理解的,看大白后一下就理解了,注释也写得很详细了,直接上模板吧

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <queue>
  6 
  7 using namespace std;
  8 
  9 #define MAXN 30
 10 #define INF 1e8
 11 
 12 struct Edge
 13 {
 14     int from,to,cap,flow;
 15     Edge(int fr,int t,int c,int f):from(fr),to(t),cap(c),flow(f){}
 16 };
 17 
 18 int n,real_m,m; //n个点,m条边
 19 vector<Edge> edges; //所有的边
 20 vector<int> G[MAXN]; //G[i][j]表示 起点 i 的第 j 条边的序号
 21 int add[MAXN]; //可增量
 22 int pre[MAXN]; //前驱
 23 
 24 void Init()
 25 {
 26     edges.clear();
 27     for(int i=0;i<=n;i++)
 28         G[i].clear();
 29 }
 30 
 31 int AddEdge(int from,int to,int cap)
 32 {
 33     edges.push_back(Edge(from,to,cap,0));
 34     edges.push_back(Edge(to,from,0,0));
 35     m=edges.size();
 36     G[from].push_back(m-2);
 37     G[to].push_back(m-1);
 38     return 0;
 39 }
 40 
 41 int MaxFlow(int s,int t)
 42 {
 43     int flow=0;
 44     while(1)
 45     {
 46         memset(add,0,sizeof(add));
 47 
 48         add[s]=INF;
 49         queue<int> Q;
 50         Q.push(s);
 51 
 52         while(!Q.empty())
 53         {
 54             int u = Q.front(); Q.pop();
 55             for(int i=0;i<G[u].size();i++)
 56             {
 57                 Edge e = edges[G[u][i]];
 58                 if(!add[e.to]&&e.cap>e.flow)//如果没去过并且可增
 59                 {
 60                     add[e.to]=min(add[u],e.cap-e.flow);
 61                     pre[e.to]=G[u][i];
 62                     Q.push(e.to);
 63                 }
 64                 if(add[t])
 65                     break;
 66             }
 67         }
 68         if (!add[t]) //不能增了
 69             break;
 70 
 71         for(int u=t;u!=s;u=edges[pre[u]].from)
 72         {
 73             int num=pre[u];//那条边的编号
 74             edges[num].flow +=add[t];
 75             edges[num^1].flow-=add[t];
 76         }
 77         flow+=add[t];
 78     }
 79     return flow;
 80 }
 81 
 82 int main()
 83 {
 84     while(1)
 85     {
 86         cout<<"输入顶点个数:"; cin >> n;
 87         Init();
 88 
 89         int from , to ,cap;
 90         cout<<"输入边个数:"; cin>>real_m;
 91         cout<<"起点 终点 容量"<<endl;
 92         for(int i=0;i<real_m;i++)
 93         {
 94             scanf("%d%d%d",&from,&to,&cap);
 95             AddEdge(from,to,cap);
 96         }
 97         int s,t;
 98         cout<<"起点:"; cin >> s;
 99         cout<<"终点:"; cin >> t;
100         cout<<"最大流量为:"<<MaxFlow(s,t)<<endl;
101     }
102     return 0;
103 }
View Code

 

转载于:https://www.cnblogs.com/haoabcd2010/p/6836973.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值