HDU 5416 CRB and Tree(트리 DP)
제목:
한 나무에 함수 F(u, v)를 주어 u에서 v까지의 경로의 변의 값이 다르거나 일어나는 결과를 표시한 다음에 F(u, v)=s가 몇 가지 상황이 있는지 구한다.
분석:
dp[u]를 설정하면 점 u가 루트 노드의 경로가 다르거나 일어나는 값을 표시하고 F(u, v)=dp[u]^dp[v]를 설정합니다. 우리는 cnt[x]를 설정하면 dp[u]=x의 상황이 몇 가지가 있는지 나타냅니다. 그러면 s가 0과 같지 않을 때 ans[s]=sigma(cnt[i]*cnt[s^i])를 표시하고 s=0의 상황을 주의하십시오.
코드는 다음과 같습니다.
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 1e6+10;
typedef long long LL;
int dp[maxn];
int head[maxn],ip;
LL cnt[maxn];
int n;
struct nod{
int to,next,w;
}edge[maxn];
bool vis[maxn];
void init(){
ip=0;
memset(head,-1,sizeof(head));
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
}
void add(int u,int v,int w){
edge[ip].to=v;
edge[ip].w=w;
edge[ip].next=head[u];
head[u]=ip++;
}
int mmax;
void dfs(int u,int pre,int val){
for(int i=head[u];i!=-1;i=edge[i].next){
int v= edge[i].to;
if(v==pre) continue;
if(edge[i].w^val>mmax)
mmax = edge[i].w^val;
cnt[edge[i].w^val]++;
dfs(v,u,val^edge[i].w);
}
}
int main()
{
int t,m;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=0;i<n-1;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
mmax = 0;
dfs(1,1,0);
scanf("%d",&m);
cnt[0]++;
for(int i=0;i<m;i++){
int s;
scanf("%d",&s);
LL ans = 0;
for(int j=0;j<maxn;j++){
if((s^j)==j) ans=ans+(cnt[j]*(cnt[j]-1));
else ans = ans=ans+cnt[j]*cnt[s^j];
}
ans=ans/2;
if(s==0) ans=ans+n;
printf("%I64d
",ans);
}
}
return 0;
}
/***
45
7
1 2 1
1 3 1
1 4 1
4 5 2
3 6 2
2 7 2
1123
1
2
3
0
**/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.