交友问题
交友问题
题目背景
题目描述
洛谷上有 位用户,这些用户组成了一个双向的网络。
洛谷的图片分享机制如下:如果第 个用户向他的好友 分享了一张照片,那么, 的所有好友 就能看到这张照片。 也可以看到这张照片。
现在,用户 想分享一张照片,但是TA不想让用户 看到这张照片。在不发送给自己的情况下,TA想知道,他最多可以发送给多少位好友?
输入格式
第一行三个正整数 ,分别代表用户数,边数,询问数。
接下来 行,每行两个数 ,表示用户 与 之间有一条双向边。
接下来 行,每行两个数 ,表示第 次询问。
输出格式
对于每一次询问,输出一行,包含一个数,答案。
样例 #1
样例输入 #1
6 7 8
5 1
1 4
1 6
5 6
5 4
1 2
5 3
5 3
1 1
3 6
1 5
5 6
1 4
5 2
2 6
样例输出 #1
3
0
0
1
2
2
3
0
提示
对于 的数据,满足 ,;
对于 的数据,满足 ,;
对于 的数据,满足 ,。
保证没有重边和自环
解题思路
容易想到暴力的做法。对于询问 ,我们枚举 的所有邻点 ,如果 并且 的邻点不含 ,则可以将图片发送给 。如果用 std::set
来存储邻点,那么时间复杂度就是 。
我们本质是想统计与 相邻但不与 相邻的节点,所以可以给每个点 开一个 std::bitset
来记录与它相邻的点,记为 。那么既与 和 相邻的节点就是 ,则只与 相邻不与 相邻的节点就是 (如果 和 相邻需要将 的第 位置为 )。时间复杂度就是 ,时限 是可以过的,但这种做法的空间复杂度为 会爆掉。
当我们想到两种暴力的做法,就可以尝试根号分治了。如果要在图论问题中用根号分治,一般是根据点的轻重进行分类。设置一个阈值 ,如果一个节点的度数不超过 ,则该节点定义为轻节点,否则节点的度数超过 就定义为重节点。假设图中边的数量为 ,可以知道重节点的数量不超过 。
接下来就是分类讨论。
- 如果 是轻节点,那么我们直接用第一种暴力,时间复杂度是 。
- 否则如果 是轻节点,我们也用第一种暴力,不过此时我们枚举的是 的所有邻点 。一开始先假设答案选择了 的所有邻点,如果 或者 的邻点含 ,那么这个点不能被选,应将其从答案中删掉。时间复杂度也是 。
- 否则,此时 和 都是重节点,直接用第二种暴力即可,时间复杂度是 。
已知 是可以过的,因此我们可以将两种暴力的时间复杂度统一起来,即令 ,有 。另外空间复杂度为 ,这就不会爆空间了。
AC 代码如下,时间复杂度为 :
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 5, B = 180;
set<int> st[N];
int main() {
int n, m, k;
scanf("%d %d %d", &n, &m, &k);
while (m--) {
int u, v;
scanf("%d %d", &u, &v);
st[u].insert(v);
st[v].insert(u);
}
map<int, bitset<N>> mp;
for (int i = 1; i <= n; i++) {
if (st[i].size() > B) {
for (auto &x : st[i]) {
mp[i][x] = 1;
}
}
}
while (k--) {
int u, v;
scanf("%d %d", &u, &v);
int ret = 0;
if (st[u].size() <= B) {
for (auto &x : st[u]) {
if (x != v && !st[x].count(v)) ret++;
}
}
else if (st[v].size() <= B) {
ret = st[u].size();
for (auto &x : st[v]) {
if (x == u || st[x].count(u)) ret--;
}
}
else {
ret = (mp[u] ^ (mp[u] & mp[v])).count() - mp[u][v];
}
printf("%d\n", ret);
}
return 0;
}
参考资料
暴力美学——浅谈根号分治:https://www.luogu.com/article/5gtqzd4a
P8250 题解:要平衡的是空间,而不是时间:https://www.luogu.com.cn/article/wbg93nq4
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/18156213
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效