hdu6214(求最小割最少边数)

来源:互联网 发布:2016中国人口迁移数据 编辑:程序博客网 时间:2024/05/21 07:48

题目

好像是和hdu3987差不多的?传送门

有两种方法:
1、对于所有容量值扩大(边数+1)倍然后+1,跑一边最大流得到的MAXFLOW/(边数+1)即为最大流,MAXFLOW%(边数+1)即最小割的边数。
(强行解释一波:我们可以将这个图里额外加的1作为最后计算,也就是如果最后某条增广路的1被拿走了那这就是最小割边之一)
2、跑一边最大流,然后把残量网络里的容量为0的边改为1,其他的边的容量改为inf,再跑一边最大流。就是答案。

第一种方法:

#include<bits/stdc++.h>using namespace std;const int MAXN = 100010;//点数的最大值const int MAXM = 400010;//边数的最大值const int INF = 0x3f3f3f3f;#define ll long longstruct Edge{    int to,next;    ll cap,flow;} edge[MAXM]; //注意是MAXMint tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];void init(){    tol = 0;    memset(head,-1,sizeof(head));}//加边,单向图三个参数,双向图四个参数void addedge(int u,int v,ll w,int rw=0){    edge[tol].to = v;    edge[tol].cap = w;    edge[tol].next = head[u];    edge[tol].flow = 0;    head[u] = tol++;    edge[tol].to = u;    edge[tol].cap = rw;    edge[tol].next = head[v];    edge[tol].flow = 0;    head[v]=tol++;}//输入参数:起点、终点、点的总数//点的编号没有影响,只要输入点的总数ll sap(int start,int end,int N){    memset(gap,0,sizeof(gap));    memset(dep,0,sizeof(dep));    memcpy(cur,head,sizeof(head));    int u = start;    pre[u] = -1;    gap[0] = N;    ll ans = 0;    while(dep[start] < N)    {        if(u == end)        {            int Min = INF;            for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])                if(Min > edge[i].cap - edge[i].flow)                    Min = edge[i].cap - edge[i].flow;            for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])            {                edge[i].flow += Min;                edge[i^1].flow -= Min;            }            u = start;            ans += Min;            continue;        }        bool flag = false;        int v;        for(int i = cur[u]; i != -1; i = edge[i].next)        {            v = edge[i].to;            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])            {                flag = true;                cur[u] = pre[v] = i;                break;            }        }        if(flag)        {            u = v;            continue;        }        int Min = N;        for(int i = head[u]; i != -1; i = edge[i].next)            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)            {                Min = dep[edge[i].to];                cur[u] = i;            }        gap[dep[u]]--;        if(!gap[dep[u]])return ans;        dep[u] = Min+1;        gap[dep[u]]++;        if(u != start) u = edge[pre[u]^1].to;    }    return ans;}int main(){    int t,n,m,vs,vt;    scanf("%d",&t);    while (t--)    {        init();        scanf("%d %d",&n,&m);        scanf("%d %d",&vs,&vt);        for(int i=0;i<m;i++)        {            int u,v,w;            scanf("%d %d %d",&u,&v,&w);            addedge(u,v,w*MAXM+1);        }        ll ans = sap(vs,vt,n)%MAXM;        printf("%lld\n",ans);    }    return 0;}
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀了二胎想离婚怎么办 如果闺蜜疏远了怎么办 考上博士但是硕士要延期怎么办 硕士延期也不能毕业怎么办 硕士论文工作量太少被延期了怎么办 竞彩足球比赛延期中断怎么办? 竞彩足球输了怎么办 讯飞语音不兼容百度怎么办 虎牙直播不兼容语音怎么办 为什么手机打开游戏就死机怎么办 2007cad打开时时死机怎么办 手机qq总是无响应怎么办 英雄联盟登录服务器未响应怎么办 苹果7p照相死机怎么办 小米手机qq打不开怎么办啊 电脑qq老是闪退怎么办 微信摄像卡住了怎么办 电脑打开应用程序没反应怎么办 宇飞来手机锁了怎么办 宇飞来手机忘记密码怎么办 vivo手机突然开不了机怎么办 苹果六关不了机怎么办 微信老是无响应怎么办 打游戏被骂了怎么办 微信运动跳转排行榜失败怎么办 小恩爱账号忘了怎么办 华为账号更换后游戏账号怎么办 注册游戏账号需要身份证怎么办 英雄联盟被裁决了怎么办 百度网盘密码重置不了怎么办 sap密码输入被锁怎么办 dnf二级密码错10怎么办 大网卡网速慢了怎么办 小米路由器无线速度慢怎么办 小米手机无线速度慢怎么办 电脑网卡驱动没了怎么办 电脑显示网卡驱动不正常怎么办 微信别人拒收消息怎么办 电脑无线网卡速度慢怎么办 网吧吃鸡更新慢怎么办 手机号注册不了微信怎么办