3337. 我认识你
2.0 seconds
256 megabytes
人与人之间的关系错综复杂,常常会出现一个叫作共同好友的东西。所以,贴心的 QQ 就提供了这样一个功能,可以显示你与某人(不一定是好友)有多少个共同好友。但是,当用户量逐渐增大,好友关系网不断复杂化,共同好友计算的效率就变得十分重要了。
你刚刚和腾讯公司签约,获得了共同好友计算的开发资格。
Input
n,m(1≤n≤40000,1≤m≤40000)1n。
mu,v(1≤u,v≤n,u≠v)uvu,v。
q(1≤q≤40000)
qs,t(1≤s,t≤n,s≠t),表示询问的对象。
小数据规模说明:
- 20%1≤n≤10,1≤q≤200。
- 40%1≤n≤1000。
Output
对于每组询问,输出这两个人有多少个共同好友。
Examples
input
3 3 1 2 1 3 3 2 2 1 3 3 2
output
1 1
input
4 4 1 2 1 4 2 3 3 4 3 1 3 1 4 2 4
output
2 0 2
input
3 2 1 2 1 3 2 2 3 2 3
output
1 1
题解:一开始用暴力做,邻接矩阵存每个点及与它相连的点
对于每个询问,用一个used数组标记有哪几个点同时与s和t相连,计数输出即可。
但这样O(qn)时间复杂度太高只能过50%数据。
考虑用bitset压位计算。
对每个人开一个bitset,如果与第i个人有关系则对应位置1,对于每个query,两者相与取1的个数即为答案。
代码看起来非常elegant。
#include <bits/stdc++.h> #define vi vector<int> using namespace std; const int MAX_N = 4e4 + 10; int used[MAX_N]; bitset<MAX_N> graph[MAX_N]; int seq[MAX_N]; int main() { // freopen("out.txt","w",stdout); ios::sync_with_stdio(false); cin.tie(0); int n,m; cin >> n >> m; for(int i = 0; i < m; i++) { int u,v; cin >> u >> v; graph[u][v] = 1; graph[v][u] = 1; } int q; cin >> q; while(q--) { int s,t; cin >> s >> t; bitset<MAX_N> temp = bitset<MAX_N>(graph[s] & graph[t]); cout << temp.count()<<endl; } return 0; }
文章来源: EOJ3337 我认识你