zoukankan      html  css  js  c++  java
  • POJ 3281 Dining(网络流最大匹配)

    分析

    数学模型是三个集合A,B,C,(a,b,c)构成一个匹配。因为图一个点只能匹配一次,把a拆点a',a",

    在可以匹配的点上连边,s - b - a' - a" - c - t,然后最大流就好了。

    /*********************************************************
    *            ------------------                          *
    *   author AbyssalFish                                   *
    **********************************************************/
    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    typedef long long ll;
    
    const int maxv = 402, maxe = 40600+2;
    int hd[maxv],to[maxe],nx[maxe],ec, cap[maxe];
    #define eachEage int i = hd[u]; i; i = nx[i]
    void add(int u,int v,int cp)
    {
        nx[++ec] = hd[u];
        to[ec] = v;
        cap[ec] = cp;
        hd[u] = ec;
    }
    void Add(int u,int v,int cp = 1)
    {
        add(u,v,cp);
        add(v,u,0);
    }
    
    int S,T;
    
    int lv[maxv];
    bool vis[maxv];
    int que[maxv];
    
    bool bfs()
    {
        memset(vis,0,sizeof(vis));
        int *q = que, l = 0, r = 0;
        lv[q[r++] = S] = 0; vis[S] = true;
        while(l<r){
            int u = q[l++];
            for(eachEage){
                int v = to[i];
                if(!vis[v] && cap[i]){
                    lv[v] = lv[u] + 1;
                    vis[v] = true;
                    q[r++] = v;
                }
            }
        }
        return vis[T];
    }
    
    int cur[maxv];
    
    int aug(int u,int a)
    {
        if(u == T || !a) return a;
        int flow = 0,f;
        for(int &i = cur[u]; i; i = nx[i]){
            int v = to[i];
            if(lv[v] == lv[u]+1 && (f = aug(v,min(a,cap[i])))){
                flow += f; a -= f;
                cap[i] -= f; cap[i^1] += f;
                if(!a) break;
            }
        }
        return flow;
    }
    
    int maxFlow()
    {
        int flow = 0;
        while(bfs()){
            memcpy(cur,hd,sizeof(int)*(T+1));
            flow += aug(S,1<<30);
        }
        return flow;
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        ec = 1;
        int N, F, D; scanf("%d%d%d",&N,&F,&D);
        int N2 = N*2, N2F = N2+F;
        S = 0; T = N2F+D+1;
        for(int i = 1; i <= N; i++){
            int Fi, Di, x; scanf("%d%d",&Fi,&Di);
            while(Fi--){
                scanf("%d", &x);
                Add(N2+x,i);
            }
            Add(i,N+i);
            while(Di--){
                scanf("%d", &x);
                Add(N+i,N2F+x);
            }
        }
        for(int i = 1; i <= F; i++) Add(S,N2+i);
        for(int i = 1; i <= D; i++) Add(N2F+i,T);
        printf("%d
    ", maxFlow());
        return 0;
    }
  • 相关阅读:
    English,The Da Vinci Code, Chapter 23
    python,meatobject
    English,The Da Vinci Code, Chapter 22
    English,The Da Vinci Code, Chapter 21
    English,The Da Vinci Code, Chapter 20
    English,The Da Vinci Code, Chapter 19
    python,xml,ELement Tree
    English,The Da Vinci Code, Chapter 18
    English,The Da Vinci Code, Chapter 17
    English,The Da Vinci Code, Chapter 16
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4947539.html
Copyright © 2011-2022 走看看