í’€ì�´ ¶
예 1)) 분기계수 2ì—� 깊ì�´ 2ì�¸ 컴플리트 트리ì�˜ ëª¨ë“ ë…¸ë“œì�˜ 개수 = (2^(2+1) - 1)/(2-1) = 7ê°œ
예 2)) 예 1번ì—� ì�´ì–´ì„œ 7ê°œì—�서 루트 1개를 뺀 3개를 분기계수 2ì—� 맞게 3개씩 3개씩 ë‚˜ëˆ ì•¼ 한다.
즉 �것� combination(루트를 뺀 � 노드 수, 루트를 뺀 � 노드 수/분기계수) 임� 알 수 있다.
combination(6, 6/2)ì�´ ë�˜ê³ ì�´ë ‡ê²Œ 뽑ì�€ 것ì�„ ë‘�가지로 세울 수 있으므로 2!ì�˜ 줄세우는 방법ì�„ 곱해준다.
깊ì�´ 1ì—�서ì�˜ 경우ì�˜ 수 = 분기계수! * combination(루트를 뺀 ì´� 노드수, 루트를 뺸 ì´� 노드수/분기계수)
ì�´ ê³¼ì • 다ì�Œì—� 깊ì�´ 2ì�˜ 트리는 깊ì�´ 1ì�˜ 노드를 루트로 하는 ë˜� 다른 하나ì�˜ 컴플리트 트리로 ìƒ�ê°�하여 위ì�˜ ê³µì‹�ì�„ 반복하면 ë�œë‹¤.
코드 ¶
~cpp
#include <iostream>
#include <cmath>
#include "BigInteger.h"
using BigMath::BigInteger;
int depth, level, nodeNum, temp, templevel, tempdepth, select, i;
BigInteger labelingNum;
BigInteger factorial[3300];
void InitFactorial()
{
factorial[1] = 1;
for(i=2; i<3300; i++)
factorial[i] = factorial[i-1] * i;
}
BigInteger combination(int a, int b)
{
if(a==b)
return 1;
return factorial[a]/(factorial[b]*factorial[a-b]);
}
BigInteger getCompleteTreeLabeling(int l, int d)
{
labelingNum=1;
tempdepth=1;
if(l==1)
return 1;
nodeNum = (pow(l, d+1)-1)/(l-1);
nodeNum--;
while(true)
{
if(nodeNum==0)
return labelingNum/l;
select = nodeNum/l;
labelingNum = labelingNum * factorial[l] * combination(nodeNum, select);
nodeNum = select-1;
tempdepth++;
}
}
int main()
{
InitFactorial();
while(cin>>level>>depth)
cout << getCompleteTreeLabeling(level, depth) << endl;
return 0;
}










