[cogs729] [网络流24题#5] 圆桌聚餐 [网络流,最大流,多重二分图匹配]

建图:从源点向单位连边,边权为单位人数,从单位向圆桌连边,边权为1,从圆桌向汇点连边,边权为圆桌容量。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>

using namespace std;

template<const int _n>
struct Edge
{
    struct Edge_base { int    to,w,next; }e[_n];
    int    cnt,p[_n];
    Edge() { clear(); }
    void    clear() { cnt=1,memset(p,0,sizeof(p)); }
    int    start(const int x) { return p[x]; }
    Edge_base&    operator[](const int x) { return e[x]; }
    void    insert(const int x,const int y,const int z)
    { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; }
};

int    n,m,SSS,TTT;
int    level[510],cur[510];
Edge<110000>    e;

bool    Bfs(const int S)
{
    int    i,t;
    queue<int>    Q;
    memset(level,0,sizeof(int)*(n+m+3));
    level[S]=1;
    Q.push(S);
    while(!Q.empty())
    {
        t=Q.front(),Q.pop();
        for(i=e.start(t);i;i=e[i].next)
        {
            if(!level[e[i].to] && e[i].w)
            {
                level[e[i].to]=level[t]+1;
                Q.push(e[i].to);
            }
        }
    }
    return level[TTT];
}

int    Dfs(const int S,const int bk)
{
    if(S==TTT)return bk;
    int    rest=bk;
    for(int &i=cur[S];i;i=e[i].next)
    {
        if(level[e[i].to]==level[S]+1 && e[i].w)
        {
            int    flow=Dfs(e[i].to,min(rest,e[i].w));
            e[i].w-=flow;
            e[i^1].w+=flow;
            if((rest-=flow)<=0)break;
        }
    }
    if(rest==bk)level[S]=0;
    return bk-rest;
}

int    Dinic()
{
    int    flow=0;
    while(Bfs(SSS))
    {
        memcpy(cur,e.p,sizeof(int)*(n+m+3));
        flow+=Dfs(SSS,0x3f3f3f3f);
    }
    return flow;
}

int main()
{
    freopen("roundtable.in","r",stdin);
    freopen("roundtable.out","w",stdout);
    int    i,j,w,c,Sum=0;
    
    scanf("%d%d",&n,&m);
    SSS=n+m+1;TTT=SSS+1;
    for(i=1;i<=n;++i)
    {
        scanf("%d",&w);
        e.insert(SSS,i,w);
        e.insert(i,SSS,0);
        for(j=1;j<=m;++j)
        {
            e.insert(i,j+n,1);
            e.insert(j+n,i,0);
        }
        Sum+=w;
    }
    for(i=1;i<=m;++i)
    {
        scanf("%d",&c);
        e.insert(i+n,TTT,c);
        e.insert(TTT,i+n,0);
    }

    printf("%d\n",Dinic()==Sum?1:0);
    
    stack<int>    St;
    for(int t=1;t<=n;++t)
    {
        for(i=e.start(t);i;i=e[i].next)
        {
            if(e[i].to==SSS)continue;
            if(e[i].w==0)St.push(e[i].to-n);
        }
        while(!St.empty())printf("%d ",St.top()),St.pop();
        printf("\n");
    }

    return 0;
}

 

posted @ 2015-11-26 10:44  Gster  阅读(150)  评论(0编辑  收藏  举报