如题,一眼看上去是这样的。
如果只看人和房间,或者只看人和菜,那么这题就是一个sb的二分图最大匹配,随便跑就好了。
那么怎么同时满足呢?
两个图都建,然后两个图的人向自己连一条长度=1的边,用来限制流量防止这个人精分
#include<bits/stdc++.h> #define inf 10000010 #define N 1101 using namespace std; int s,t,n,m,q,p,ans,d; struct Edge{int u,v,next,f;}G[1010000]; int tot=0,head[N<<2]; inline void addedge(int u,int v,int f){ G[tot].u=u;G[tot].v=v;G[tot].f=f;G[tot].next=head[u];head[u]=tot++; G[tot].u=v;G[tot].v=u;G[tot].f=0;G[tot].next=head[v];head[v]=tot++; } int level[N<<2]; inline bool bfs(int s,int t){ memset(level,0,sizeof(level)); queue<int>q;q.push(s);level[s]=1; while(!q.empty()){//puts("!!!"); int u=q.front();q.pop(); if(u==t)return 1; for(int i=head[u];~i;i=G[i].next){ int v=G[i].v,f=G[i].f; if(f&&!level[v])level[v]=level[u]+1,q.push(v); } } return 0; } int dfs(int u,int maxf,int t){ if(u==t)return maxf;int rat=0; for(int i=head[u];~i&&rat<maxf;i=G[i].next){ int v=G[i].v,f=G[i].f; if(f&&level[v]==level[u]+1){ f=dfs(v,min(maxf-rat,f),t); rat+=f;G[i].f-=f;G[i^1].f+=f; } } if(!rat)level[u]=inf; return rat; } inline int dinic(int s,int t){ int ans=0; while(bfs(s,t))ans+=dfs(s,inf,t); return ans; } inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ n=read();p=read();q=read(); memset(head,-1,sizeof(head));s=0;t=n+n+p+q+1; for(int i=1;i<=n;i++){ addedge(i+p,i+p+n,1); for(int j=1;j<=p;j++){ if(i==1)addedge(0,j,1); int u=read(); if(u)addedge(j,i+p,1); } } for(int i=1;i<=n;i++){ for(int j=1;j<=q;j++){ if(i==1)addedge(j+p+n+n,t,1); int u=read(); if(u)addedge(i+p+n,j+p+n+n,1); } } int ans=dinic(s,t); printf("%d ",ans); return 0; }