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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ4557:[JLOI2016/SHOI2016]侦察守卫——题解

發布時間:2023/12/9 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ4557:[JLOI2016/SHOI2016]侦察守卫——题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

https://www.lydsy.com/JudgeOnline/problem.php?id=4557

小R和B神正在玩一款游戲。這款游戲的地圖由N個點和N-1條無向邊組成,每條無向邊連接兩個點,且地圖是連通的。換句話說,游戲的地圖是一棵有N個節點的樹。

游戲中有一種道具叫做偵查守衛,當一名玩家在一個點上放置偵查守衛后,它可以監視這個點以及與這個點的距離在D以內的所有點。這里兩個點之間的距離定義為它們在樹上的距離,也就是兩個點之間唯一的簡單路徑上所經過邊的條數。在一個點上放置偵查守衛需要付出一定的代價,在不同點放置守衛的代價可能不同。

現在小R知道了所有B神可能會出現的位置,請你計算監視所有這些位置的最小代價。

dp狀態很好想,但是這個式子我菜我是真的推不出來,其他的巨佬切題的速度嘆為觀止,只能感嘆我的智商擺在這里。

參考:https://www.luogu.org/blog/zcysky/solution-p3267

一眼是個樹形dp,二眼$d$很小,可以直接做成一維狀態,那么直接設$f[i][j]$為$i$子樹從$i$往下$j$層都沒有覆蓋的代價,$g[i][j]$為$i$的子樹全覆蓋,往上還可以覆蓋$j$層的代價。二者正好是互補的。

(PS:層數也包括i本身,換句話說,$j=0$時$i$并沒有被覆蓋,我在這里糾結了很久。)

(PPS:既然$g[i][j]$都可以覆蓋上$j$層,那它也能覆蓋下$j$層。)

之后對于dp式子慢慢剖析因為我自己都云里霧里的

邊界就是當點$u$為關鍵點時$f[u][0]=g[u][0]=w[u]$這個點一定是要放一個的,如果不是的話顯然我們就不需要放了,初值為0。

?

初始化就不說了。

對于每個兒子結點v,我們有:

$g[u][j]=min(g[u][j]+f[v][j],g[v][j+1]+f[u][j+1])$(所以明白f和g是互補的才能看懂)

當然也有可能出現這種的:$g[u][j]=min(g[u][j],g[u][j+1])$

推完g來推f,首先$f[u][0]=g[u][0]$因為此時二者狀態等價。

然后顯然的,$f[u][j]+=f[v][j-1]$

以及也有可能出現這種的:$f[u][j]=min(f[u][j],f[u][j-1])$

(所以其實核心還是在狀態含義上而非式子,含義搞懂式子就很顯然了。)

#include<map> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<vector> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=5e5+5; const int D=21; const int INF=1e9; inline int read(){int X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } struct node{int to,nxt; }e[N*2]; int n,d,m,cnt,head[N],w[N]; int f[N][D],g[N][D]; bool im[N]; inline void add(int u,int v){e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt; } void dfs(int u,int fa){if(im[u])f[u][0]=g[u][0]=w[u];for(int i=1;i<=d;i++)g[u][i]=w[u];g[u][d+1]=INF;for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;if(v==fa)continue;dfs(v,u);for(int j=d;j>=0;j--)g[u][j]=min(g[u][j]+f[v][j],g[v][j+1]+f[u][j+1]);for(int j=d;j>=0;j--)g[u][j]=min(g[u][j],g[u][j+1]);f[u][0]=g[u][0];for(int j=1;j<=d+1;j++)f[u][j]+=f[v][j-1];for(int j=1;j<=d+1;j++)f[u][j]=min(f[u][j],f[u][j-1]);} } int main(){n=read(),d=read();for(int i=1;i<=n;i++)w[i]=read();m=read();for(int i=1;i<=m;i++)im[read()]=1;for(int i=1;i<n;i++){int u=read(),v=read();add(u,v);add(v,u);}dfs(1,0);printf("%d\n",f[1][0]);return 0; }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

轉載于:https://www.cnblogs.com/luyouqi233/p/9193761.html

總結

以上是生活随笔為你收集整理的BZOJ4557:[JLOI2016/SHOI2016]侦察守卫——题解的全部內容,希望文章能夠幫你解決所遇到的問題。

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