• UVA-10779 Collectors Problem (网络流建模)


    题目大意:有n个人,已知每人有ki个糖纸,并且知道每张糖纸的颜色。其中,Bob希望能和同伴交换使得手上的糖纸数尽量多。他的同伴只会用手上的重复的交换手上没有的,并且他的同伴们之间不会产生交换。求出Bob能拥有的最大糖纸种数。

    题目分析:对于Bob拥有的糖纸,从源点s连一条弧,容量为Bob拥有的数量;对于Bob的小伙伴,从Bob连一条弧向他拥有的糖纸,容量为拥有数量减1,对于他不拥有的糖纸,连一条有向弧从糖纸到他,容量为1;对于每一种糖纸,连一条弧向汇点t。最大流便是答案。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<string>
    # include<vector>
    # include<list>
    # include<set>
    # include<map>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    # define LL long long
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a))
    # define CLL(a,b,n) fill(a,a+n,b)
    
    const double inf=1e30;
    const int INF=1<<30;
    const int N=80;
    
    struct Edge
    {
        int fr,to,cap,fw;
        Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){}
    };
    vector<Edge>edges;
    vector<int>G[N];
    int vis[N],d[N],cur[N],s,t,n,m,mark[30];
    
    void init()
    {
        s=0,t=n+m+1;
        edges.clear();
        REP(i,0,t+1) G[i].clear();
    }
    
    void addEdge(int u,int v,int cap)
    {
        edges.push_back(Edge(u,v,cap,0));
        edges.push_back(Edge(v,u,0,0));
        int len=edges.size();
        G[u].push_back(len-2);
        G[v].push_back(len-1);
    }
    
    bool BFS()
    {
        queue<int>q;
        CL(vis,0);
        d[s]=0;
        vis[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            REP(i,0,G[x].size()){
                Edge &e=edges[G[x][i]];
                if(!vis[e.to]&&e.cap>e.fw){
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    
    int DFS(int x,int a)
    {
        if(x==t||a==0) return a;
        int flow=0,f;
        for(int &i=cur[x];i<G[x].size();++i){
            Edge &e=edges[G[x][i]];
            if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.fw)))>0){
                e.fw+=f;
                edges[G[x][i]^1].fw-=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }
    
    int Dinic()
    {
        int flow=0;
        while(BFS()){
            CL(cur,0);
            flow+=DFS(s,INF);
        }
        return flow;
    }
    
    int main()
    {
        int T,k,r,cas=0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            init();
            CL(mark,0);
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&r);
                ++mark[r];
            }
            REP(i,1,m+1) if(mark[i]) addEdge(s,i,mark[i]);
            REP(i,1,n){
                CL(mark,0);
                scanf("%d",&k);
                while(k--){
                    scanf("%d",&r);
                    ++mark[r];
                }
                REP(j,1,m+1){
                    if(mark[j]>=2) addEdge(m+i+1,j,mark[j]-1);
                    else if(mark[j]==0) addEdge(j,m+i+1,1);
                }
            }
            REP(i,1,m+1) addEdge(i,t,1);
            printf("Case #%d: %d
    ",++cas,Dinic());
        }
      return 0;
    }
    

      

  • 相关阅读:
    2017.10.04
    2017.10.03
    Luogu P3110 [USACO14DEC]驮运Piggy Back
    Luogu P2176 [USACO14FEB]路障Roadblock
    Luogu P3797 妖梦斩木棒
    数列分块入门1-9 By hzwer
    CodeForces 【20C】Dijkstra?
    Luogu P2835 刻录光盘
    Luogu P1692 部落卫队
    Luogu P2847 [USACO20DEC]Moocast(gold)奶牛广播-金
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5033233.html
Copyright © 2020-2023  润新知