#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#define clear(xxx) memset(xxx,0,sizeof(xxx))
using namespace std;
const int inf=1e9;
int dis[4005],cnt[4005],n,x,y,z,m;
int N;
int tot_edge=0;
struct line{
int from,to,remain,acc;
int fan;
};
line edge[2000005];
int last[2005],_next[1000005];
void add_edge(int x,int y,int c,int accom){
tot_edge++;
edge[tot_edge].from=x;
edge[tot_edge].to=y;
edge[tot_edge].acc=accom;
edge[tot_edge].remain=c;
_next[tot_edge]=last[x];
last[x]=tot_edge;
tot_edge++;
edge[tot_edge].from=y;
edge[tot_edge].to=x;
edge[tot_edge].acc=0;
edge[tot_edge].remain=0;
_next[tot_edge]=last[y];
last[y]=tot_edge;
edge[tot_edge].fan=tot_edge-1;
edge[tot_edge-1].fan=tot_edge;
}
int sap(int u,int flow){
int v,temp,delta=0;
if(u==N+2)return flow;
for(int h=last[u];h;h=_next[h]){
v=edge[h].to;
if(edge[h].remain&&dis[u]==dis[v]+1){
temp=sap(v,min(flow-delta,edge[h].remain));
edge[h].remain-=temp;
edge[edge[h].fan].remain+=temp;
delta+=temp;
if(delta==flow||dis[N+1]>=N+2)return delta;
}
}
if(dis[N+1]>N+2)return delta;
cnt[dis[u]]--;
if(cnt[dis[u]]==0)dis[N+1]=N+2;
dis[u]++;
cnt[dis[u]]++;
return delta;
}
int main(){
int tot=0,i,j,k,t=0,t3,t4;
cin>>n>>m;
N=n+m;
for(i=1;i<=n;i++){
add_edge(i+m,N+2,1,1);
int x;
while(scanf("%d",&x)!=EOF&&x!=0){
add_edge(x,m+i,1,1);
}
}
for(i=1;i<=m;i++)add_edge(N+1,i,1,1);
while(dis[N+1]<N+2){
t+=sap(N+1,inf);
}
cout<<t;
}
存边sap
最新推荐文章于 2025-02-27 16:17:26 发布