zoukankan      html  css  js  c++  java
  • HackerRank "Bike Racer"

    Just for study from its editorial~

    Lesson learnt: an optimized Hungarian Algorithm: Hopcroft-Karp Algorithm (a batched version of Hungarian)
    A very good article on it (in Chinese): https://www.renfei.org/blog/bipartite-matching.html

    The basic idea of Hungarian is: find all augment pathes and flip (matchedunmatched toggled) them, recursively.
    And Hopcroft-Karp is a batched version of Hungarian: we simply check all edges at each node.

    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    #include <unordered_set>
    using namespace std;
    
    #define MAX 2001
    
    typedef long long LL;
    
    int N, M, K;
    vector<int> edges[MAX]; // edges of left side
    vector<bool> visited(MAX);
    vector<int> Left(MAX), Right(MAX);
    vector<vector<LL>> dist(MAX, vector<LL>(MAX));
    
    /*
     *    Hopcroft-Karp Algorithm: optimized(batched) Hungarian Algorithm
     *     Complexity: E*sqrt(V)
     */
    
    //    True: augment path flipped
    //    False:augment path stay the same
    //
    bool dfs(int u)
    {
        if(visited[u]) return false;
        
        visited[u] = true;
        
        //    Flip input u-v pairs
        for(auto v : edges[u])
        {
            if(Right[v] == -1) // u-v not matched
            {
                // then match u-v
                Right[v] = u, Left[u] = v;
                return true; 
            }
        }
        
        //    Given all input u-v are matched    then match deeper pathes
        for(auto v : edges[u])
        {
            if(dfs(Right[v])) // flipped deeper?
            {
                //    then flip current edge too
                Right[v] = u, Left[u] = v;
                return true;
            }
        }
        return false;
    }
    
    int match()
    {
        //    Cleanup work
        Left.assign(MAX, -1);    
        Right.assign(MAX, -1);
        
        int i, ret = 0;
        bool done = true;
        do
        {
            done = true;
            
            // for the new aug. path
            visited.assign(MAX, 0);
            
            for(int i = 1; i <= N; i ++)
                if(Left[i] == -1 && dfs(i))
                    done = false; // augment-able? again..
            
        }while(!done);
        
        //    Count no. of matched edges
        for(int i = 1; i <= N; i ++) 
            ret += Left[i] != -1;
        return ret;
    }
    /**********************************************/
    
    bool check(LL val)
    {
        //    Pick reasonable edges
        for( int i=1 ; i<=N ; i++)    
        for( int j=1 ; j<=M ; j++)
            if(dist[i][j] <= val)
                edges[i].push_back(j);
    
        //    Run Hopcroft-Karp
        LL num_match = match();
    
        //    Clean for the next check
        for(int i= 1 ; i<= N ; i++)
            edges[i].clear();
    
        return num_match >= K;
    }
    
    int main()
    {    
        cin >> N >> M >> K;
        
        //    Get input array
        vector<pair<LL, LL>> P(N + 1), Q(M + 1);
        for(int i = 1; i <= N; i ++)
            cin >> P[i].first >> P[i].second;
        for(int i = 1; i <= M; i ++)
            cin >> Q[i].first >> Q[i].second;
        
        //     Calculate distances    
        for(int i=1 ; i<=N ; i++)    
        for(int j=1 ; j<=M ; j++)
        {
            LL a = P[i].first - Q[j].first;
            LL b = P[i].second - Q[j].second;
            dist[i][j] = a * a + b * b;
        }
    
        //    Binay Search the min matching result for K
        LL low = 0, high = 10000000000000000;
        while(low < high)
        {
            LL mid = (low + high) >> 1;
            if(check(mid))    high = mid;
            else            low  = mid + 1;        
        }
        cout << low << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    代码编译时JDK版本和运行时JDK版本不一致启动项目报错
    Apache 环境变量配置
    Android NDK 环境变量配置
    Android SDK 环境变量配置
    JAVA 环境变量配置
    FFmpeg Download
    JAVA SE Download
    VS 2015 Download
    BASS HOME
    C++11的闭包(lambda、function、bind)
  • 原文地址:https://www.cnblogs.com/tonix/p/5163152.html
Copyright © 2011-2022 走看看