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

    题解:源点向单位建容量为单位人数的边,桌子向汇点建容量为桌子最多容纳多少人的边,单位向所有桌子连容量为1的边,跑最大流。

    如果最大流等于单位总人数则有解,输出满流边即为方案。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=450,M=(150*270+N)*2,inf=1e9;
     4 int h[N],e[M],ne[M],f[M],idx;
     5 int cur[N],d[N];
     6 int n,m,S,T;
     7 void add(int a,int b,int c)
     8 {
     9     ne[idx]=h[a],e[idx]=b,f[idx]=c,h[a]=idx++;
    10     ne[idx]=h[b],e[idx]=a,f[idx]=0,h[b]=idx++;
    11 }
    12 bool bfs()
    13 {
    14     memset(d,-1,sizeof d);
    15     queue<int>q;
    16     d[S]=0;
    17     q.push(S);
    18     cur[S]=h[S];
    19     while(q.size())
    20     {
    21         int t=q.front();
    22         q.pop();
    23         for(int i=h[t];i!=-1;i=ne[i])
    24         {
    25             int j=e[i];
    26             if(d[j]==-1&&f[i])
    27             {
    28                 d[j]=d[t]+1;
    29                 cur[j]=h[j];
    30                 if(j==T)return true;
    31                 q.push(j);
    32             }
    33         }
    34     }
    35     return false;
    36 }
    37 int find(int u,int limit)
    38 {
    39     if(u==T)return limit;
    40     int flow=0;
    41     for(int i=cur[u];i!=-1&&flow<limit;i=ne[i])
    42     {
    43         int j=e[i];
    44         cur[u]=i;
    45         if(d[j]==d[u]+1&&f[i])
    46         {
    47             int t=find(j,min(f[i],limit-flow));
    48             if(!t)d[j]=-1;
    49             f[i]-=t,f[i^1]+=t,flow+=t;
    50         }
    51     }
    52     return flow;
    53 }
    54 int dinic()
    55 {
    56     int r=0,flow;
    57     while(bfs())while(flow=find(S,inf))r+=flow;
    58     return r;
    59 }
    60 int main()
    61 {
    62     memset(h,-1,sizeof h);
    63     cin>>m>>n;
    64     S=0,T=N-1;
    65     int tot=0;
    66     for(int i=1;i<=m;i++)
    67     {
    68         int x;
    69         scanf("%d",&x);
    70         add(S,i,x);
    71         tot+=x;
    72     }
    73     for(int i=1;i<=n;i++)
    74     {
    75         int x;
    76         scanf("%d",&x);
    77         add(m+i,T,x);
    78     }
    79     for(int i=1;i<=m;i++)
    80     for(int j=1;j<=n;j++)
    81     add(i,m+j,1);
    82     if(tot!=dinic())puts("0");
    83     else
    84     {
    85         puts("1");
    86         for(int i=1;i<=m;i++)
    87         {
    88         for(int j=h[i];j!=-1;j=ne[j])
    89         {
    90             int b=e[j];
    91             if(b>=m+1&&b<=n+m&&!f[j])
    92             printf("%d ",b-m);
    93         }
    94         printf("
    ");
    95         }
    96     }
    97 }
  • 相关阅读:
    HttpWebRequest 的一个 异步封装
    AcWing 6 多重背包问题III【单调对列优化】
    AcWing 8. 二维费用的背包问题
    AcWing 1019. 庆功会
    P1421 小玉买文具
    P5709 【深基2.习6】Apples Prologue / 苹果和虫子
    P2181 对角线
    AcWing 1020. 潜水员
    AcWing 1013. 机器分配【分组背包+求方案数】
    AcWing 7. 混合背包问题
  • 原文地址:https://www.cnblogs.com/flyljz/p/13674040.html
Copyright © 2011-2022 走看看