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; }