[BZOJ 4337 BJOI 2015 나무의 동구] 나무 해시.
9479 단어 ACM____모형.판.ACM____하하.희망 하 다.
분류:
Data Structure
Hash
template
1. 제목 링크[BZOJ 4337 BJOI 2015 나무의 동 구성]
2. 제목 설명
설명 트 리 는 흔히 볼 수 있 는 데이터 구조 이다.우 리 는 N 개의 점, N - 1 개의 변 의 연결 무 방향 도 를 나무 라 고 부른다.어떤 점 을 뿌리 로 하고 뿌리 부터 옮 겨 다 니 면 다른 점 은 모두 전구 가 있 고 이 나 무 는 뿌리 가 있 는 나무 가 된다.두 나무 T1 과 T2 에 대해 나무 T1 의 모든 점 을 다시 표시 하여 나무 T1 과 나무 T2 를 똑 같이 만 들 수 있다 면 이 두 나 무 는 같은 구조 이다.같은 형 태 를 갖 고 있다 는 얘 기다.지금, 당신 에 게 M 개의 나무 가 있 습 니 다. 그것들 을 같은 구조 관계 에 따라 몇 개의 등가 류 로 나 누 어 주세요.Input 첫 줄, 정수 M.다음 M 줄 은 줄 마다 몇 개의 정 수 를 포함 하고 나 무 를 표시 합 니 다.첫 번 째 정수 N 은 점 수 를 나타 낸다.다음 N 개의 정 수 는 번호 가 1 에서 N 인 각 점 의 아버지 결점 의 번 호 를 차례대로 나타 낸다.뿌리 노드 의 아버지 노드 번 호 는 0 이다.Output 출력 M 줄 은 줄 마다 하나의 정수 로 모든 트 리 와 같은 구조의 트 리 의 최소 번 호 를 표시 합 니 다.데이터 범위: 100% 데이터 중 1 ≤ N, M ≤ 50.
3. 문제 풀이 사고방식
트 리 해시 템 플 릿 문제 입 니 다.
4. 구현 코드
#include
using namespace std;
typedef long long ll;
typedef long double lb;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair pll;
typedef pair puu;
typedef pair pbb;
typedef vector<int> vi;
const int INF = 0x3f3f3f3f;
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const long double PI = acos(-1.0);
const long double eps = 1e-4;
template<typename T> inline void umax(T &a, T b) { a = max(a, b); }
template<typename T> inline void umin(T &a, T b) { a = min(a, b); }
void debug() { cout << endl; }
template<typename T, typename ...R> void debug (T f, R ...r) { cout << "[" << f << "]"; debug (r...); }
const int MAXN = 100;
const int MAXE = 200;
ull qz[MAXN];
struct Tree {
struct Edge {
int v, next;
} edge[MAXE];
int n, head[MAXN], tot, root;
ull h[MAXN];
void init() {
tot = 0;
memset(head, -1, sizeof(head));
}
inline void add_edge(int u, int v) {
edge[tot] = Edge{v, head[u]};
head[u] = tot ++;
}
void read() {
scanf("%d", &n);
int fa;
for (int i = 1; i <= n; ++i) {
scanf("%d", &fa);
if (fa == 0) root = i;
else {
add_edge(fa, i);
add_edge(i, fa);
}
}
}
int siz[MAXN], mx_sum, g[MAXN], g_cnt;
void dfs(int u, int fa) {
int v, temp = 0;
siz[u] = 1;
for (int i = head[u]; ~i; i = edge[i].next) {
v = edge[i].v;
if (v == fa) continue;
dfs(v, u);
siz[u] += siz[v];
umax(temp, siz[v] + 1);
}
umax(temp, n - siz[u] + 1);
if (temp < mx_sum) {
mx_sum = temp;
g_cnt = 0;
g[g_cnt ++] = u;
} else if (mx_sum == temp) {
g[g_cnt ++] = u;
}
}
void hash_dfs(int u, int fa) {
int v;
h[u] = siz[u] = 1;
for (int i = head[u]; ~i; i = edge[i].next) {
v = edge[i].v;
if (v == fa) continue;
hash_dfs(v, u);
h[u] += h[v] ^ qz[siz[v]];
siz[u] += siz[v];
}
h[u] *= qz[n - siz[u] + 1];
}
ull hashV() {
mx_sum = INF; g_cnt = 0;
dfs(root, 0);
ull hv = 1;
for(int i = 0; i < g_cnt; ++i) {
hash_dfs(g[i], 0);
hv *= h[g[i]];
}
return hv;
}
} tr;
int main() {
#ifdef ___LOCAL_WONZY___
freopen ("input.txt", "r", stdin);
#endif // ___LOCAL_WONZY___
for (int i = 0; i < MAXN; ++i) qz[i] = (ull) rand() * rand();
int m;
while (~scanf("%d", &m)) {
mapint > mp;
for (int i = 1; i <= m; ++i) {
tr.init();
tr.read();
ull hv = tr.hashV();
if (!mp[hv]) mp[hv] = i;
printf("%d
", mp[hv]);
}
}
#ifdef ___LOCAL_WONZY___
cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;
#endif // ___LOCAL_WONZY___
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
세계 최고의 방화벽 Look n Stop 중국어 버 전Look n Stop 은 세계 최고의 방화벽 으로 불 린 다!같은 종류의 제품 에 비해 가장 두 드 러 진 강력 한 기능 과 남 다른 특징 을 가지 고 있 으 며 기능 평가 가 유명 방화벽 에서 가장 강 할 뿐만 아...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.