HDU 4275 Color the Tree(트 리 동 구성)
4239 단어 color
제목:n 개 노드 의 나 무 를 주 고 m 가지 색상 이 있 습 니 다.--다른 염색 방안 은 얼마나 되 나.
사고:본 문 제 는 먼저 대칭 적 인 상황 을 해결 해 야 한다.인터넷 에서 나무의 중심 을 찾 아야 한다 고 말 했다.즉,나무의 가장 긴 길 을 찾 는 것 이다.가장 긴 길 은 홀수 이 고 중간 에 한 노드 를 뿌리 노드 로 한다.그렇지 않 으 면 중간 에 한 노드 를 추가 하여 뿌리 노드 로 서 양쪽 의 가장 긴 길 을 똑 같이 한다.그 다음 에 나무 형 DP,ans[u]는 u 를 뿌리 노드 로 하 는 서브 트 리 의 전체적인 염색 방안 을 나타 내 고 hash[u]는 u 를 뿌리 노드 로 하 는 서브 트 리 의 구 조 를 저장 합 니 다.u 노드 를 설정 하면 k 키 노드,v1,v2...vk 가 있 습 니 다.먼저 하위 노드 를 hash 값 에 따라 정렬 합 니 다.그러면 같은 구조의 하위 나 무 는 정렬 한 후에 인접 합 니 다.x 키 트 리 와 같은 구 조 를 설정 하면 이 x 키 트 리 의 전체적인 염색 방안 은 C(ans[v]+x-1,x)입 니 다.이 식 이 어떻게 밀어 내 는 지 저도 잘 모 르 겠 습 니 다.어쨌든 ans[v]=2,x=2 를 시험 해 본 것 이 옳 습 니 다.그 다음 에 이 를 곱 하면 u 노드 의 ans 값 을 얻 고 u 노드 의 hash 값 은 하위 노드 의 hash 값 Hash 에서 얻 을 수 있 습 니 다.
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct node
{
int v,next;
};
struct Node
{
__int64 hash,ans;
};
const __int64 mod=1000000007;
const __int64 P=10003;
const __int64 Q=100000037;
node edges[200005];
Node q[50005];
int head[50005],e,E,M,MM,C,f[50005],dp[50005],n;
__int64 hash[100005],ans[100005],p[100005],son[50005];
void Add(int u,int v)
{
edges[e].v=v;
edges[e].next=head[u];
head[u]=e++;
}
__int64 POW(__int64 a,__int64 b)
{
__int64 ans=1;
while(b)
{
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
__int64 cal(int n,int m)
{
if(n==m) return 1;
__int64 n1=1,n2=p[m],i;
for(i=1;i<=m;i++) n1=n1*(n-i+1)%mod;
return n1*POW(n2,mod-2)%mod;
}
int cmp(Node a,Node b)
{
return a.hash<b.hash;
}
void init()
{
int i;
p[1]=1;
for(i=2;i<=100000;i++) p[i]=p[i-1]*i%mod;
}
int DFS(int u,int pre)
{
int m1=0,m2=0,i,v,t;
for(i=head[u];i!=-1;i=edges[i].next)
{
v=edges[i].v;
if(v==pre) continue;
t=DFS(v,u);
if(t>m1) m2=m1,m1=t,f[u]=i;
else if(t>m2) m2=t;
}
if(M<m1+m2) MM=u,M=m1+m2;
dp[u]=m1;
return dp[u]+1;
}
void DFS1(int u,int pre)
{
int i,j,v;
son[u]=0;
for(i=head[u];i!=-1;i=edges[i].next)
{
v=edges[i].v;
if(v==pre||i==E||i==(E^1)) continue;
ans[v]=C;
DFS1(v,u);
son[u]++;
}
if(!son[u])
{
hash[u]=1;
return;
}
for(j=0,i=head[u];i!=-1;i=edges[i].next)
{
v=edges[i].v;
if(v==pre||i==E||i==(E^1)) continue;
q[j].hash=hash[v];
q[j++].ans=ans[v];
}
sort(q,q+son[u],cmp);
hash[u]=977872;
for(i=0;i<son[u];i++)
{
for(j=i;j<son[u]&&q[i].hash==q[j].hash;j++)
{
hash[u]*=P;
hash[u]^=q[j].hash;
hash[u]%=mod;
}
j--;
ans[u]*=cal(q[i].ans+j-i,j-i+1);
ans[u]%=mod;
i=j;
}
}
int main()
{
init();
while(scanf("%d%d",&n,&C)!=-1)
{
memset(head,-1,sizeof(head));
e=2;
int i,u,v;
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
Add(u,v);
Add(v,u);
}
M=-1;DFS(1,-1);
if(M&1)
{
while(dp[MM]*2>M+1) MM=edges[f[MM]].v;
E=f[MM];
Add(MM,n+1);
Add(n+1,MM);
Add(edges[f[MM]].v,n+1);
Add(n+1,edges[f[MM]].v);
MM=n+1;
ans[MM]=1;
}
else
{
E=0;
while(dp[MM]*2>M) MM=edges[f[MM]].v;
ans[MM]=C;
}
DFS1(MM,-1);
printf("%I64d
",ans[MM]);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C++ Builder XE4 > TStringGrid 및 TCalendar > TStringGrid에 TCalendar 문자열을 복사하여 배경색을 변경하는 구현운영 환경 처리 개요 TCalendar와 TStringGrid가 있습니다 TStringGrid에 TCalendar 문자열을 복사합니다. TStringGrid의 일부 셀의 배경색 변경 구현 Unit1.h Unit1.c...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.