• 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;
    }
    
  • 相关阅读:
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark RDD(Resilient Distributed Datasets)论文
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    【机器学习实战】第10章 K-Means(K-均值)聚类算法
    [译]flexbox全揭秘
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9501789.html
Copyright © 2020-2023  润新知