zoukankan      html  css  js  c++  java
  • P3254 圆桌问题

    P3254 圆桌问题

    题目描述

    假设有来自m 个不同单位的代表参加一次国际会议。每个单位的代表数分别为(ri (i =1,2,……,m))

    会议餐厅共有(n)张餐桌,每张餐桌可容纳(ci (i =1,2,……,n))个代表就餐。

    为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐。试设计一个算法,给出满足要求的代表就餐方案。

    对于给定的代表数和餐桌数以及餐桌容量,编程计算满足要求的代表就餐方案。


    典型的二分图匹配

    很显然,任何一个公司的人都可以随便坐。而一个公司的人不能有超过一个人在同一张桌子上。

    每个桌子和公司看做一个点,然后每每相连一条流量为一的边

    然后我们要所有人都坐上。就是要满流

    然后跑一边dinic就行了

    #include<cstdio> 
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using std::queue;
    using std::min;
    const int inf=0x7fffffff;
    const int maxn=10000;
    struct node
    {
    	int p;
    	int f;
    	int nxt;
    };
    node line[maxn<<3];
    int head[maxn],tail=-1;
    int cur[maxn];
    int dis[maxn];
    void add(int a,int b,int c)
    {
    	line[++tail].p=b;
    	line[tail].f=c;
    	line[tail].nxt=head[a];
    	head[a]=tail;
    }
    bool bfs(int begin,int end)
    {
    	memset(dis,0,sizeof(dis));
    	dis[begin]=1;
    	queue<int>q;
    	q.push(begin);
    	while(!q.empty())
    	{
    		int pas=q.front();q.pop();
    		for(int i=head[pas];i!=-1;i=line[i].nxt)
    			if(!dis[line[i].p]&&line[i].f)
    			{
    				dis[line[i].p]=dis[pas]+1;
    				q.push(line[i].p);
    			}
    	}
    	return dis[end];
    }
    int dfs(int now,int aim,int flow)
    {
    	if(now==aim||!flow)	return flow;
    	int res=0,f;
    	for(int &i=cur[now];i!=-1;i=line[i].nxt)
    		if(dis[line[i].p]==dis[now]+1&&(f=dfs(line[i].p,aim,min(flow,line[i].f))))
    		{
    			flow-=f;
    			res+=f;
    			line[i].f-=f;
    			line[i^1].f+=f;
    			if(!flow) break;
    		}
    	return res;
    } 
    int dinic(int begin,int end,int t)
    {
    	int res=0;
    	while(bfs(begin,end))
    	{
    		for(int i=0;i<=t;i++)
    			cur[i]=head[i];
    		res+=dfs(begin,end,inf);
    	}
    	return res;
    }
    int main()
    {
    	memset(head,-1,sizeof(head));
    	int n,m;
    	scanf("%d%d",&n,&m);
    	int a,tot=0;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a);
    		add(0,i,a);
    		add(i,0,0);
    		tot+=a;
    	}
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d",&a);
    		add(n+i,n+m+1,a);
    		add(n+m+1,n+i,0);
    	}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			add(i,n+j,1),add(n+j,i,0);
    	int judge=dinic(0,n+m+1,n+m+1);
    	if(judge!=tot)
    	{
    		printf("0");
    		return 0;
    	}
    	printf("1
    ");
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=head[i];j!=-1;j=line[j].nxt)
    			if(!line[j].f&&line[j].p)
    				printf("%d ",line[j].p-n);
    		printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    go反射实现实体映射
    golang的time包:秒、毫秒、纳秒时间戳输出
    在 Gin 框架中使用 JWT 认证
    docker安装redis
    docker安装mysql5.7
    Python Web实战:Python+Django+MySQL实现基于Web版的增删改查
    apache2.4配置weblogic12c集群(linux环境)
    小BUG大原理:重写WebMvcConfigurationSupport后SpringBoot自动配置失效
    Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析
    Git进阶:常用命令和问题案例整理
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9501789.html
Copyright © 2011-2022 走看看