• # [洛谷1345] 奶牛的电信 (最大流最小割)


    [洛谷1345] 奶牛的电信 (最大流最小割)

    洛谷1345

    题意

    给出点的个数,边的条数,源点和汇点。

    分别给出与边相连的点,边权为1。

    求最少删去多少点使得源点和汇点不连通。

    思路

    • 割点转割边+最大流最小割

    • 最大流最小割定理:最大流=最小割

    • 割:删去一些边使得源点和汇点不连通

    题目是求删点,最大流最小割算法删的是边,所以要割点转化为割边(最大流最小割其实并不能算一个算法,只是将求最小割转化为求最大流)

    建模

    将一个点拆成两个点,其中一个点负责连接入边,另外一个点负责连接出边,拆成的两个点之间边权为1,表示只能一个点只能删一次(如果这条边被删了,入边和出边无法连通表示点被删除)。由于求的是删除点的个数,其他的边置为INF。

    举个栗子

    代码实现

    这题我的代码建了反向边,但是有些Ac代码没有建反向边,我也不知道为什么可以不用建反向边,望路过的大佬指点指点。

    #include <bits/stdc++.h>
    using namespace std;
    #define fre freopen("data.in","r",stdin);
    #define ms(a) memset((a),0,sizeof(a))
    #define go(i,a,b) for(register int (i)=(a);(i)<(b);++(i))
    #define rep(i,a,b) for(register int (i)=(a);(i)<=(b);++(i))
    #define sf(x) scanf("%d",&(x))
    #define reg register
    typedef long long LL;
    const int inf=(100000);
    const int maxn=1e2+5;
    const int maxm=6e2+5;
    struct node{int to,flow,next;}e[(maxn+maxm)<<1];
    int n,m,s,t;
    int head[maxn<<1],cur[maxn<<1],deep[maxn<<1];
    int cnt;
    queue<int> q;
    inline void add(int x,int y,int w){
        e[cnt].to=y,e[cnt].flow=w,e[cnt].next=head[x];
        head[x]=cnt++;
    }
    
    inline bool bfs(){
        memset(deep,0,sizeof(deep));
        deep[s]=1;q.push(s);
        int u,v;
        while(!q.empty()){
            u=q.front();q.pop();
            for(int i=head[u];~i;i=e[i].next){
                v=e[i].to;
                if(!deep[v]&&e[i].flow){
                    deep[v]=deep[u]+1;
                    q.push(v);
                }
            }
        }
        return deep[t];
    }
    int dfs(int now,int nowFlow){
        if(now==t)return nowFlow;
        int totFlow=0;
    //    if(now==10){
    //        puts("bug
    ");
    //    }
        for(int i=cur[now],v;~i;i=e[i].next){
            cur[now]=i;v=e[i].to;
    //        if(v==5){
    //            puts("bug
    ");
    //        }
            if(deep[v]==deep[now]+1&&e[i].flow){
                int canFlow=dfs(v,min(nowFlow,e[i].flow));
                if(!canFlow)continue;
                totFlow+=canFlow,nowFlow-=canFlow;
                e[i].flow-=canFlow;e[i^1].flow+=canFlow;
                if(nowFlow<=0)break;
            }
        }
        if(totFlow<=0)deep[now]=-2;
        return totFlow;
    }
    inline void Dinic(){
        int maxFlow=0;
        while(bfs()){
          //  puts("bfs");
            memcpy(cur,head, sizeof(head));
            maxFlow+=dfs(s,inf);
          //  puts("dfs");
        }
        printf("%d
    ",maxFlow);
    }
    int main(){
        scanf("%d%d%d%d",&n,&m,&s,&t);
        memset(head,-1,sizeof(head));
        rep(i,1,n){
            add(i,i+n,1);add(i+n,i,0);
        }
        s+=n;
        for(int i=0,x,y;i<m;++i){
            scanf("%d%d",&x,&y);
            add(x+n,y,inf);add(y+n,x,inf);
        }
        Dinic();
        return 0;
    }
    
  • 相关阅读:
    Delphi中WebBrowser控件打开部分网站报"Invalid floating point operation”解决
    delphi中URL的汉字编码
    python手记(11)
    李维对VCL理解的几个错误
    如何配置MYSQL的MASTER---SLAVE复制备份?
    UniDAC连接Embedded MySQL server
    unigui组件中client javascript delphi组件之间的操作
    Delphi中SendMessage使用说明(所有消息说明) good
    iOS面试题
    Windows的MAX_PATH
  • 原文地址:https://www.cnblogs.com/sstealer/p/12210238.html
Copyright © 2020-2023  润新知