• 网络流24题之圆桌问题


    P3254 圆桌问题 

    题目描述

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

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

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

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

    输入格式:

    第1 行有2 个正整数m 和n,m 表示单位数,n 表示餐桌数,1<=m<=150, 1<=n<=270。

    第2 行有m 个正整数,分别表示每个单位的代表数。

    第3 行有n 个正整数,分别表示每个餐桌的容量。

    输出格式:

    如果问题有解,第1 行输出1,否则输出0。接下来的m 行给出每个单位代表的就餐桌号。如果有多个满足要求的方案,只要输出1 个方案。

    样例输入:

    4 5
    4 5 3 5
    3 5 2 6 4

    样例输出:

    1
    1 2 4 5
    1 2 3 4 5
    2 4 5
    1 2 3 4 5

    本题可以用贪心求解。

    首先将桌子从大到小排个序,再讲单位的规模从大到小排个序。单位规模越大就越难满足,所以我们优先考虑单位。

    之后先坐大桌子,再坐小桌子就OK了。

    但是此题我写的网络流

    模型很简单,二分图最大匹配,桌子和单位匹配一下。

    建立二分图,每个单位为X集合中的顶点,每个餐桌为Y集合中的顶点,增设附加源S和汇T。

    1、从S向每个Xi顶点连接一条容量为该单位人数的有向边。
    2、从每个Yi顶点向T连接一条容量为该餐桌容量的有向边。
    3、X集合中每个顶点向Y集合中每个顶点连接一条容量为1的有向边。

    之后跑最大流。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define N 4000000
    int n,m;
    int a[N];
    int b[N];
    int nex[N];
    int head[N];
    int to[N];
    int val[N];
    int dep[N];
    int S,T;
    int idx=1;
    void addedge(int a,int b,int c)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
    }
    bool bfs(int S,int T)
    {
        memset(dep,-1,sizeof(dep));
        queue <int > q;
        q.push(S);
        dep[S]=0;
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=head[x];i;i=nex[i])
            {
                if(val[i]&&dep[to[i]]==-1)
                {
                    dep[to[i]]=dep[x]+1;
                    q.push(to[i]);
                    if(to[i]==T)
                        return 1;
                }
            }
        }
        return 0;
    }
    int dinic(int x,int flow)
    {
        int nowflow=flow;
        if(x==T)
            return nowflow;
        for(int i=head[x];i;i=nex[i])
        {
            if(val[i]>0&&dep[to[i]]==dep[x]+1)
            {
                int now=dinic(to[i],min(nowflow,val[i]));
                if(now==0)
                    dep[to[i]]=-1;
                nowflow-=now;
                val[i]-=now;
                val[i^1]+=now;
                if(nowflow==0)
                    break;
            }
        }
        return flow-nowflow;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        S=0;
        T=n+m+1;
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
            addedge(S,i,a[i]);
            addedge(i,S,0);
        }
        for(int i=n+1;i<=m+n;i++)
        {	
            scanf("%d",&b[i]);
            addedge(i,T,b[i]);
            addedge(T,i,0);
        }
        for(int i=1;i<=n;i++)
            for(int j=n+1;j<=m+n;j++)
            {
                addedge(i,j,1);
                addedge(j,i,0);
            }
        int ans=0;
        while(bfs(S,T))
            ans+=dinic(S,1<<30);
        if(ans==0||ans<sum)
            printf("0");
        else
        {
            puts("1");
            for(int i=1;i<=n;i++)
            {
                for(int j=head[i];j;j=nex[j])
                {
                    if(to[j]!=S&&(!val[j]))
                        printf("%d ",to[j]-n);
                }
                puts("");
            }
        }
    }
  • 相关阅读:
    C winpcap 网络抓包 并获取IP TCP 协议的相关信息
    python基础
    k8s部署测试实例
    node节点的部署
    k8s集群之master节点部署
    k8s集群之Docker安装镜像加速器配置与k8s容器网络
    k8s集群部署之环境介绍与etcd数据库集群部署
    docker存储管理
    docker 镜像仓库的安装与使用
    docker 镜像管理
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/9813762.html
Copyright © 2020-2023  润新知