poj 3659 樹形dp(樹上的最小支配集)

2021-07-04 22:35:12 字數 834 閱讀 4871

題意:求樹的最小支配集。

思路:動態規劃。一開始每個點只取了兩個變數,表示在以其為根的子樹中選擇和不選擇該點的最少點數。由一組資料(6個點的路徑)發現了問題,考慮第3個點的時候,如果不選擇此點,那麼第4個點必須要選取,實際上這是不必的。該組資料的最優解是選擇第2和第5個點。

dp1[x]表示選擇第x個點。

dp0[x][0]表示不選擇第x個點,而且該點並沒有被兒子所覆蓋。

dp0[x][1]表示不選擇第x個點,但是該點已經被兒子所覆蓋了,即至少有乙個兒子被選擇。

如此一來就對了,轉移方程見**,懶得寫了。

#include #include #include #include #include #include using namespace std;

#define clc(s,t) memset(s,t,sizeof(s))

#define inf 0x3fffffff

#define n 10005

struct edgee[n<<1];

int first[n],n,top;

int dp1[n],dp0[n][2];

void add(int x,int y)

void dfs(int x,int fa)

}dp1[x] ++;

if(son)

dp0[x][1] = 1;

}int main(){

int i,a,b;

clc(first,-1);

clc(dp1, 0);

clc(dp0, 0);

top = 0;

scanf("%d",&n);

for(i = 1;i

每日一題 POJ 2486 樹形dp 樹上揹包

並不難寫,關鍵是要想清楚。樹形dp的第乙個比較完整寫完的題,是比較經典的題,來紀念一下。一開始沒想清楚是因為對揹包問題的滾動陣列優化的理解不夠,自然在樹上的問題也沒思考清楚。同時因為每個case過後忘記清零,導致re了一發,以後需要注意。dpr是回到該點,nr是不回到該點,轉移方程如 ac 耗時18...

POJ 1655 樹的重心(樹形 DP)

balancing act 定義乙個點的 平衡 值等於將這個點拆去後,形成的子樹中節點數的最大值。求一棵樹 平衡 值最小的點。這其實就是樹的重心的概念,通過樹形 dp 很容易解決。當去掉抹一點後,它下面的子樹的節點個數通過 dfs 可以得到,它上面的子樹的節點個數等於總節點個數減去它本身及其子節點的...

poj1655 樹的重心 樹形dp

樹的重心定義為 找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡.處理處每個節點的孩子有幾個,和樹的大小就好了。include include include include include define inf 99999999 usi...