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;
    }
  • 相关阅读:
    iframe
    daterangepicker 时间区间选择
    刷新父窗口
    echars
    原生http请求封装
    css布局方式总结
    js获取http请求响应头信息
    js事件循环机制 (Event Loop)
    http协议的状态码
    javaScript函数节流与函数防抖
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4947539.html
Copyright © 2011-2022 走看看