2020杭电多校第四场 Go Running 最小点覆盖等于二分图最大匹配数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6808
思路:刚开始也是乱想,想几下就忍不住画个t-x图像,然后每个点有两种可能,一是向西跑,一是向东跑。在图中都画出来发现:
我画了4个点,箭头表示可能移动的方向,这时候发现这不就是找“覆盖所有点最少需要多少条直线”吗?我蠢的是刚开始就想到了这里,然后我忘了怎么找了,这种模板题当初学二分图时就做过,到了最后20分钟恍然大悟:把横纵坐标分别当做二分图的两边,把点所在的横纵坐标相连。因为我们把横纵坐标当做了二分图的点,二分图中的一个边就代表一个点。到这里就很清楚了,我们求的就是:选最少的点使得二分图中每条边都有端点被覆盖。最小点覆盖就是:选最少的点让二分图中每个边都有端点被选。最大匹配数 = 最小点覆盖。n = 1e5,肯定dinic,套个板子就行了。
咦?怎么知道点是不是在一条直线呢?直接旋转坐标系45度就行了。
x'=x·cos(θ)+y·sin(θ)
y'=y·cos(θ)-x·sin(θ)
我就直接用map哈希的,分配编号就行了。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define lowbit(x) ((-x)&x)
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define bep(i, a, b) for(int i = a; i >= b; i--)
#define pb push_back
#define mp make_pair
#define debug cout << "KKK" << endl
#define ls num*2
#define rs num*2+1
#define re return
using namespace std;
const ll mod = 1e9 + 7;
const double PI = acos(-1);
const ll INF = 2e18+1;
const int inf = 1e9+5;
const double eps = 1e-10;
const int maxn = 2e5 + 5;
inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline int rd(){
int x = 0; char ch = gc(); bool positive = 1;
for (; !isdigit(ch); ch = gc()) if (ch == '-') positive = 0;
for (; isdigit(ch); ch = gc()) x = x * 10 + ch - '0';
return positive ? x : -x;
}
map<double, int> vx, vy; ll dis[maxn];
int tot=1, cur[maxn],ne[maxn]; // tot初始化为1哦。 struct node {
int to,net;
long long val;
} p[maxn*2]; inline void add(int u,int v,long long w) {
p[++tot] = (node){v, ne[u], w};
ne[u] = tot;
} inline int bfs(int s, int t) {
for(register int i=1;i<=t;i++) dis[i]=inf;
queue<int> q;
q.push(s);
dis[s]=0;
cur[s]=ne[s];
while(!q.empty()) {
int x=q.front();
q.pop();
for(register int i=ne[x];i;i=p[i].net) {
int v=p[i].to;
if(p[i].val>0&&dis[v]==inf) {
q.push(v);
cur[v]=ne[v];
dis[v]=dis[x]+1;
if(v==t) return 1;
}
}
}
return 0;
} inline ll dfs(int x,long long sum,int t) {
if(x==t) return sum;
long long k,res=0;
for(register int i=cur[x];i&∑i=p[i].net) {
cur[x]=i;
int v=p[i].to;
if(p[i].val>0&&(dis[v]==dis[x]+1)) {
k=dfs(v,min(sum,p[i].val), t);
if(k==0) dis[v]=inf;
p[i].val-=k;
p[i^1].val+=k;
res+=k;
sum-=k;
}
}
return res;
} ll dinic(int s, int t){
ll ans = 0;
while(bfs(s, t)) {
ans+=dfs(s,inf, t);
}
return ans;
} int main(){
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
int T = rd();
double xx, yy, sq = sqrt(2)/2; //sq就是sin(θ)
int x, t, dx, dy;
int n, m, px, py;
while(T--){
vx.clear(); vy.clear();
n = rd(); tot = 1;
px = 0, py = n;
int st = 0, en= 2*n + 3; // 源点汇点
rep(i, 0, en) ne[i] = 0;
rep(i, 1, n){
x = rd();
t = rd();
xx = sq*(x + t);
yy = sq*(x - t); //旋转后的坐标
if(!vx.count(xx)) vx[xx] = ++px;
if(!vy.count(yy)) vy[yy] = ++py; // 分派编号
dx = vx[xx], dy = vy[yy];
add(dx, dy, 1);
add(dy, dx, 0); // 二分图建边
}
rep(i, 1, px){
add(st, i, 1);
add(i, st, 0); //源点建边
}
rep(i, n+1, py){
add(i, en, 1);
add(en, i, 0); //汇点建边
}
cout << dinic(st, en) << endl;
}
return 0;
}
2020杭电多校第四场 Go Running 最小点覆盖等于二分图最大匹配数的更多相关文章
- 杭电多校第四场 E Matrix from Arrays
Problem E. Matrix from Arrays Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 ...
- 杭电多校第四场 Problem K. Expression in Memories 思维模拟
Problem K. Expression in Memories Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262 ...
- [2019杭电多校第四场][hdu6623]Minimal Power of Prime
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6623 题目大意为求一个数的唯一分解的最小幂次.即120=23*31*51则答案为1. 因为数字太大不能 ...
- [2019杭电多校第四场][hdu6621]K-th Closest Distance(主席树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6621 题意为求区间[l,r]内第k小|a[i]-p|的值. 可以二分答案,如果二分的值为x,则判断区间 ...
- [2019杭电多校第四场][hdu6616]Divide the Stones
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6616 题意是说n个数分别为1-n,将n个数分成k堆,能否满足每堆个数相等,数值之和相等.保证n%k=0 ...
- [2019杭电多校第四场][hdu6614]AND Minimum Spanning Tree(贪心)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6614 题目大意是有一张n个点的完全图,n个点点权为1-n,边权为两点点权按位与(&).求最小生 ...
- 2019杭电多校第四场hdu6623 Minimal Power of Prime
Minimal Power of Prime 题目传送门 解题思路 先打\(N^\frac{1}{5}\)内的素数表,对于每一个n,先分解\(N^\frac{1}{5}\)范围内的素数,分解完后n变为 ...
- 杭电多校第四场-H- K-th Closest Distance
题目描述 You have an array: a1, a2, , an and you must answer for some queries.For each query, you are g ...
- 2019杭电多校第四场hdu6621 K-th Closest Distance(二分答案+主席树)
K-th Closest Distance 题目传送门 解题思路 二分答案+主席树 先建主席树,然后二分答案mid,在l和r的区间内查询[p-mid, p+mid]的范围内的数的个数,如果大于k则说明 ...
- 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)
以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...
随机推荐
- Tomcat 性能监控与调优
Tomcat 性能监控与调优 Tomcat 远程 Debug JDWP bin/startup.sh 修改最后一行(添加 jpda) exec "$PRGDIR"/"$E ...
- 实时中文语音克隆——开源项目MockingBird体验
[引子] 在今年大型网络攻防演练前不久,笔者接到一个公司的座机号码来电,上来就问防守准备得怎么样了,哪里还有不足等.等等,这声音不认识,笔者第一反应就是蓝军(Red Team)来进行社会工程攻击,于是 ...
- 实验:spring-boot整合mybatis-plus实现分页查询的功能
1.建立基于sping-boot的javaweb工程(java1.8) 按结构建立包 2.POM.XML添加支持mybatis-plus,sql,lombok <!--mybatis-plus的 ...
- mac常用命令和Git创建tag命令
一.mac命令 p.p1 { margin: 0; font: 12px ".PingFang SC" } p.p2 { margin: 0; font: 12px "H ...
- CCF 202006-2 稀疏向量
#include <iostream> #include <bits/stdc++.h> #include <string> using namespace std ...
- leetcode-560-和为 K 的子数组
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 . 示例 1: 输入:nums = [1,1,1], k = 2 输出:2 示例 2: 输入:num ...
- 使用SonarQube对Unity项目进行代码分析的问题记录
1.这里不仔细描述每个步骤,只记录一些关键问题,到官网下载解压最新版的SonarQube(我用的是8.9.1). 2.下载安装jdk,这里要注意官网的说明,我一开始下的jdk16,启动Sonar后报错 ...
- JS计算加减乘除出现多位小数的解决方法
function add(arg1, arg2){ let decima1, decima2, differ, m; try { decima1 = arg1.toString().split('.' ...
- PLC入门笔记8
梯形图基础电路 起保停电路 多点起保停电路 互锁控制电路 周期闪烁电路 这应该是等价的!! 定时器的接力电路 同 延时接通,延时断开电路 同 保持信号变脉冲信号电路 定时器TON 接通延时变断开延时电 ...
- springboot项目记录2用户注册功能
七.注册-业务层 7.1规划异常 7.1.1用户在进行注册的时候,可能会产生用户名被占用的错误,抛出一个异常: RuntimeException异常,作为该异常的子类,然后再去定义具体的异常类型继承这 ...