正解:网络流
解题报告:
一看就很网络流昂,,,于是现在的问题就变成怎么建图了$QwQ$
首先如果只有一个要求,那就直接按要求建图然后跑个最大流就好.
现在变成,有两个要求,必须同时满足,考虑怎么解决?
考虑拆点,把人拆成两个点,分别连食物和酒店,然后跑个最大流,做完了$QwQ$
$over$
#include<bits/stdc++.h> using namespace std; #define il inline #define lf double #define gc getchar() #define t(i) edge[i].to #define n(i) edge[i].nxt #define w(i) edge[i].wei #define ri register int #define rb register bool #define rc register char #define rp(i,x,y) for(ri i=x;i<=y;++i) #define my(i,x,y) for(ri i=x;i>=y;--i) #define e(i,x) for(ri i=head[x];~i;i=edge[i].nxt) const int N=100+5,M=N*20,inf=1e9; int head[M],ed_cnt=-1,n,p,q,S,T,cur[M],nod_cnt,dep[M]; struct ed{int to,nxt,wei;}edge[M<<1]; il int read() { ri x=0;rb y=1;rc ch=gc; while(ch!='-' && (ch>'9' || ch<'0'))ch=gc; if(ch=='-')ch=gc,y=0; while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc; return y?x:-x; } il void ad(ri x,ri y,ri z){edge[++ed_cnt]=(ed){x,head[y],z};head[y]=ed_cnt;edge[++ed_cnt]=(ed){y,head[x],0};head[x]=ed_cnt;} il bool bfs() { queue<int>Q;Q.push(S);memset(dep,0,sizeof(dep));dep[S]=1; while(!Q.empty()){ri nw=Q.front();Q.pop();e(i,nw)if(w(i) && !dep[t(i)])dep[t(i)]=dep[nw]+1,Q.push(t(i));} return dep[T]; } il int dfs(ri nw,ri flow) { if(nw==T || !flow)return flow;ri ret=0; for(ri &i=cur[nw];~i;i=n(i))if(w(i) && dep[t(i)]==dep[nw]+1){ri tmp=dfs(t(i),min(flow,w(i)));flow-=tmp,w(i)-=tmp,ret+=tmp,w(i^1)+=tmp;} return ret; } il int dinic(){ri ret=0;while(bfs()){rp(i,S,T)cur[i]=head[i];while(int d=dfs(S,inf))ret+=d;}return ret;} int main() { memset(head,-1,sizeof(head));n=read();p=read();q=read(); S=0;T=p+q+(n<<1)+1;rp(i,1,p)ad(i,S,1);rp(i,1,n)ad(i+p+n,i+p,1);rp(i,1,q)ad(T,i+p+(n<<1),1); rp(i,1,n)rp(j,1,p){ri tmp=read();if(tmp)ad(i+p,j,1);}rp(i,1,n)rp(j,1,q){ri tmp=read();if(tmp)ad(j+p+(n<<1),i+p+n,1);} printf("%d\n",dinic()); return 0; }