zoukankan      html  css  js  c++  java
  • [Cogs14] [网络流24题#1] 飞行员分配方案 [网络流,最大流,二分图匹配]

    经典二分图匹配,可以用匈牙利算法,也可以用最大流

    代码如下(Dinic):

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    template<const int _n>
    struct Edge
    {
        struct Edge_base { int    to,next,w; }e[_n]; int    p[_n],cnt;
        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    start(const int    x) { return p[x]; }
        void    clear() { cnt=1;memset(p,0,sizeof(p)); }
        Edge_base&    operator[](const int x) { return e[x]; }
    };
    
    int    n,m,flow,SSS,TTT;
    int    level[110],From[110],From_e[110];
    Edge<310>    e;
    
    bool    Bfs(const int S)
    {
        int    i,t;
        queue<int>    Q;
        memset(level,0,sizeof(level));
        memset(From,0,sizeof(From));
        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);
                    From[e[i].to]=t;
                    From_e[e[i].to]=i;
                    if(e[i].to==TTT)goto End;
                }
            }
        }
    End:
        if(!level[TTT])return false;
        flow++;
        for(i=TTT;i!=SSS;i=From[i])e[From_e[i]].w--,e[From_e[i]^1].w++;
        return true;
    }
    
    int    Dinic()
    {
        while(Bfs(SSS));
        return flow;
    }
    
    int main()
    {
        freopen("flyer.in","r",stdin);
        freopen("flyer.out","w",stdout);
    
        int    i,x,y;
    
        scanf("%d%d",&m,&n);
        m=m-n;
        while(scanf("%d%d",&x,&y)==2)
        {
            if(x>y)swap(x,y);
            e.insert(x,y,1);
            e.insert(y,x,0);
        }
        
        SSS=n+m+1,TTT=n+m+2;
        for(i=1;i<=n;++i)
        {
            e.insert(SSS,i,1);
            e.insert(i,SSS,0);
        }
        for(i=n+1;i<=m+n;++i)
        {
            e.insert(i,TTT,1);
            e.insert(TTT,i,0);
        }
    
        printf("%d
    ",Dinic());
    
        return 0;
    }

    匈牙利代码:http://www.cnblogs.com/Ngshily/p/4988909.html

  • 相关阅读:
    golang 数据结构 优先队列(堆)
    leetcode刷题笔记5210题 球会落何处
    leetcode刷题笔记5638题 吃苹果的最大数目
    leetcode刷题笔记5637题 判断字符串的两半是否相似
    剑指 Offer 28. 对称的二叉树
    剑指 Offer 27. 二叉树的镜像
    剑指 Offer 26. 树的子结构
    剑指 Offer 25. 合并两个排序的链表
    剑指 Offer 24. 反转链表
    剑指 Offer 22. 链表中倒数第k个节点
  • 原文地址:https://www.cnblogs.com/Gster/p/4989304.html
Copyright © 2011-2022 走看看