jzoj1029-电子眼【树形dp】
生活随笔
收集整理的這篇文章主要介紹了
jzoj1029-电子眼【树形dp】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
大意
一個n個點n條邊的無向圖,在一個點安電子眼就能監視到連接它的邊,要求所有的邊都被監視求安放電子眼的最少數目。
解題思路
就是沒一條邊的兩頭都至少得有一個電子眼。我們先假設它是n-1條邊的環
用f[i]f[i]來表示不在這個點放電子眼的最少電子眼數目
用g[i]g[i]來表示在這個點放電子眼的最少電子眼數目
然后我們可以進行推算,一個點不放電子眼,那么它的子節點就一點要放。
如果一個地方放電子眼,那么它的子節點就可放可不放
g[i]=max{f[son],g[son]}g[i]=max{f[son],g[son]}
然后我們在處理環。發現環時我們可以不去進行dp該點但是取該點的結果。
代碼
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; struct node{int to,next; }a[200001]; int ls[100001],g[100001],f[100001],tot,n,k,x,maxs; bool v[100001]; void addl(int x,int y) {a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot; } void dp(int x) {int s1=1,s2=0;for (int i=ls[x];i;i=a[i].next){if (!v[a[i].to]){v[a[i].to]=1;//標記dp(a[i].to);//dps1+=min(g[a[i].to],f[a[i].to]);//動態轉移}s2+=g[a[i].to];//處理環(因為父節點沒有值所以不會有影響)}g[x]=s1;f[x]=s2;//保證搜完子節點之前父節點沒有值 } int main() {scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d",&k);for (int j=1;j<=k;j++)scanf("%d",&x),addl(i,x);}v[1]=1; dp(1);printf("%d",min(f[1],g[1]));//輸出 }總結
以上是生活随笔為你收集整理的jzoj1029-电子眼【树形dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果电脑退出ID账号的方法苹果电脑如何删
- 下一篇: jzoj1503-体育场【带权并查集】