• LuoguP3254 圆桌问题(最大流)


    题目描述

    假设有来自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 个方案。

    解题思路:

    建立源点汇点。

    源点向公司连边流量为公司人数。

    公司向餐桌连边流量为$1$

    餐桌向汇点连边流量为就餐人数上限。

    最大流跑一下就好了。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 const int oo=0x3f3f3f3f;
      5 namespace stb{
      6     template<class tnt>
      7     class queue{
      8         #define INF 1000000
      9         public:
     10             queue(){h=1;t=0;}
     11             int nxt(int x){if(x+1==INF)return 1;return x+1;}
     12             void clear(void){h=1;t=0;}
     13             void push(tnt x){t=nxt(t);l[t]=x;}
     14             void pop(void){h=nxt(h);}
     15             tnt front(void){return l[h];}
     16             bool empty(void){return nxt(t)==h;}
     17         private:
     18             tnt l[INF];
     19             int h,t;
     20         #undef INF
     21     };
     22 };
     23 struct pnt{
     24     int hd;
     25     int lyr;
     26     int now;
     27 }p[10000];
     28 struct ent{
     29     int twd;
     30     int lst;
     31     int vls;
     32 }e[100000];
     33 int cnt;
     34 int n,m;
     35 int s,t;
     36 int N;
     37 stb::queue<int>Q;
     38 void ade(int f,int t,int v)
     39 {
     40     cnt++;
     41     e[cnt].twd=t;
     42     e[cnt].vls=v;
     43     e[cnt].lst=p[f].hd;
     44     p[f].hd=cnt;
     45     return ;
     46 }
     47 bool Bfs(void)
     48 {
     49     Q.clear();
     50     for(int i=1;i<=N;i++)
     51         p[i].lyr=0;
     52     p[s].lyr=1;
     53     Q.push(s);
     54     while(!Q.empty())
     55     {
     56         int x=Q.front();
     57         Q.pop();
     58         for(int i=p[x].hd;i;i=e[i].lst)
     59         {
     60             int to=e[i].twd;
     61             if(p[to].lyr==0&&e[i].vls>0)
     62             {
     63                 p[to].lyr=p[x].lyr+1;
     64                 if(to==t)
     65                     return true;
     66                 Q.push(to);
     67             }
     68         }
     69     }
     70     return false;
     71 }
     72 int Dfs(int x,int fll)
     73 {
     74     if(x==t)
     75         return fll;
     76     for(int& i=p[x].now;i;i=e[i].lst)
     77     {
     78         int to=e[i].twd;
     79         if(p[to].lyr==p[x].lyr+1&&e[i].vls>0)
     80         {
     81             int ans=Dfs(to,std::min(fll,e[i].vls));
     82             if(ans>0)
     83             {
     84                 e[i].vls-=ans;
     85                 e[((i-1)^1)+1].vls+=ans;
     86                 return ans;
     87             }
     88         }
     89     }
     90     return 0;
     91 }
     92 int Dinic(void)
     93 {
     94     int ans=0;
     95     while(Bfs())
     96     {
     97         for(int i=1;i<=N;i++)
     98             p[i].now=p[i].hd;
     99         int dlt;
    100         while(dlt=Dfs(s,oo))
    101             ans+=dlt;
    102     }
    103     return ans;
    104 }
    105 int main()
    106 {
    107     scanf("%d%d",&n,&m);
    108     s=n+m+1;
    109     t=s+1;
    110     N=t;
    111     int sum=0;
    112     for(int i=1;i<=n;i++)
    113     {
    114         int v;
    115         scanf("%d",&v);
    116         sum+=v;
    117         ade(s,i,v);
    118         ade(i,s,0);
    119         for(int j=m;j;j--)
    120         {
    121             ade(i,j+n,1);
    122             ade(j+n,i,0);
    123         }
    124     }
    125     for(int i=1;i<=m;i++)
    126     {
    127         int v;
    128         scanf("%d",&v);
    129         ade(i+n,t,v);
    130         ade(t,i+n,v);
    131     }
    132     if(Dinic()!=sum)
    133     {
    134         printf("%d
    ",0);
    135         return 0;
    136     }
    137     printf("%d
    ",1);
    138     for(int i=1;i<=n;i++)
    139     {
    140         for(int j=p[i].hd;j;j=e[j].lst)
    141         {
    142             int to=e[j].twd;
    143             if(to>n&&e[j].vls==0)
    144                 printf("%d ",to-n);
    145         }
    146         puts("");
    147     }
    148     return 0;
    149 }

     

  • 相关阅读:
    LoadRunner支持的IE版本
    构建10亿级PV的大型网站设计要点 网络层
    珠海金山软件急聘性能测试工程师【内部推荐】
    PrefTest性能测试解决方案 C/S结构应用系统的压力测试
    Android性能测试主要方法
    使用LoadRunner监控Apach服务器的步骤
    MySQL+HandlerSocket
    Android configChanges属性
    创业故事:腾讯的创始人们
    [置顶] 学习linux的几点忠告
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10205395.html
Copyright © 2020-2023  润新知