luogu P2764 最小路径覆盖问题

DAG的最小不相交路径覆盖板子

#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
",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-ans);
	return 0;
}

  

原文地址:https://www.cnblogs.com/mybing/p/9050145.html