日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【CF613D】Kingdom and its Cities(虚树,动态规划)

發布時間:2024/1/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CF613D】Kingdom and its Cities(虚树,动态规划) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題面

洛谷
CF
翻譯洛谷上有啦

題解

每次構建虛樹,首先特判無解,也就是關鍵點中存在父子關系。
考慮 dp d p ,設 f[i] f [ i ] 表示解決 i i 子樹以內的最小點數
再用一個數組g[i]g[i]表示 i i 的子樹中還未阻斷的點數
f[u]=f[v],g[u]=g[v]f[u]=∑f[v],g[u]=∑g[v]
考慮轉移,
如果 u u 不是關鍵點,并且v>1v>1
那么,當前點必須放置, f[u]+=1,g[u]=0 f [ u ] + = 1 , g [ u ] = 0
如果 u u 是關鍵點,此時需要截斷所有子樹中未匹配的點
f[u]+=g[u],g[u]=1f[u]+=g[u],g[u]=1

#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define ll long long #define RG register #define MAX 111111 inline int read() {RG int x=0,t=1;RG char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=-1,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*t; } struct Line{int v,next;}e[MAX<<1]; int h[MAX],cnt=1; inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;} int fa[MAX],dep[MAX],size[MAX],hson[MAX],dfn[MAX],low[MAX],top[MAX],tim; void dfs1(int u,int ff) {fa[u]=ff;dep[u]=dep[ff]+1;size[u]=1;for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(v==ff)continue;dfs1(v,u);size[u]+=size[v];if(size[v]>size[hson[u]])hson[u]=v;} } void dfs2(int u,int tp) {top[u]=tp;dfn[u]=++tim;if(hson[u])dfs2(hson[u],tp);for(int i=h[u];i;i=e[i].next)if(e[i].v!=fa[u]&&e[i].v!=hson[u])dfs2(e[i].v,e[i].v);low[u]=tim; } int LCA(int u,int v) {while(top[u]^top[v])dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];return dep[u]<dep[v]?u:v; } int p[MAX<<1],S[MAX]; bool cmp(int a,int b){return dfn[a]<dfn[b];} int f[MAX],g[MAX],n,Q,K; bool FL=false,vis[MAX]; void DP(int u) {for(int i=h[u];i;i=e[i].next){int v=e[i].v;DP(v);f[u]+=f[v];g[u]+=g[v];}if(vis[u])f[u]+=g[u],g[u]=1;else f[u]+=(g[u]>1),g[u]=(g[u]==1); } int Calc(int rt) {DP(rt);for(int i=1;i<=K;++i)if(vis[p[i]]&&vis[fa[p[i]]])return -1;return f[rt]; } int main() {n=read();for(int i=1,u,v;i<n;++i)u=read(),v=read(),Add(u,v),Add(v,u);dfs1(1,0);dfs2(1,1);memset(h,0,sizeof(h));Q=read();while(Q--){K=read();cnt=1;for(int i=1;i<=K;++i)vis[p[i]=read()]=true;sort(&p[1],&p[K+1],cmp);for(int i=K;i>1;--i)p[++K]=LCA(p[i],p[i-1]);sort(&p[1],&p[K+1],cmp);K=unique(&p[1],&p[K+1])-p-1;for(int i=1,tp=0;i<=K;++i){while(tp&&low[S[tp]]<dfn[p[i]])--tp;Add(S[tp],p[i]);S[++tp]=p[i];}printf("%d\n",Calc(p[1]));for(int i=1;i<=K;++i)h[p[i]]=0,vis[p[i]]=false,f[p[i]]=g[p[i]]=0;}return 0; }

總結

以上是生活随笔為你收集整理的【CF613D】Kingdom and its Cities(虚树,动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。