• 最小路径覆盖问题(网络流最大流)


    最小路径覆盖问题(网络流最大流)

    题目

    洛谷题目传送门

    题解

    网络流题目详讲

    code

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iomanip>
    #include<algorithm>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<vector>
    #define rg register
    #define il inline
    #define lst long long
    #define ldb long double
    #define N 550
    #define M 100050
    using namespace std;
    const int Inf=1e9;
    il int read()
    {
        rg int s=0,m=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
        while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
        return m?-s:s;
    }
    
    int n,m,S,T,ans;
    int to[N],tag[N],dep[N];
    int hd[N],cur[N],cnt=1;
    struct EDGE{int to,nxt,c;}ljl[M<<1];
    il void add(rg int p,rg int q,rg int o)
    {
        ljl[++cnt]=(EDGE){q,hd[p],o},hd[p]=cnt;
        ljl[++cnt]=(EDGE){p,hd[q],0},hd[q]=cnt;
    }
    
    queue<int> Q;
    il bool BFS()
    {
        for(rg int i=S;i<=T;++i)dep[i]=0;
        while(!Q.empty())Q.pop();
        Q.push(S),dep[S]=1;
        while(!Q.empty())
        {
            rg int now=Q.front();Q.pop();
            for(rg int i=hd[now];i;i=ljl[i].nxt)
            {
                rg int qw=ljl[i].to;
                if(!dep[qw]&&ljl[i].c>0)
                {
                    dep[qw]=dep[now]+1;
                    Q.push(qw);
                }
            }
        }
        return dep[T];
    }
    
    int dfs(rg int now,rg int aim,rg int flow)
    {
        if(now==aim)return flow;
        for(rg int &i=cur[now];i;i=ljl[i].nxt)
        {
            rg int qw=ljl[i].to;
            if(ljl[i].c>0&&dep[qw]==dep[now]+1)
            {
                rg int kk=dfs(qw,aim,min(flow,ljl[i].c));
                if(kk>0)
                {
                    to[now]=qw;
                    if(now!=S)tag[qw-n]=1;
                    ljl[i].c-=kk,ljl[i^1].c+=kk;
                    return kk;
                }
            }
        }
        return 0;
    }
    
    il int Dinic()
    {
        rg int ans=0;
        while(BFS())
        {
            for(rg int i=S;i<=T;++i)cur[i]=hd[i];
            while(int kk=dfs(S,T,Inf))ans+=kk;
        }
        for(rg int i=1;i<=n;++i)
            if(!tag[i])
            {
                rg int now=i;
                printf("%d ",now);
                while(to[now]&&to[now]!=T)
                {
                    printf("%d ",to[now]-n);
                    now=to[now]-n;
                }
                puts("");
            }
        return ans;
    }
    
    int main()
    {
        n=read(),m=read();
        S=0,T=2*n+1;
        for(rg int i=1;i<=n;++i)
            add(S,i,1),add(i+n,T,1);
        for(rg int i=1;i<=m;++i)
        {
            rg int p=read(),q=read();
            add(p,q+n,1);
        }
        printf("%d
    ",n-Dinic());
        return 0;
    }
    
  • 相关阅读:
    【git hub使用】
    【struct2 第一天】
    【JSP基础 第一天】
    【Java基础学习 day01】
    网站建设 【Django】 【MTV】
    Python-Json字符串和XML解析
    Python-冒泡和快排
    Python-面向对象编程
    练习-字符串编码
    练习-统计文件中单词数量
  • 原文地址:https://www.cnblogs.com/cjoierljl/p/9415902.html
Copyright © 2020-2023  润新知