zoukankan      html  css  js  c++  java
  • [luogu]P1402:酒店之王

    原题链接

    酒店之王

    分析

    先大致讲一下题意:
    题目给定p道菜,q个房间和n个客人。
    每个客人满意的条件当且仅当那个客人分配到的房间和菜都是自己喜欢的。

    想都不想直接网络流,裸题。(但是因为没看清题意一开始疯狂30分)

    模型:

    • 把每道菜,每个客人,每个房间看成点,有喜欢关系的就连有向边,容量为1。
    • 超级源向每一个菜,每个房间向超级汇连有向边,容量为1。
    • 客人拆点,入点向出点连一条容量为1的边。

    这样子只要跑一边网络流求出最大流就行了。。(感觉没有紫题难度)

    代码

    
    #include <bits/stdc++.h>
    using namespace std;
    const int inf=1<<31-1;
    queue <int> q;
    int n,p,w,s=0,t;
    int rm[109][109],tmp[109],d[529],flow,maxflow;
    int head[529],ver[300009],next[300009],edge[300009],tot=1;
    void add(int x,int y){
    	ver[++tot]=y;edge[tot]=1;next[tot]=head[x];head[x]=tot;
    	ver[++tot]=x;edge[tot]=0;next[tot]=head[y];head[y]=tot;
    }
    bool bfs();
    int dinic(int x,int flow);
    int main()
    {
    	int tt;
    	scanf("%d%d%d",&n,&p,&w);
    	t=p+2*n+w+1;
        for(int i=1;i<=p;i++)add(s,i);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=p;j++){
                scanf("%d",&tt);
    			if(tt)add(j,i+p);
            }
        for(int i=1;i<=n;i++)add(i+p,i+p+n);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=w;j++){
                scanf("%d",&tt);
    			if(tt)add(p+n+i,p+2*n+j);
            }
        }
        for(int i=1;i<=w;i++)add(p+2*n+i,t);
    	while(bfs())
    		while(flow=dinic(s,inf))maxflow+=flow;
    	cout<<maxflow<<endl;
    	return 0;
    }
    bool bfs(){
    	memset(d,0,sizeof(d));
    	while(q.size())q.pop();
    	q.push(s);d[s]=1;
    	while(q.size()){
    		int x=q.front();q.pop();
    		for(int i=head[x];i;i=next[i]){
    			if(!d[ver[i]] && edge[i]){
                    d[ver[i]]=d[x]+1;
                    q.push(ver[i]);
                    if(ver[i]==t)return true;
    			}
    		}
    	}
    	return false;
    }
    int dinic(int x,int flow){
    	if(x==t)return flow;
    	int res=flow,k;
    	for(int i=head[x];i&&res;i=next[i]){
    		if(edge[i] && d[ver[i]]==d[x]+1){
    			k=dinic(ver[i],min(flow,edge[i]));
    			if(!k)d[ver[i]]=0;
    			edge[i]-=k;
    			edge[i^1]+=k;
    			res-=k;
    		}
    	}
    	return flow-res;
    }
    
  • 相关阅读:
    RedHat Linux-配置YUM仓库
    04、管道符、重定向与环境变量
    03、新手必须掌握的Linux命令
    size_t
    decltype关键字
    python numpy使用笔记
    Huffman编码
    动态规划(dynamic programming)
    Prim算法
    Kruskal算法
  • 原文地址:https://www.cnblogs.com/onglublog/p/9859755.html
Copyright © 2011-2022 走看看