【luogu1402】酒店之王(网络流)

来源:互联网 发布:历史湿度数据查询 编辑:程序博客网 时间:2024/05/01 17:58

题目:

我是超链接

题解:

就是一个网络流(一开始搜二分图匹配的orz)

建图就是S->Room->P->P->Dish->T

容量都是1,人拆点是因为一个人只能使用一次

以后还要考虑的周密一些

代码:

#include <cstdio>#include <queue>#include <iostream>#include <cstring>#define N 105#define INF 1e9+7using namespace std;int tot=-1,nxt[N*N*2],point[N*N*2],v[N*N*2],remind[N*N*2];int cur[N*N*2],deep[N*N*2],s,t,n,p,q;bool c[N][N+N];void addline(int x,int y,int z){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; remind[tot]=z;++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; remind[tot]=0;} int dfs(int now,int t,int limit){int flow=0,f;if (now==t || !limit) return limit;for (int i=cur[now];i!=-1;i=nxt[i]){cur[now]=i;if (deep[v[i]]==deep[now]+1 && (f=dfs(v[i],t,min(limit,remind[i])))){flow+=f;limit-=f;remind[i]-=f;remind[i^1]+=f;if (!limit) break;}}return flow;}bool bfs(int s,int t){queue <int> q;for (int i=s;i<=t;i++) cur[i]=point[i];q.push(s);memset(deep,0x7f,sizeof(deep));deep[s]=0;while (!q.empty()){int now=q.front(); q.pop();for(int i=point[now];i!=-1;i=nxt[i])  if (deep[v[i]]>INF && remind[i])  {  deep[v[i]]=deep[now]+1;  q.push(v[i]);  }}if(deep[t]>INF) return false;return true;}void dinic(int s,int t){int ans=0;while (bfs(s,t))  ans+=dfs(s,t,INF);printf("%d",ans);}int main(){int i,j,k;int a;memset(nxt,-1,sizeof(nxt));memset(point,-1,sizeof(point));scanf("%d%d%d",&n,&p,&q);s=0;t=p+q+1+2*n;for (i=1;i<=p;i++)  addline(s,i,1);for (i=1;i<=q;i++)  addline(i+p+n*2,t,1);for (i=1;i<=n;i++)  for (j=1;j<=p;j++)  {  scanf("%d",&a);  if (a) addline(j,p+i,1);  }for (i=1;i<=n;i++)  for (j=1;j<=q;j++)    {  scanf("%d",&a);  if (a) addline(p+i+n,p+n*2+j,1);  }for (i=1;i<=n;i++)  addline(i+p,i+p+n,1);dinic(s,t);}