题目描述:
一个社交平台上有 N 名用户,其中,有 M 对用户是互相关注的,有 K 对用户是互相拉黑的。
当用户 i 和用户 j 满足以下条件时,用户 j 就是用户 i 的“推荐用户”:
- 用户 i 可以与 用户 j 通过若干对用户的互相关注关系连接起来。(比如用户 1 与用户 2,用户 2 与用户 3 都互相关注,则用户 1 和 用户 3 就可以通过他们的关系连接起来)
- 用户 i 与用户 j 没有互相关注或互相拉黑。
求每位用户的“推荐用户”的数量。
数据保证不会存在一对用户既互相关注又互相拉黑。
限制:
输入:
输出:
样例1
输入:
4 4 1
2 1
1 3
3 2
3 4
4 1
输出:
0 1 0 1
样例2
输入:
5 10 0
1 2
1 3
1 4
1 5
3 2
2 4
2 5
4 3
5 3
4 5
输出:
0 0 0 0 0
样例3
输入:
10 9 3
10 1
6 7
8 2
2 5
8 4
7 3
10 9
6 4
5 8
2 6
7 5
3 1
输出:
1 3 5 4 3 3 3 3 1 0
思路:把这个人并查集里的人-他认识的朋友-他自己就是最终结果
代码:
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const ll N=1e7+5;
ll pre[N];
ll ans[N];
ll ant[N];
ll find(ll x)
{
if(x==pre[x])return x;
return pre[x]=find(pre[x]);
}
void join(ll x,ll y)
{
ll a=find(x);
ll b=find(y);
if(a!=b)
{
pre[a]=b;
ans[b]+=ans[a];
}
}
int main()
{
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
pre[i]=i;
ans[i]=1;
}
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
ant[x]++;
ant[y]++;
join(x,y);
}
for(int i=1;i<=k;i++)
{
ll x,y;
cin>>x>>y;
ll a=find(x);
ll b=find(y);
if(a==b)
{
ant[x]++;
ant[y]++;
}
}
for(int i=1;i<=n;i++)
{
cout<<ans[find(i)]-ant[i]-1<<" ";
}
return 0;
}