华为实习4.10机考第二题C++代码

考的是简单的并查集

这道题考法就是并查集,若两个图片相似度大于0,则将他们放到一个家族中,同时维护家族的相似度总和。

注意 M 矩阵是对称矩阵,所以需要避免重复维护相似度,因此可以只针对 M 矩阵的下三角矩阵或上三角矩阵中的连接块,计算相似度总和;或考虑整个 M 矩阵,然后相似度总和除以2。

代码如下:

#include<iostream>
#include<unordered_set>
#include<vector>
#include<algorithm>
using namespace std;

const int N = 910;

int f[N], sum[N] , M[N][N];

int find(int x){
	if(x != f[x]) f[x] = find(f[x]);
	return f[x];
}

bool cmp(int x,int y){
	return x > y;
}

int main(){
	unordered_set<int> Set;
	vector<int> v;
	int n ;
	cin >> n ;
	
	for(int i = 1 ; i <= n ; i ++) {
		f[i] = i;
		sum[i] = 0;
	}
	
	for(int i = 1 ; i <= n ; i ++){
		for(int j = 1 ; j <= n ; j ++){
			scanf("%d",&M[i][j]);
		}
	}
	
	for(int i = 1 ; i <= n ; i ++){
		for(int j = 1 ; j <= i ; j ++){
			if(M[i][j]) {
				int t = sum[find(i)] + M[i][j];
				f[find(i)] = find(j);
				sum[find(i)] += t;
			}
		}
	}
	
	for(int i = 1 ; i <= n ; i ++) Set.insert(sum[find(i)]);
	
	for(auto it: Set) v.push_back(it);
	
	sort(v.begin(),v.end(),cmp);
	
	for(int i = 0 ; i < v.size() ; i ++) printf("%d ",v[i]);
	
	return 0;
}

测试用例:
输入:

5
0 0 50 0 0
0 0 0 25 0
50 0 0 0 15
0 25 0 0 0
0 0 15 0 0

输出:

65 25
posted @ 2024-04-16 14:42  时光以北  阅读(18)  评论(0编辑  收藏  举报