문제 : icpc.me/4195
친구 관계가 생길 때 마다 가입한 두사람의 친구 네트워크에 몇명이 있는지 구하는 문제이다.
문제의 답은 union_find를 통하여 쉽게 구해줄 수 있지만 string으로 들어오는 입력 때문에 좌표 압축이나 map을 이용한 테크닉이 필요하다.
-좌표압축 이용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include <cstdio> #include <algorithm> #include <string> #include <iostream> #include <map> #include <vector> using namespace std; int par[200010]; int t, n; int num[200010]; vector<string> vn; vector<pair<string, string>> vt; int find(int x) { if (x == par[x]) return x; return par[x] = find(par[x]); } int merge(int x, int y) { x = find(x); y = find(y); if (x != y) { par[x] = y; num[y] += num[x]; num[x] = 1; } return num[y]; } int main() { scanf("%d", &t); while (t--) { int ct = 1; vt.clear(); vn.clear(); scanf("%d", &n); for (int i = 0; i < 2 * n; i++) { par[i] = i; num[i] = 1; } for (int i = 0; i < n; i++) { char a[21], b[21]; scanf("%s %s", &a, &b); vt.push_back({ a,b }); vn.push_back(a); vn.push_back(b); } sort(vn.begin(), vn.end()); vn.erase(unique(vn.begin(), vn.end()), vn.end()); for (int i = 0; i < n; i++) { int x = lower_bound(vn.begin(), vn.end(), vt[i].first) - vn.begin(); int y = lower_bound(vn.begin(), vn.end(), vt[i].second) - vn.begin(); printf("%d\n", merge(x, y)); } } return 0; } | cs |
-맵 이용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <cstdio> #include <algorithm> #include <string> #include <iostream> #include <map> using namespace std; int par[200010]; int t, n; int num[200010]; char a[21], b[21]; int find(int x) { if (x == par[x]) return x; return par[x] = find(par[x]); } int merge(int x, int y) { x = find(x); y = find(y); if (x != y) { par[x] = y; num[y] += num[x]; num[x] = 1; } return num[y]; } int main() { scanf("%d", &t); while (t--) { int ct = 1; map<string, int> mp; scanf("%d", &n); for (int i = 1; i <= 2 * n; i++) { par[i] = i; num[i] = 1; } for (int i = 0; i < n; i++) { scanf("%s %s", &a, &b); if (mp.count(a) == 0) mp[a] = ct++; if (mp.count(b) == 0) mp[b] = ct++; printf("%d\n", merge(mp[a], mp[b])); } } return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)5419 북서풍 (7) | 2017.01.10 |
---|---|
BOJ)1849 순열 (0) | 2017.01.10 |
BOJ)9345 디지털 비디오 디스크(DVDs) (0) | 2017.01.10 |
BOJ)1321 군인 (1) | 2017.01.10 |
BOJ)10868 최소값 (0) | 2017.01.10 |