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

    题目描述

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

    会议餐厅共有n 张餐桌,每张餐桌可容纳ci(i=1,2,,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个方案。

    输入输出样例





    输入样例#1:
    4 5
    4 5 3 5
    3 5 2 6 4

    输出样例#1:
    1
    1 2 4 5
    1 2 3 4 5
    2 4 5
    1 2 3 4 5

    题解:每个单位的人与每一个桌子都建立一个容量为00的边,每单位与原点建立容量为单位人数的边,每个桌子都与汇点建立容量为桌子人数的边,最后查看边被减为00的,既代表有人坐。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define inf 0x3f3f3f3f3f3f3f3f
    #define ll long long
    #define MAXN 30000
    using namespace std;
    int n;//点数、边数
    int X[MAXN],y[MAXN];
    int sp,tp;//原点、汇点
    struct node
    {
        int v,next;
        ll cap;
    }mp[MAXN*10];
    int pre[MAXN],dis[MAXN],cur[MAXN];//cur为当前弧优化,dis存储分层图中每个点的层数(即到原点的最短距离),pre建邻接表
    int cnt=0;
    void init()//不要忘记初始化
    {
        cnt=0;
        memset(pre,-1,sizeof(pre));
    }
    void add(int u,int v,int w)//加边
    {
        mp[cnt].v=v;
        mp[cnt].cap=w;
        mp[cnt].next=pre[u];
        pre[u]=cnt++;
        mp[cnt].v=u;
        mp[cnt].cap=0;
        mp[cnt].next=pre[v];
        pre[v]=cnt++;
    }
    bool bfs()//建分层图
    {
        memset(dis,-1,sizeof(dis));
        queue<int>q;
        while(!q.empty())
            q.pop();
        q.push(sp);
        dis[sp]=0;
        int u,v;
        while(!q.empty())
        {
            u=q.front();
            q.pop();
            for(int i=pre[u];i!=-1;i=mp[i].next)
            {
                v=mp[i].v;
                if(dis[v]==-1&&mp[i].cap>0)
                {
                    dis[v]=dis[u]+1;
                    q.push(v);
                    if(v==tp)
                        break;
                }
            }
        }
        return dis[tp]!=-1;
    }
    ll dfs(int u,ll cap)//寻找增广路
    {
        if(u==tp||cap==0)
            return cap;
        ll res=0,f;
        for(int &i=cur[u];i!=-1;i=mp[i].next)
        {
            int v=mp[i].v;
            if(dis[v]==dis[u]+1&&(f=dfs(v,min(cap-res,mp[i].cap)))>0)
            {
                mp[i].cap-=f;
                mp[i^1].cap+=f;
                res+=f;
                if(res==cap)
                    return cap;
            }
        }
        if(!res)
            dis[u]=-1;
        return res;
    }
    ll dinic()
    {
        ll ans=0;
        while(bfs())
        {
            for(int i=0;i<=n;i++)
                cur[i]=pre[i];
            ans+=dfs(sp,inf);
        }
        return ans;
    }
    int main()
    {
        init();
        int a,b,sum=0;
        scanf("%d%d",&a,&b);
        for (int i = 1; i <=a ; ++i) {
            scanf("%d",&X[i]);
            sum+=X[i];
        }
        for (int i = 1; i <=b ; ++i) {
            scanf("%d",&y[i]);
        }
        for (int i = 1; i <=a ; ++i) {
            for (int j = 1; j <=b ; ++j) {
                add(i,a+j,1);
            }
            add(0,i,X[i]);
        }
        for (int j = 1; j <=b ; ++j) {
            add(a+j,a+b+1,y[j]);
        }
        n=a+b+1;
        sp=0;tp=a+b+1;
        int k=dinic();
     //   printf("%d
    ",k);
        if(k==sum) printf("1
    ");
        else {printf("0
    ");return 0;}
        for (int i = 1; i <=a; ++i) {
            for (int j = pre[i]; j !=-1 ; j=mp[j].next) {
                if(mp[j].cap ==0) printf("%d ",mp[j].v-a);
            }
            printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/-xiangyang/p/9220230.html
Copyright © 2011-2022 走看看