[P2764最小路径覆盖问题]

  • 模板题不多说,因为是以前写的代码,所以可能比较young。
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
int ans=0,len=0,lin[500],din[50000],dout[50000],level[500],x,y,S,T,n,m,q[500];
int q1[500],q2[500],tail1=0,tail2=0;
bool f[500];
struct one
{
    int x,y,v,next,reverse;
};
one e[30000];
void insert(int xx,int yy)
{
    e[++len].next=lin[xx];
    lin[xx]=len;
    e[len].x=xx;
    e[len].y=yy;
    e[len].v=1;
    e[len].reverse=len+1;
    e[++len].next=lin[yy];
    lin[yy]=len;
    e[len].x=yy;
    e[len].y=xx;
    e[len].v=0;
    e[len].reverse=len-1;
}
bool makelevel()
{
    memset(level,-1,sizeof(level));
    level[0]=0;
    q[1]=0;
    int head=0,tail=1,tn,ty;
    while(head++<tail)
    {
        tn=q[head];
        for(int i=lin[tn];i;i=e[i].next)
        {
            ty=e[i].y;
            if(level[ty]<0&&e[i].v>0)
            {
                level[ty]=level[tn]+1;
                q[++tail]=ty;
            }
        }
    }
    return level[T]>=0;
}
int MAXflow(int aa,int flow)
{
    if(aa==T)return flow;
    int maxflow=0,d;
    for(int i=lin[aa];maxflow<flow&&i;i=e[i].next)
    {
        if(level[e[i].y]==level[aa]+1&&e[i].v>0)
        {
            d=MAXflow(e[i].y,min(e[i].v,flow-maxflow));
            e[i].v-=d;
            e[e[i].reverse].v+=d;
            maxflow+=d;
        }
    }
    if(maxflow<=0)level[aa]=-1;
    return maxflow;
}
void work(int p)
{
    tail1=0;tail2=1;
    f[p]=true;
    q2[tail2]=p;
    int xx=p;
    while(din[p])
    {
        q1[++tail1]=din[p];
        p=din[p];
        f[p]=true;
    }
    p=xx;
    
    while(dout[p])
    {
        q2[++tail2]=dout[p];
        p=dout[p];
        f[p]=true;
    }
    for(int i=tail1;i>=1;i--)
        printf("%d ",q1[i]);
    for(int i=1;i<tail2;i++)
        printf("%d ",q2[i]);
    printf("%d\n",q2[tail2]);
}
void dinic()
{
    int d;
    while(makelevel())
        while(d=MAXflow(S,99999999))
            ans+=d;
    for(int i=1;i<=m*2;i+=2)
    {
        if(e[i].v<=0)
        {
            din[(e[i].y+1)/2]=(e[i].x+1)/2;
            dout[(e[i].x+1)/2]=(e[i].y+1)/2;
        }
    }
    for(int i=1;i<=n;i++)if(!f[i])work(i);
}
int main()
{
    scanf("%d%d",&n,&m);
    S=0;T=n*2+1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        insert(x*2-1,y*2);
    }
    for(int i=1;i<=n;i++)
    {
        insert(S,i*2-1);
        insert(i*2,T);
    }
    dinic();
    printf("%d\n",n-ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39759315/article/details/88849806
今日推荐