• P2764 最小路径覆盖问题


    传送门:

    二分图构图思想!!!

    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    using namespace std;
    #define ll long long
    #define re register
    #define pb push_back;
    const int N=1e4;
    const int inf=1e9;
    inline void read(int &a)
    {
        a=0;
        int d=1;
        char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    queue <int> q;
    struct note
    {
        int next,dis,v,u;
    }edge[4*N];
    int head[2*N],f[2*N],num,deep[2*N],n,m;
    inline void init()
    {
        for(re int i=1;i<=n;i++)
            f[i]=i;
        memset(head,0xff,sizeof(head));
        num=-1;
    }
    inline void add(int u,int v,int dis)
    {
        edge[++num].next=head[u];
        edge[num].v=v;
        edge[num].u=u;
        edge[num].dis=dis;
        head[u]=num;
    }
    inline bool bfs(int s,int t)
    {
        while(!q.empty())
            q.pop();
        memset(deep,0x7f,sizeof(deep));
        deep[s]=0;
        q.push(s);
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            for(re int i=head[now];i!=-1;i=edge[i].next)
            {
                if(deep[edge[i].v]>inf&&edge[i].dis)
                {
                    deep[edge[i].v]=deep[now]+1;
                    q.push(edge[i].v);
                }
            }
        }
        if(deep[t]<inf)
            return true;
        return false;
    }
    inline int dfs(int now,int t,int limit)
    {
        if(now==t||!limit)
            return limit;
        int flow=0,x;
        for(re int i=head[now];i!=-1;i=edge[i].next)
        {
            if(deep[now]+1==deep[edge[i].v]&&(x=dfs(edge[i].v,t,min(edge[i].dis,limit))))
            {
                flow+=x;
                edge[i].dis-=x;
                edge[i^1].dis+=x;
                limit-=x;
                if(!limit)
                    break;
            }
        }
        return flow;
    }
    inline int dinic(int s,int t)
    {
        int ans=0;
        while(bfs(s,t))
            ans+=dfs(s,t,inf);
        return ans;
    }
    inline void write(int x)
    {
        printf("%d ",x);
        for(re int i=head[x];i!=-1;i=edge[i].next)
            if(!edge[i].dis&&edge[i].v>n)
                write(edge[i].v-n);
    }
    inline int getv(int v){return f[v]=v==f[v]?v:getv(f[v]);}
    int main()
    {
        //freopen("in.txt","r",stdin);
        read(n);
        read(m);
        init();
        int s=0,t=(n<<1)+1;
        for(re int i=0;i<m;i++)
        {
            int x,y;
            read(x);
            read(y);
            add(x,n+y,1);
            add(n+y,x,0);
        }
        for(re int i=1;i<=n;i++)
            add(s,i,1),add(i,s,0);
        for(re int i=n+1;i<=(n<<1);i++)
            add(i,t,1),add(t,i,0);
        int ans=n-dinic(s,t);
        for(re int i=0;i<=num;i++)
            if(edge[i].u>=1&&edge[i].u<=n&&edge[i].v>n&&edge[i].v<t&&!edge[i].dis)
                f[getv(edge[i].v-n)]=getv(edge[i].u);
        for(re int i=1;i<=n;i++)
            if(f[i]==i)
                write(i),putchar('
    ');
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    沉痛的一天
    PowerBuilder之5年经验谈(一之1)--PB对Unicode的支持
    C# Client API for Sphinx (support to 0.99)
    F#学习笔记基本类型
    F#学习笔记方法
    接口串联
    eclipse 中如何设置注释?
    软件测试过程中手机截屏
    Postan中执行接口时使用JSON数据,那么什么是 JSON?
    MySQL使用dump备份以及恢复备份
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11107122.html
Copyright © 2020-2023  润新知