홍시홍의 프로그래밍

[백준 4195] 친구 네트워크 본문

알고리즘 문제풀이/백준

[백준 4195] 친구 네트워크

홍시홍 2020. 1. 14. 23:28

https://www.acmicpc.net/problem/4195

 

4195번: 친구 네트워크

문제 민혁이는 소셜 네트워크 사이트에서 친구를 만드는 것을 좋아하는 친구이다. 우표를 모으는 취미가 있듯이, 민혁이는 소셜 네트워크 사이트에서 친구를 모으는 것이 취미이다. 어떤 사이트의 친구 관계가 생긴 순서대로 주어졌을 때, 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하시오. 친구 네트워크란 친구 관계만으로 이동할 수 있는 사이를 말한다. 입력 첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계

www.acmicpc.net

 

요구사항

주어진 2명의 친구 네트워크의 총합을 출력한다

 

풀이

1. 해싱을 이용해 이름을 저장한다

2. hash_size를 고유 값으로 받는다

3. 두 이름을 disjoint하여 부모 값을 찾는다

 

#include <iostream>

using namespace std;
const int HASH_SIZE = 10000;
const int PN = 23;
int table[10000][100];
char hash_raw[100001][30];

int hash_size = 0;
int parent[100001];
int num[100001];
unsigned int get_key(char str[]) {
	unsigned int key = 0, p = 1;
	for (int i = 0; str[i] != 0; i++) {
		key += (str[i] * p);
		p *= PN;
	}
	return key%HASH_SIZE;
}
void add(char str[]) {
	unsigned int key = get_key(str);
	int i = 0;
	for (i = 0; str[i] != 0; i++) {
		hash_raw[hash_size][i] = str[i];
	}
	hash_raw[hash_size][i] = 0;

	int &size = table[key][0];
	table[key][++size] = hash_size++;
}
int my_strcmp(char a[], char b[]) {
	int i = 0;
	int j = 0;
	while (a[i]) {
		if (a[i++] != b[j++]) {
			i--, j--;
			break;
		}
	}
	return a[i] - b[j];
}
int contain(char str[]) {
	unsigned int key = get_key(str);
	int size = table[key][0];
	for (int i = 1; i <= size; i++) {
		int pos = table[key][i];
		if (my_strcmp(hash_raw[pos], str) == 0) {
			return pos;
		}
	}
	return 0;
}
int Find(int x) {
	if (parent[x] == x) return x;
	return parent[x] = Find(parent[x]);
}

int Union(int x, int y) {
	x = Find(x);
	y = Find(y);
	//cout << "FF" << endl;
	if (x < y) {
		parent[x] = y;
		num[y] += num[x];
		num[x] = 1;
		return num[y];
	}
	else if (x>y){
		parent[y] = x;
		num[x] += num[y];
		num[y] = 1;
		return num[x];
	}
	else {
		return num[x];
	}
}
int main() {
	int t;
	scanf("%d", &t);
	for (int tc = 1; tc <= t; tc++) {
		int n;
		scanf("%d", &n);
		hash_size = 0;
		for (int i = 0; i < 10000; i++) {
			table[i][0] = 0;
		}
		for (int i = 0; i <= n; i++)
		{
			parent[i] = i;
			num[i] = 1;
		}

		for (int i = 0; i < n; i++)
		{
			char ch1[21], ch2[21];
			scanf(" %s %s", ch1, ch2);
			int a = contain(ch1);
			int b = contain(ch2);
			if (a == 0) {
				add(ch1);
				a = contain(ch1);
			}
			if (b == 0) {
				add(ch2);
				b = contain(ch2);
			}
			//	cout << "A" << endl;
			//	cout << "A" << a << "B" << b << endl;
			printf("%d\n", Union(a, b));

		}
	}
}

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 3020] 개똥벌레  (0) 2020.01.14
[백준 2959] 거북이  (0) 2020.01.14
[백준 5052] 전화번호 목록(20200514 수정)  (0) 2020.01.14
[백준 11652] 카드  (0) 2020.01.14
[백준 3047]ABC  (0) 2020.01.14
Comments