LibreOJ #6002. 「网络流 24 题」最小路径覆盖

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LibreOJ #6002. 「网络流 24 题」最小路径覆盖相关的知识,希望对你有一定的参考价值。

                        内存限制:256 MiB 时间限制:1000 ms 标准输入输出
                          题目类型:传统 评测方式:Special Judge
                                上传者: 匿名

网络流 最大流

屠龙宝刀点击就送

#include <cstring>
#include <cstdio>
#include <queue>
#define N 6005
#define inf 0x3f3f3f3f

using namespace std;
bool flag[N];
int n,m,dep[N],nextt[N<<1],to[N<<1],flow[N<<1],head[N],cnt=1,Next[N];
inline void ins(int u,int v,int l)
{
    nextt[++cnt]=head[u];
    to[cnt]=v;
    flow[cnt]=l;
    head[u]=cnt;
}
bool bfs(int s,int t)
{
    for(int i=s;i<=t;++i) dep[i]=-1;
    dep[s]=0;
    queue<int>q;
    q.push(s);
    for(int now;!q.empty();)
    {
        now=q.front();
        q.pop();
        for(int i=head[now];i;i=nextt[i])
        {
            int v=to[i];
            if(dep[v]==-1&&flow[i])
            {
                dep[v]=dep[now]+1;
                if(v==t) return true;
                q.push(v);
            }
        }
    }
    return false;
}
inline int min(int a,int b) {return a>b?b:a;}
int dfs(int now,int t,int Limit)
{
    if(now==t||!Limit) return Limit;
    int f,ret=0;
    for(int i=head[now];i;i=nextt[i])
    {
        int v=to[i];
        if(dep[v]==dep[now]+1&&flow[i]&&(f=dfs(v,t,min(flow[i],Limit))))
        {
            if(v>n) flag[v-n]=1;
            flow[i]-=f;
            flow[i^1]+=f;
            Limit-=f;
            ret+=f;
            Next[now]=v;
            if(!Limit) break;
        }
    }
    if(Limit!=ret) dep[now]=-1;
    return ret;
}
int dinic(int s,int t)
{
    int ret=0;
    for(;bfs(s,t);ret+=dfs(s,t,inf));
    return ret;
}
int Main()
{
    scanf("%d%d",&n,&m);
    int s=0,t=n*2+1;
    for(int x,y;m--;)
    {
        scanf("%d%d",&x,&y);
        ins(x,y+n,inf);
        ins(y+n,x,0);
    }
    for(int i=1;i<=n;++i)
    {
        ins(s,i,1);ins(i,s,0);
        ins(i+n,t,1);ins(t,i+n,0);
    }
    int ans=n-dinic(s,t);
    for(int i=1;i<=n;++i)
    {
        if(flag[i]) continue;
        int now=i;
        printf("%d ",now);
        for(;Next[now];now=Next[now])
        {
            if(Next[now]>n) Next[now]-=n;
            printf("%d ",Next[now]);
        }
        printf("\\n");
    }
    printf("%d\\n",ans);
    return 0;
}
int sb=Main();
int main(int argc,char *argv[]) {;}

 

以上是关于LibreOJ #6002. 「网络流 24 题」最小路径覆盖的主要内容,如果未能解决你的问题,请参考以下文章

LOJ#6002. 「网络流 24 题」最小路径覆盖

LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图

LibreOJ 6002 最小路径覆盖(最大流)

网络流 24 题汇总(LOJ 上只有 22 题???)

洛谷 P2764 LibreOJ 6002 最小路径覆盖问题

LibreOJ #101. 最大流