zoukankan      html  css  js  c++  java
  • LibreOJ 6004 圆桌聚餐 (最大流)

    题解:天啊,这道最大流真是水的一批……只需要每张桌子向每个单位建一条容量为1的边,源点向桌子建边,容量为桌子能坐的人数;单位向汇点建边,容量为单位人数即可,然后根据单位与桌子的连边值是否为一来了解每个单位配对的桌子即可

    代码如下:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int head[100010],next[100010],w[100010],v[100010],deep[100010],cur[100010];
    int n,m,s,t,cnt;
    
    int init()
    {
        cnt=-1;
        memset(head,-1,sizeof(head));
        memset(next,-1,sizeof(next));
    }
    
    void add(int from,int to,int cost)
    {
        cnt++;
        next[cnt]=head[from];
        w[cnt]=cost;
        v[cnt]=to;
        head[from]=cnt;
    } 
    
    void add_edge(int from,int to,int cost)
    {
        add(from,to,cost);
        add(to,from,0);
    }
    
    int bfs(int s,int t)
    {
        queue<int> q;
        memset(deep,0,sizeof(deep));
        deep[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i!=-1;i=next[i])
            {
                if(w[i]>0&&!(deep[v[i]]))
                {
                    deep[v[i]]=deep[u]+1;
                    q.push(v[i]);
                }
            }
        }
        if(!deep[t])
        {
            return 0;
        }
        return 1;
    }
    
    int dfs(int u,int t,int dist)
    {
        if(u==t)
        {
            return dist;
        }
        for(int &i=cur[u];i!=-1;i=next[i])
        {
            if(deep[v[i]]==deep[u]+1&&w[i]!=0)
            {
                int di=dfs(v[i],t,min(dist,w[i]));
                if(di>0)
                {
                    w[i]-=di;
                    w[i^1]+=di;
                    return di;
                }
            }
        }
        return 0;
    }
    
    int dinic(int s,int t)
    {
        int res=0;
        while(bfs(s,t))
        {
            for(int i=s;i<=t;i++)
            {
                cur[i]=head[i];
            }
            while(int di=dfs(s,t,inf))
            {
                res+=di;
            }
        }
        return res;
    }
    
    int main()
    {
        int a[1000],b[1000],sum=0;
        vector<int> g[1000];
        scanf("%d%d",&m,&n);
        init();
        s=0;t=n+m+1;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&a[i]);
            add_edge(i+n,t,a[i]);
            sum+=a[i];
    
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&b[i]);
            add_edge(s,i,b[i]);        
            for(int j=1;j<=m;j++)
            {
                add_edge(i,j+n,1);
            }
        }
        int ans=dinic(s,t);
        if(ans==sum)
        {
            puts("1");
        }
        else
        {
            puts("0");
            return 0;
        }
        for(int i=head[t];i!=-1;i=next[i])
        {
            for(int j=head[v[i]];j!=-1;j=next[j])
            {
                if(w[j]&&v[j]!=t)
                {
                    g[v[i]-n].push_back(v[j]);
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<g[i].size();j++)
            {
                printf("%d ",g[i][j]);
            }
            printf("
    ");
        }
    }
  • 相关阅读:
    explicit
    boolalpha 和 noboolalpha
    C++ 头文件一览
    C++ I/O库总结
    Error:collect2:ld returned 1 exit status (总结)
    常用目录的作用
    硬盘分区与硬软链接
    POJ3694 Network(Tarjan双联通分图 LCA 桥)
    2016"百度之星"
    2016"百度之星"
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8584489.html
Copyright © 2011-2022 走看看