jzoj5248-[NOIP2017提高A组模拟8.10]花花的聚会【倍增,树形dp】
生活随笔
收集整理的這篇文章主要介紹了
jzoj5248-[NOIP2017提高A组模拟8.10]花花的聚会【倍增,树形dp】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
題目鏈接:https://gmoj.net/senior/#main/show/5248
題目大意
nnn個(gè)點(diǎn)的一棵樹,有mmm張票(v,k,w)(v,k,w)(v,k,w)表示可以在點(diǎn)vvv買,可以走kkk步以內(nèi),價(jià)格為www。
一個(gè)時(shí)間只能有一個(gè)票,每次詢問一個(gè)點(diǎn)到根節(jié)點(diǎn)需要的最少票錢。
解題思路
設(shè)fif_{i}fi?表示iii到根節(jié)點(diǎn)的價(jià)錢,然后vectorvectorvector存票,倍增轉(zhuǎn)移即可。
時(shí)間復(fù)雜度O(nlog?n)O(n\log n)O(nlogn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define mp(x,y) make_pair(x,y) using namespace std; const int N=1e5+10,T=20; struct node{int to,next; }a[N*2]; int n,m,tot,ls[N],f[N][T],g[N][T]; vector<pair<int,int> > q[N]; void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return; } void dfs(int x,int fa){for(int i=0;i<q[x].size();i++){int now=fa,k=q[x][i].first,w=q[x][i].second;for(int i=T-1;i>=0;i--)if((k>>i)&1)g[x][0]=min(g[x][0],g[now][i]+w),now=f[now][i];}for(int i=1;i<T;i++)g[x][i]=min(g[x][i-1],g[f[x][i-1]][i-1]),f[x][i]=f[f[x][i-1]][i-1];for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa)continue;f[y][0]=x;dfs(y,x);}return; } int main() {scanf("%d%d",&n,&m);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);addl(x,y);addl(y,x);}for(int i=1;i<=m;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);q[x].push_back(mp(y,w));}memset(g,0x3f,sizeof(g));g[1][0]=0;dfs(1,1);scanf("%d",&m);while(m--){int x;scanf("%d",&x);printf("%d\n",g[x][0]);} }總結(jié)
以上是生活随笔為你收集整理的jzoj5248-[NOIP2017提高A组模拟8.10]花花的聚会【倍增,树形dp】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 51nod1551-集合交易【hall定
- 下一篇: 基于 bZ4X,小马智行与丰田合作首款纯