整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


CF1519E

Weblink

https://codeforces.com/contest/1519/problem/E

Problem

Solution

显然同一个直线上的点,(x,y)(x,y)(x,y),x,yx,yx,y 同除 gcd⁡(x,y)\gcd(x,y)gcd(x,y) ,得到的是同一个点,所以我们可以在输入的时候处理一下每个点上移一步(x+1,y)(x+1,y)(x+1,y),下移一步 (x,y+1)(x,y+1)(x,y+1) 到达的是哪条直线,我们直接映射一下,这样就可以 O(n)O(n)O(n) 建图。什么?你说 x,yx,yx,y 不一定是整数?x=ab,y=cdx=\cfrac{a}{b},y=\cfrac{c}{d}x=ba​,y=dc​,例如 (x,y+1)=(ab,cd+1)(x,y+1)=(\cfrac{a}{b},\cfrac{c}{d}+1)(x,y+1)=(ba​,dc​+1) 显然我们直接将点同乘 b×db\times db×d ,因为不管乘多少,最后除去 gcd⁡\gcdgcd 以后都代表同一个直线。

即:

(ab,cd+1)=(ab×bd,(cd+1)×bd)=(a×d,b×(c+d))\begin{aligned}(\cfrac{a}{b},\cfrac{c}{d}+1)&=(\cfrac{a}{b}\times b\ d,(\cfrac{c}{d}+1)\times b\ d)&\\&=(a\times d,b\times(c+d))\end{aligned}(ba​,dc​+1)​=(ba​×b d,(dc​+1)×b d)=(a×d,b×(c+d))​​

(ab+1,cd)=((ab+1)×bd,cd×bd)=((a+b)×d,b×c))\begin{aligned}(\cfrac{a}{b}+1,\cfrac{c}{d})&=((\cfrac{a}{b}+1)\times b\ d,\cfrac{c}{d}\times b\ d)&\\&=((a+b)\times d,b\times c))\end{aligned}(ba​+1,dc​)​=((ba​+1)×b d,dc​×b d)=((a+b)×d,b×c))​​

建图之后我们计算最大的匹配边数即可。好像是一个最大匹配?带花树!但是很难处理,每一个点,因为有两个移动策略,所以每一个点会拓展成两个点,也就代表着两条直线,所以把题目中的模型抽离出来,即为:给定一个无向图,每次匹配为选定两条没有用过的相邻的边,将他们匹配,求最大的匹配数以及匹配的方案数。

直接做无向图有点难搞,显然我们可以利用数据简化的思想,先来考虑树的做法,显然对于一颗节点数为 nnn 的树,最大匹配边数为 ⌊n2⌋\lfloor\cfrac{n}{2}\rfloor⌊2n​⌋,即除了一条直接与根节点相连的边不确定以外,其他的边一定能够两两配对,因为对于一个节点,如果度数为偶数 2k2k2k,显然形成 kkk 个匹配,若为奇数 2k−12k-12k−1,我们可以将它与它的父结点匹配,剩余的点就为偶数个,相互匹配既可。

那么拓展到一个无向图,我们只需要将无向图转换为一个树就行啦,当然图不一定是连通的,所以是一个森林hhh 。我们选择DFS序生成树,这样一个无向图就被分为了若干个生成树,有树边和非树边,我们直接按照时间戳,按照深度从大到小,从低到高匹配,可以保证匹配数一定可以达到 ⌊n2⌋\lfloor\cfrac{n}{2}\rfloor⌊2n​⌋ 的上界。

具体的代码实现的话,我们有一个取巧的方法,设 match[x] 表示是否存在一条与 xxx 相连且还没有匹配的边,这样我们只需要看一下子节点和父结点是否有可以匹配的边就行了。

因为每条边只能用一次,所以我们用完之后直接把边删掉就行了。

Code

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
#define x first
#define y secondconst int N = 500007;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;map<PLL, int> mp;
vector<PII> ans;
PII match[N];
int cnt;
int n, m;
bool vis[N];
int head[N], ver[N], edge[N], nex[N], tot;int get_id(ll x, ll y)
{ll d = __gcd(x, y);x /= d;y /= d;if(mp.find({x, y}) == mp.end())mp[{x, y}] = ++ cnt;return mp[{x, y}];
}void add(int x, int y, int id)
{ver[tot] = y;nex[tot] = head[x];edge[tot] = id;head[x] = tot ++ ;
}int dfs(int x)
{vis[x] = 1;for(int i = head[x]; ~i; i = nex[i]) {int y = ver[i], id = edge[i];ver[i] = ver[i ^ 1] = 0;if(y) {if(vis[y] == 0)dfs(y);if(match[y].x) {ans.push_back({id, match[y].y});match[y] = {0, 0};}else if(match[x].x) {ans.push_back({match[x].y, id});match[x] = {0, 0};}else match[x] = {y, id};}}
}int main()
{memset(head, -1, sizeof head);scanf("%d", &n);for(int i =1; i <= n; ++ i) {int a, b, c, d, x, y;scanf("%d%d%d%d", &a, &b, &c, &d);x = get_id((1ll * a + b) * d, 1ll * b * c);y = get_id(1ll * a * d, (1ll * c + d) * b);add(x, y, i);add(y, x, i);}for(int i = 1; i <= cnt; ++ i) if(vis[i] == 0)  dfs(i);printf("%d\n", ans.size()); for(auto i : ans) {printf("%d %d\n", i.first, i.second);}return 0;
}

Educational Codeforces Round 108(Rated for Div. 2) E - Off by One(一种一般图的边最大匹配,好题)相关推荐

  1. Educational Codeforces Round 108 (Rated for Div. 2)-B. The Cake Is a Lie-题解

    目录 Educational Codeforces Round 108 (Rated for Div. 2)-B. The Cake Is a Lie Problem Description Inpu ...

  2. Educational Codeforces Round 108 (Rated for Div. 2) D. Maximum Sum of Products 思维 + dp

    传送门 文章目录 题意: 思路: 题意: 给你两个长度为nnn的数组a,ba,ba,b,你可以至多反转一段连续区间,求∑i=1nai∗bi\sum _{i=1}^n a_i*b_i∑i=1n​ai​∗ ...

  3. Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)

    Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...

  4. Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...

  5. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...

  6. Educational Codeforces Round 37 (Rated for Div. 2) 1

    Educational Codeforces Round 37 (Rated for Div. 2) A.Water The Garden 题意:Max想给花园浇水.花园可被视为长度为n的花园床,花园 ...

  7. Educational Codeforces Round 89 (Rated for Div. 2)(A, B, C, D)

    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords 思路 题意非常简单,就是得到最多的物品嘛,我们假定a, ...

  8. Educational Codeforces Round 114 (Rated for Div. 2) D. The Strongest Build 暴力 + bfs

    传送门 文章目录 题意: 思路: 题意: 你有nnn个装备槽,每个槽里面有cic_ici​个力量加成,对于每个槽只能选一个力量加成,现在给你mmm个力量组合[b1,b2,...,bn][b_1,b_2 ...

  9. Educational Codeforces Round 72 (Rated for Div. 2) D. Coloring Edges dfs树/拓扑找环

    传送门 文章目录 题意: 思路: 题意: 给你一张图,你需要给这个图的边染色,保证如果有环那么这个环内边的颜色不全相同,输出染色方案和用的颜色个数. n,m≤5e3n,m\le5e3n,m≤5e3 思 ...

最新文章

  1. Cookie和Session的区别与联系
  2. Swift--逃逸闭包与非逃逸闭包(Swift3.1)
  3. 如何使用 .NET Core 安全地加/解密文件
  4. 7-4 最短工期 (25 分)
  5. CVPR 2020 论文大盘点-目标检测篇
  6. 机器学习-吴恩达-笔记-5-神经网络学习
  7. 俄罗斯、乌克兰程序员薪资大曝光:年薪普遍 15w+,女程序员比男程序员收入高?
  8. Python调用搜狗语音API实现文字转音频
  9. 如何使用微信小程序第三方UI组件库
  10. word转PDF时,英文单词的字母间距问题
  11. 阿里需要定力打持久战
  12. 【基于Centos】驱动安装
  13. 华为路由器DNS服务器未响应,路由器dns辅服务器未响应
  14. 写数据分析报告,建议部分憋到脸红,咋整?
  15. Linux-alias设置命令别名
  16. 一个会发邮件的Java
  17. npm ERR While resolving: vue-admin-template@3.8.0问题的解决方案
  18. 扬州大学广陵学院计算机控制,计算机控制课程设计(最小拍无波纹).docx
  19. LeetCode高频题:《逆水寒》在地图的制作中,美术在地图上刷一片连通区域,连通区域自动填充,请你判断给定几个点位置,他们是否属于被刷区域
  20. JS代码清除localStorage缓存

热门文章

  1. 目标检测算法终结篇:YOLOv7(非正式版)正式开源
  2. Mysql 根据一个表数据更新另外一个表
  3. virsh 常用操作
  4. asp.net C# 实现微信接口权限开发类
  5. win32 打印机api
  6. SVN:更新、同步与提交 PS:被锁定之解决方法
  7. python 中的下划线
  8. python logger
  9. 海思3531D上编译FFmpeg源码操作步骤
  10. 二极管ss14测量_各种常用二极管的检测方法