zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    POJ 1837 (DP)
    POJ 2255(分治递归)
    红球多于白球的概率(分治递归)
    HDOJ 4039 (Data_Structure)
    管道问题(prim)
    寻找给定区间内第K小的数(分治递归)
    大数加法
    1000元购物券 (分治递归)
    POJ 1308(并查集) (Data_Structure)
    我的2012年还不是世界末日
  • 原文地址:https://www.cnblogs.com/mybing/p/9050145.html
Copyright © 2011-2022 走看看