2019瀋陽網賽樹形dp

2022-05-23 22:24:14 字數 1670 閱讀 2333

2019瀋陽網路賽d題

樹形dp。一棵樹,求任意兩個點的距離之和。u-v和v-u算兩次。兩點之間的距離分為三類,模3等於0,1,2三類,最後輸出這三類的總和。

第一種方法。直接累加。遍歷到乙個點的時候。先計算答案。答案加上所有已經遍歷過得點到他的距離之和。同時該點也要加上這個值,同時要加上數量。每次先搜到底統計往下遍歷的值,然後回溯的時候統計

回溯的值。因為每次只計算了之前的點到他的距離之和,所以最後的結果要乘以2,因為u-v與v-u算兩次。

每次加的時候先計算當前點前乙個點到他的距離,及0+該邊的邊權。然後在按0,1,2來累加,如果為零表示沒有,就不累加。

#include #define ll long long

using

namespace

std;

const

int n = 1e4 + 5

;const

int mod = 1e9 + 7

;typedef pair

pii;

intn;

vector

g[n];

ll ans[

4];//結果陣列

struct

node node[n];

void dfs(int u, int

f) dfs(v, u);

node[u].valup[w%3] = (node[u].valup[w%3] + w) %mod;

node[u].cntup[w%3] = (node[u].cntup[w%3] + 1) %mod;

for(int j = 0; j < 3; j++)

}}int

main()

for(int i = 1; i < n; i++)

dfs(

0, -1

);

for(int i = 0; i < 3; i++)

}return0;

}

算貢獻的方法。

#include #include 

using

namespace

std;

#define ll long long

const

int n=100010

;const ll mod = 1e9 + 7

;int

n,root;

intnex[n],tot,fir[n],to[n],len[n];

ll f[n][

3],g[n][3],num[n][3

];void build(int x,int y,int

z)void mo(ll &x)

void dfs(int x,int

fa) }

for(int i=0;i<3;i++)

for(int i=fir[x];i;i=nex[i])}}

}int

main()

dfs(

1,0);

printf(

"%lld %lld %lld\n

",f[1][0],f[1][1],f[1][2

]); }

return0;

}/**3

0 1 2

0 2 3

*/

長春和瀋陽網路賽的DP

你能看得出來每個數字需要幾根火柴。給你n 大於等於5小於等於500 根火柴,問能擺出幾種a b c,其中a b c沒有前導零的正整數。答案mod m input 4 12 1000000007 17 1000000007 20 1000000007 147 1000000007 output cas...

CSP模擬賽 Repulsed(樹形DP)

w 的 焰就要被熄滅了。簡便起 假設 w 的內 是 棵 n 1 條邊,n 個節點的樹。現在你要在每個節點 放 些個滅 器,每個節點可以放任意多個。接下來每個節點都要被分配給 個 多 k 條邊遠的滅 器,每個滅 器最多能分配給 s 個節 點。少要多少個滅 器才能讓 w 徹底死 呢?樹形dp,由於k 2...

訓練賽B FZB(樹形DP)

時間限制 1 sec 記憶體限制 128 mb hja有一棵n個點的樹,樹上每個點有點權,每條邊有顏色。一條路徑的權值是這條路徑上所有點的點權和,一條合法的路徑需要滿足該路徑上任意相鄰的兩條邊顏色都不相同。問這棵樹上所有合法路徑的權值和是多少。第一行乙個數n。接下來一行n個數代表每個點的權值。接下來...