Friend Suggestions

一个社交平台上有 NN 名用户,其中,有 MM 对用户是互相关注的,有 KK 对用户是互相拉黑的。

当用户 ii 和用户 jj 满足以下条件时,用户 jj 就是用户 ii 的“推荐用户”:

  • 用户 ii 可以与 用户 jj 通过若干对用户的互相关注关系连接起来。(比如用户 1 与用户 2,用户 2 与用户 3 都互相关注,则用户 1 和 用户 3 就可以通过他们的关系连接起来)
  • 用户 ii 与用户 jj 没有互相关注或互相拉黑。

求每位用户的“推荐用户”的数量。

数据保证不会存在一对用户既互相关注又互相拉黑。

Constraints

  • 输入的所有数值都是整数。
  • 2 ≤ N ≤ 10^52≤N≤105
  • 0 \leq M \leq 10^50≤M≤105
  • 0 \leq K \leq 10^50≤K≤105
  • 1 \leq A_i, B_i \leq N1≤Ai​,Bi​≤N
  • A_i \neq B_iAi​=Bi​
  • 1 \leq C_i, D_i \leq N1≤Ci​,Di​≤N
  • C_i \neq D_iCi​=Di​
  • (A_i, B_i) \neq (A_j, B_j) (i \neq j)(Ai​,Bi​)=(Aj​,Bj​)(i=j)
  • (A_i, B_i) \neq (B_j, A_j)(Ai​,Bi​)=(Bj​,Aj​)
  • (C_i, D_i) \neq (C_j, D_j) (i \neq j)(Ci​,Di​)=(Cj​,Dj​)(i=j)
  • (C_i, D_i) \neq (D_j, C_j)(Ci​,Di​)=(Dj​,Cj​)
  • (A_i, B_i) \neq (C_j, D_j)(Ai​,Bi​)=(Cj​,Dj​)
  • (A_i, B_i) \neq (D_j, C_j)(Ai​,Bi​)=(Dj​,Cj​)

Input

第一行输入三个正整数 N,M,KN,M,K;

接下来 MM 行,每行两个正整数 A_i,B_iAi​,Bi​,表示一对互相关注的用户

再接下来 KK 行,每行两个正整数 C_i,D_iCi​,Di​,表示一对互相拉黑的用户。

Output

输出用空格隔开的 NN 个整数,第 ii 个数表示用户 ii 的“推荐用户”的数量。

样例输入

4 4 1
2 1
1 3
3 2
3 4
4 1

样例输出

0 1 0 1

输入

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

这道题呢,其实就是一个简单的并查集问题,只是多了一个计数。

假设1这个集体中有5个人,统计与1直接相关的2人,那么还剩下三人,接下来就是看这三个人中有几个拉黑的,最后相减输出即可。

ok,下面就是ac的代码(有兴趣的可以试一下带权)

#include<iostream>
using namespace std;
const int N=1e5+10;
int q[N];  // 根节点
int w[N];  //  关注用户
int p[N];  // 拉黑用户
int fl[N];  //  各个节点人数
int find(int x){
	if(q[x]!=x){
		q[x]=find(q[x]);
	}
	return q[x];
}
int main(){
	int n,m,k;
	int a,b;
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++){
		q[i]=i;
		w[i]++;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&a,&b);
		w[a]++;
		w[b]++;
		q[find(a)]=find(b);
	}
	for(int i=1;i<=k;i++){
		cin>>a>>b;
		if(find(a)==find(b)){
			p[a]++;
			p[b]++;
		}
	}
	for(int i=1;i<=n;i++){
		fl[find(i)]++;
	}
	for(int i=1;i<=n;i++){
		if(fl[find(i)]-w[i]-p[i]>0){
			cout<<fl[find(i)]-w[i]-p[i]<<" ";
		}else cout<<"0 ";
	}
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值