2019瀋陽網路賽d題
樹形dp。一棵樹,求任意兩個點的距離之和。u-v和v-u算兩次。兩點之間的距離分為三類,模3等於0,1,2三類,最後輸出這三類的總和。
第一種方法。直接累加。遍歷到乙個點的時候。先計算答案。答案加上所有已經遍歷過得點到他的距離之和。同時該點也要加上這個值,同時要加上數量。每次先搜到底統計往下遍歷的值,然後回溯的時候統計
回溯的值。因為每次只計算了之前的點到他的距離之和,所以最後的結果要乘以2,因為u-v與v-u算兩次。
每次加的時候先計算當前點前乙個點到他的距離,及0+該邊的邊權。然後在按0,1,2來累加,如果為零表示沒有,就不累加。
#include #define ll long longusing
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 #includeusing
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個數代表每個點的權值。接下來...