題意:在一棵樹上每個點都有價值,在這些點裡找出一些互不相連的點並使其價值之和最大。
標籤是樹形dp,於是我第一次就嘗試著用dp做,然而在讀入的時候這個題挖了個坑,讀入a,b,b是a的上司,然而我二話沒說就把a當做了b的上司,結果就做不出來了。然後第二次我就「think diffierent」,用了一種貪心+bfs的做法,一掃題解裡樹形dp的烏煙瘴氣,而且速度也不慢,雖然這時候我在讀入的坑里,但這個做法並不受邊的方向的影響。在a掉這個題之後我找神犇交談,發現了我讀入上的錯誤,之後明白怎麼用樹形dp了。下面介紹這兩種做法。
一、貪心+bfs
記錄每一層的總分值(不記錄小於0的),然後就只有兩種交叉選層方法(例:有5層,第一種:1,3,5;第二種:2,4;),這兩種都滿足沒有直接相連的點,在這兩種裡選乙個最大的就行了。
#include
#include
#include
using
namespace
std;
int max(int a,int b)
vector
dui[6010],bian[6010];//dui記錄了每一層的點,bian表示鄰接表記錄每個點所連的邊。
int w[6010],fen[6010]=; //w表示每個點的歡樂指數(分),fen表示每一層的總分值(不帶小於0的)。
bool f[6010]=,vis[6010]=;
int n;
int main()
int a,b;
for (int i=1;i<=n-1;i++)
for (int i=1;i<=n;i++)
if (!f[i])
int tot=0;
bool ff;do}
}}while (ff);
int ans1=0,ans2;
for (int i=1;i<=tot;i+=2)
ans1+=fen[i];
ans2=sum-ans1;
cout
0;}
二、樹形dp用乙個二維陣列dp[i][0]表示不選i這個點時以i為根的樹所能得到的最大分值,dp[i][1]表示選i的時候。那麼dp[i][0]賦值為每個兒子dp[a][0]和dp[a][1]的最大值的和,dp[i][1]就賦值為所有兒子dp[a][0]的和就行了。
一遍dfs,回溯時用兒子的dp值求出父親的dp值。
#include
#include
#include
using
namespace
std;
int max(int a,int b)
vector
bian[6010];
int w[6010],dp[6010][2];
bool f[6010]=;
int n;
void dfs(int d)
}int main()
int a,b;
for (int i=1;i<=n-1;i++)
for (int i=1;i<=n;i++)
if (!f[i])
}
codevs1380 沒有上司的舞會
題目描述 description ural大學有n個職員,編號為1 n。他們有從屬關係,也就是說他們的關係就像一棵以校長為根的樹,父結點就是子結點的直接上司。每個職員有乙個快樂指數。現在有個周年慶宴會,要求與會職員的快樂指數最大。但是,沒有職員願和直接上司一起與會。輸入描述 input descri...
CODEVS 1380沒有上司的舞會
include include include using namespace std vector sons 6010 int mmax int a,int b if f cur state 0 return f cur state int sum 0 for int i 0 iint tryso...
codevs1380沒有上司的舞會
題目描述 ural大學有n個職員,編號為1 n。他們有從屬關係,也就是說他們的關係就像一棵以校長為根的樹,父結點就是子結點的直接上司。每個職員有乙個快樂指數。現在有個周年慶宴會,要求與會職員的快樂指數最大。但是,沒有職員願和直接上司一起與會。輸入格式 第一行乙個整數n。1 n 6000 接下來n行,...