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. markdown简明语法

    # markdown简明语法 标签(空格分隔): markdown 本语法只涵盖了常用的内容 [toc] 标题 标题 标题 语法为: 根据需求 可以指定 不同大小的标题 # 顶级 ## 次级 ### ...

  2. 【题解】【BT】【Leetcode】Binary Tree Preorder/Inorder/Postorder (Iterative Solution)

    [Inorder Traversal] Given a binary tree, return the inorder traversal of its nodes' values. For exam ...

  3. nohup启动命令(转)

    简单而有用的nohup命令在UNIX/LINUX中,普通进程用&符号放到后台运行,如果启动该程序的控制台logout,则该进程随即终止. 要实现守护进程,一种方法是按守护进程的规则去编程(本站 ...

  4. vcf_filter.py

    pyvcf 中带的一个工具 比其他工具用着好些 其他filter我很信不过~~  自己写的功能又很有限 所以转投vcf_filter.py啦 Filtering a VCF file based on ...

  5. 从Wordpress迁移到Jekyll

    http://pinkyjie.com/2013/10/24/migrate-from-wordpress-to-jekyll/ 上周末闲着没事干突然想把博客从Wordpress迁移到Github p ...

  6. Java--继承和super关键字

    一.Java中方法的参数传递(重点) Java中参数传递都是值传递 Java中的值分两种: 1.如果传递的参数是基本数据类型: 传递的值就是基本数据类型的值. 传递的时候,其实是把基本数据类型的值,复 ...

  7. linux安装phpredis扩展

    1.下载扩展安装包 wget   https://github.com/nicolasff/phpredis/downloads 2.解压 tar -zxvf nicolasff-phpredis-2 ...

  8. div+css 遮罩层

    CSS样式部分: ---------------------------------- <style type="text/css">#loading-mask{    ...

  9. Codeforces Round #126 (Div. 2)

    A. Cinema 假设当前要的位置为\((x, y)\),如果枚举答案的横坐标,那么每次找离\(y\)最近的纵坐标. 如果占用了位置\((x,y)\),需要要更新第\(x\)行的信息,而占用位置\( ...

  10. spark新能优化之广播共享数据

    如果你的算子函数中,使用到了特别大的数据,那么,这个时候,推荐将该数据进行广播.这样的话,就不至于将一个大数据拷贝到每一个task上去.而是给每个节点拷贝一份,然后节点上的task共享该数据. 这样的 ...