最大流模板

来源:互联网 发布:哪个校音器软件好用 编辑:程序博客网 时间:2024/06/06 05:56
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 444 //邻接表要开边数的2倍struct Edge{    int v,cap,next;}edge[MAXN];int level[MAXN];//标记层次(距离标号)//间隙优化,定义gap[i]为标号是i的点的个数//在重标记i时,检查gap[level[i]],若减为0,这算法结束。int gap[MAXN];int pre[MAXN];//前驱int cur[MAXN];int head[MAXN];int NV,NE;//NE为边数,初始化为0;void Insert(int u,int v,int cap,int cc=0){    edge[NE].cap=cap;edge[NE].v=v;    edge[NE].next=head[u];head[u]=NE++;    edge[NE].cap=cc;edge[NE].v=u;    edge[NE].next=head[v];head[v]=NE++;}//参数,源点,汇点int SAP(int vs,int vt){    memset(level,0,sizeof(level));    memset(pre,-1,sizeof(pre));    memset(gap,0,sizeof(gap));    //cur[i]保存的是当前弧    for(int i=0;i<=NV;i++)cur[i]=head[i];    int u=pre[vs]=vs;//源点的pre还是其本身    int maxflow=0,aug=0x7FFFFFFF;gap[0]=NV;    while(level[vs]<NV){loop :        for(int &i=cur[u];i!=-1;i=edge[i].next){            int v=edge[i].v;//v是u的后继            //寻找可行弧            if(edge[i].cap&&level[u]==level[v]+1){                //aug表示增广路的可改进量                aug=min(aug,edge[i].cap);                pre[v]=u;u=v;                //如果找到一条增广路                if(v==vt){                    maxflow+=aug;//更新最大流;                    //路径回溯更新残留网络                    for(u=pre[v];v!=vs;v=u,u=pre[u]){                        //前向弧容量减少,反向弧容量增加                        edge[cur[u]].cap-=aug;                        edge[cur[u]^1].cap+=aug;                    }                    aug=0x7fffffff;                }                goto loop;            }        }        int minlevel=NV;        //寻找与当前点相连接的点中最小的距离标号(重标号)        for(int i=head[u];i!=-1;i=edge[i].next){            int v=edge[i].v;            if(edge[i].cap&&minlevel>level[v]){                cur[u]=i;//保存弧                minlevel=level[v];            }        }        if((--gap[level[u]])==0)break;//更新gap数组后如果出现断层,则直接退出。        level[u]=minlevel+1;//重标号        gap[level[u]]++;//距离标号为level[u]的点的个数+1;        u=pre[u];//转当前点的前驱节点继续寻找可行弧    }    return maxflow;} int main(){    int m;//边的条数    while(~scanf("%d%d",&m,&NV)){        memset(head,-1,sizeof(head));        NE=0;        for(int i=1;i<=m;i++){            int u,v,cap;            scanf("%d%d%d",&u,&v,&cap);            Insert(u,v,cap);        }        printf("%d\n",SAP(1,NV));    }    return 0;}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 喝多了全身痛怎么办 喝完酒第二天浑身酸痛怎么办 鑫和陌车骗我钱怎么办 社会人加你qq怎么办 有人问你加qq怎么办 住酒店遇到被色情诈骗怎么办 怎么办我陷入感情骗局了 移动手机卡被强制停机怎么办 诚e赊套现被骗了怎么办 钻戒小了怎么办小窍门 爱用商城逾期了怎么办 工程骗局洗脑了怎么办 还网贷客服电话打不通怎么办 中信客服电话打不通怎么办 亚马逊客服电话打不通怎么办 安卓软件闪退怎么办? 吃鸡麦克风炸麦怎么办 美版iphone屏摔了怎么办 天地荣域四十后怎么办 淘宝拍下商品不付款怎么办 淘宝买东西取消订单淘金币怎么办 淘宝淘金币快过期了怎么办 公众号密码忘了怎么办 酷狗直播个入驻粉丝少怎么办 健康证预约显示未接收怎么办 在互惠车贷逾期怎么办 天天中彩票怎么登陆不了怎么办 正宇新商城不能提现怎么办 融e购买完不发货怎么办 婴儿肚子胀气肚脐凸出来怎么办 微信商城买东西被骗了怎么办 拼多多商家不发货怎么办 鞋上的饰品掉了怎么办 饰品上的钻掉了怎么办 dota2饰品被好友礼物怎么办 dota2接收的礼物打不开怎么办 英雄联盟线上被压制怎么办 云联商城的钱怎么办 高顿财经不退款怎么办 拼多多连不上网怎么办 拼多多评分太低怎么办