zoukankan      html  css  js  c++  java
  • 飞行员配对方案问题

    飞行员配对方案问题

    传送门

    读完题,就知道这就是个裸的二分图皮配,然后,我还是不说匈牙利,(因为我真的不会啊!)

    所以,我还是用了喜闻乐见的 Dinic 并且跑的也不慢.唯一难点就是输出方案了吧...输出方案用最后的连通性判断,这题就没了....

    Code:

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    const int N = 1e5 + 5 ;
    const int INF = 1061109567 ;
    
    using std::queue ;
    
    struct edge { int to , next , flow ; } e[(N<<1)] ;
    
    int tot = 1 , head[N] , flor[N] , s , t , n , m , x , y ;
    
    inline void build (int u , int v ,int w) {
        e[++tot].next = head[u] ; e[tot].to = v ;
        e[tot].flow = w ; head[u] = tot ; return;
    }
    
    queue < int > q ;
    inline bool bfs ( int cur ) {
        while ( ! q.empty () ) q.pop () ;
        memset ( flor , false , sizeof ( flor ) ) ;
        q.push ( cur ) ; flor[cur] = 1 ;
        while ( ! q.empty () ) {
            int j = q.front () ; q.pop () ;
            for (int i = head[j] ; i ; i = e[i].next) {
                int k = e[i].to ;
                if ( ! flor[k] && e[i].flow ) {
                    flor[k] = flor[j] + 1 ;
                    if ( k == t ) return flor[t] ;
                    q.push ( k ) ;
                }
            }
        }
        return flor[t] ;
    }
    
    inline int dfs (int cur , int dist) {
        if ( cur == t ) return dist ;
        for (int i = head[cur] ; i ; i = e[i].next) {
            int k = e[i].to ;
            if ( flor[k] == flor[cur] + 1 && e[i].flow ) {
                int now = dfs ( k , std::min ( e[i].flow , dist ) ) ;
                if ( now != 0 ) {
                    e[i].flow -= now ;
                    e[i^1].flow += now ;
                    return now ;
                }
            }
        }
        return 0 ;
    }
    
    inline int Dinic () {
        int ans = 0 ;
        while ( bfs ( s ) )
            while ( int now = dfs ( s , INF ) )
                ans += now ;
        return ans ;
    }
    
    int main () {
        scanf ("%d%d" , & m , & n ) ; s = 0 ; t = n + 1 ;
        for (int i = 1 ; i <= m ; ++ i) build ( s , i , 1 ) , build ( i , s , 0 ) ; // 连外籍
        for (int i = m + 1 ; i <= n ; ++ i) build ( i , t , 1 ) , build ( t , i , 0 ) ; // 连皇家
        while ( scanf ("%d%d" , & x , & y ) && x != - 1 && y != - 1 )
            build ( x , y , 1 ) , build ( y , x , 0 ) ;
        int ans = Dinic () ;
        if ( ! ans ) { puts ("No Solution!") ; return 0 ; }
        printf ("%d
    " , ans  ) ;
        for (int i = 2 ; i <= tot ; i += 2)
            if ( e[i].to != s && e[i^1].to != s )
                if ( e[i].to != t && e[i^1].to != t )
                    if ( e[i^1].flow != 0 ) printf ("%d %d
    " , e[i^1].to , e[i].to ) ;
        system ("pause") ; return 0 ;
    }
    
    May you return with a young heart after years of fighting.
  • 相关阅读:
    微博短地址识别正则表达式
    VM 虚拟机, linux mount windows的共享目录,php报错:Fatal error: Unknown: Failed opening required
    新贵 轻雅 100 数字键 numlock问题
    [转]人大常委会委员:文理分科降低民族整体素质
    NTFS变RAW后的修复
    西门子plc视频教程
    ProE 工程图教程系列3 Pro/E消息区域中错误、警告消息的处理
    奥运会上同时升起三面五星红旗
    亦歌 在线听歌网站
    [转]国内外常用钢号对照表
  • 原文地址:https://www.cnblogs.com/Equinox-Flower/p/10786098.html
Copyright © 2011-2022 走看看