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 (matched\unmatched 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] == -) // 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, -);
Right.assign(MAX, -); int i, ret = ;
bool done = true;
do
{
done = true; // for the new aug. path
visited.assign(MAX, ); for(int i = ; i <= N; i ++)
if(Left[i] == - && dfs(i))
done = false; // augment-able? again.. }while(!done); // Count no. of matched edges
for(int i = ; i <= N; i ++)
ret += Left[i] != -;
return ret;
}
/**********************************************/ bool check(LL val)
{
// Pick reasonable edges
for( int i= ; i<=N ; i++)
for( int j= ; 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= ; 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 + ), Q(M + );
for(int i = ; i <= N; i ++)
cin >> P[i].first >> P[i].second;
for(int i = ; i <= M; i ++)
cin >> Q[i].first >> Q[i].second; // Calculate distances
for(int i= ; i<=N ; i++)
for(int j= ; 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 = , high = ;
while(low < high)
{
LL mid = (low + high) >> ;
if(check(mid)) high = mid;
else low = mid + ;
}
cout << low << endl;
return ;
}

HackerRank "Bike Racer"的更多相关文章

  1. Hackerrank 2020 February 2014 解题报告

    Hackerrank 2020 February 2014 解题报告 比赛链接 Sherlock and Watson (20分) 题意:给定一个数组,向右平移K次,然后有Q个询问,问第x位置上是几 ...

  2. Rust初步(三):使用atom搭配racer进行rust编程

    在rust.cc社区中有一个关于rust编辑器的讨论(话说很多人要学一个新语言,都会立即考虑编辑器的问题,包括我在内),主要关注的是,智能提示(这个真的太重要了).大家讨论下来有几个选择 1. ecl ...

  3. UVALive 6908---Electric Bike(DP或记录型深搜)

    题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  4. 日常小测:颜色 && Hackerrank Unique_colors

    题目传送门:https://www.hackerrank.com/challenges/unique-colors 感谢hzq大神找来的这道题. 考虑点分治(毕竟是路经统计),对于每一个颜色,它的贡献 ...

  5. HackerRank "Square Subsequences" !!!

    Firt thought: an variation to LCS problem - but this one has many tricky detail. I learnt the soluti ...

  6. HackerRank "Minimum Penalty Path"

    It is about how to choose btw. BFS and DFS. My init thought was to DFS - TLE\MLE. And its editorial ...

  7. HackerRank "TBS Problem" ~ NPC

    It is marked as a NPC problem. However from the #1 code submission (https://www.hackerrank.com/Charl ...

  8. HackerRank Extra long factorials

    传送门 今天在HackerRank上翻到一道高精度题,于是乎就写了个高精度的模板,说是模板其实就只有乘法而已. Extra long factorials Authored by vatsalchan ...

  9. HackerRank "Lucky Numbers"

    Great learning for me:https://www.hackerrank.com/rest/contests/master/challenges/lucky-numbers/hacke ...

随机推荐

  1. PAT (Basic Level) Practise:1006. 换个格式输出整数

    [题目链接] 让我们用字母B来表示“百”.字母S表示“十”,用“12...n”来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数.例如234应该被输出为BBSSS1234,因为它 ...

  2. lanuchy快捷操作

    down arrow: display history shift+delete: remove the item from the distory

  3. (实用篇)php 文件夹删除,清除缓存程序

    <?php header('content-type:text/html;charset=utf-8'); function delFile($fpath) { $filesize = arra ...

  4. Linux下用C读取配置文件。类似ini这样。

    Introduction ccl is the customizable configuration library, a collection of functions for applicatio ...

  5. 使用Dnsmasq搭建本地dns服务器上网

    导读 搭建一个属于自己的本地DNS服务器很有必要,利用Dnsmasq来搭建一个属于自己的本地DNS服务器,享受更干净无污染.更智能快速和没有广告干扰的DNS解析服务. 一.Dnsmasq安装 安装并启 ...

  6. codefoces round193a

    link: http://codeforces.com/contest/332/problem/A /* ID: zypz4571 LANG: C++ TASK: 193a.cpp */ #inclu ...

  7. leetcode 121. Best Time to Buy and Sell Stock ----- java

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  8. sessionStorage和localStorage中 存储

    转:http://my.oschina.net/crazymus/blog/371757 sessionStorage只在页面打开是起作用, localStorage关闭页面后仍然起作用. 有时候,我 ...

  9. 黑马程序员——JAVA基础之简述多线程,两种创建多线程的方式

    ------- android培训.java培训.期待与您交流! ---------- 多线程: 进程和线程: 进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者 ...

  10. 视图缩放、移动、旋转--ios

    UIView *view=[[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)]; view.backgroundColor=[UICo ...