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)
以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...
随机推荐
- FFmpeg input与output 函数流程
重要结构体 AVFormatContext AVCodecContextAVCodecAVPacketAVFrame 0.公共部分 av_register_all(); avfilter_regist ...
- 打车起步价8元(3KM以内) 超过3KM,超出的每公里1.2元 超过5KM,超出的每公里1.5元 请在键盘上接收公里数,得出总价。
import java.util.Scanner; public class Taxi { public static void main(String []agrs){ Scanner s = ne ...
- Centos7编译Nginx1.19.0笔记
下载Nginx安装包 官网下载页:http://nginx.org/en/download.html 终端输入: # 安装依赖yum -y install wget gcc gcc-c++ autoc ...
- Python 的 Requests 和 Httpx 在爬取应用中的一个区别
HTTPX是功能齐全的Python3的HTTP客户端,支持同步和异步API,支持HTTP/1.1 和 HTTP/2. 一般情况下,在爬取网页内容的时候,httpx 与 requests 的基本使用方法 ...
- <四>JMeter数据库连接/后置处理器/断言简介
一.数据库连接 1.右键线程组添加--配置元件--JDB Cconnection Configuration 2.配置如下: URL为数据路连接地址,用户名密码为数据库用户名和密码 3.添加一个JDB ...
- b站——沐神——深度学习
预备知识 数据操作 MXNet nd:(array函数:得到NDArray) [[1. 1. 1.] [1. 1. 1.]] <NDArray 2x3 @cpu(0)> np:(asnum ...
- ESP32(WeMos D1 R32)开发资料
1.乐鑫官网 2.ESP32踩坑 ESP32控制摇杆,定义sw的引脚时一定要设置为上拉才行. 3.ESP32入门之arduino IDE环境搭建 4.ESP32 MicroPython编程官网文档 E ...
- SQL Server 还原数据库
1.备份要还原的数据库 选择要备份的数据库,右键单击,任务--备份. 2.备份完成后,将数据库还原 3.新建一个空的数据库,比如Gsy_TestNew,将备份的数据库还原到这个新的库上 4.右键单击[ ...
- Python抓取数据具体流程
之前看了一段有关爬虫的网课深有启发,于是自己也尝试着如如何过去爬虫百科"python"词条等相关页面的整个过程记录下来,方便后期其他人一起来学习. 抓取策略 确定目标:重要的是先确 ...
- 数据库ip被锁了怎么办
由于多次访问失败,导致ip被限制,登录时会报错 Internal error/check (Not system error) 如何解决: 找一台同事的机子,(或者修改自己的ip),然后打开sql 的 ...