網路流專題
阿新 • • 發佈:2022-03-23
很明顯的一道最大流匹配題目
唯一要注意的點是題目要求是一頭牛隻能搭配一個飲料和事物
所以要拆點
點選檢視程式碼
#include<bits/stdc++.h> using namespace std; #define lowbit(x) x&(-x) #define ll long long #define INF 0x7fffffff const int maxn=505; const int maxm=200000; int N,F,D,cnt,S,T; int head[maxm],num[maxn],maxflow; struct node{ int to,next,w; }edg[maxm]; void add(int u,int v,int w){ ++cnt; edg[cnt].to=v; edg[cnt].w=w; edg[cnt].next=head[u]; head[u]=cnt; } queue<int>Q; bool bfs(){ while(!Q.empty()){ Q.pop(); } for(int i=S;i<=T+N;i++)num[i]=-1; num[S]=1; Q.push(S); while(!Q.empty()){ int now=Q.front();Q.pop(); for(int i=head[now];i;i=edg[i].next){ int to=edg[i].to,w=edg[i].w; if(w&&num[to]==-1){ num[to]=num[now]+1; Q.push(to); } } } return (num[T]!=-1); } int dfs(int u,int f){ if(u==T){ return f; } int flow; for(int i=head[u];i;i=edg[i].next){ int to=edg[i].to,w=edg[i].w; if(w&&num[to]==num[u]+1&&(flow=dfs(to,min(f,w)))){ edg[i].w-=flow; edg[i^1].w+=flow; return flow; } } return 0; } void dinic(){ int minn; while(bfs()){ while(minn=dfs(S,INF)){ maxflow+=minn; } } } int main(){ scanf("%d%d%d",&N,&F,&D); cnt++; S=1,T=1+N+F+D+1; for(int i=1;i<=F;i++)add(S,i+1,1),add(i+1,S,0); for(int i=1;i<=D;i++)add(i+1+F+N,T,1),add(T,i+1+F+N,0); for(int i=1;i<=N;i++)add(1+F+i,1+F+N+D+1+i,1),add(1+F+N+D+i+1,1+F+i,0); for(int i=1;i<=N;i++){ int ff,dd; scanf("%d%d",&ff,&dd); for(int t,j=1;j<=ff;j++){ scanf("%d",&t); add(t+1,1+F+i,1); add(1+F+i,t+1,0); } for(int t,j=1;j<=dd;j++){ scanf("%d",&t); add(1+F+N+D+1+i,1+F+N+t,1); add(1+F+N+t,1+F+N+D+1+i,0); } } dinic(); printf("%d\n",maxflow); return 0; }