日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

北京理工大学小学期乐学 t23树上统计

發(fā)布時間:2023/12/2 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 北京理工大学小学期乐学 t23树上统计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

寫在前頭

玩一下csdn的markdown。
這道題的大意是

給定一棵樹,兩個相鄰點之間的距離為111,對于相鄰距離為222的點之間可以新建一條邊,要求每個點到其他所有點點的距離之和的和。

看似是一道搜索題,但是我多日后再想起來感覺還有動態(tài)規(guī)劃的思路在里頭。

t23

參考帖子:http://lexue.bit.edu.cn/mod/forum/discuss.php?d=126124,閱讀前請先看一看這篇文章。

如果看不到原帖,這里大致概括本貼中用到的原帖中的結(jié)論,對于相鄰的節(jié)點 i,ji,ji,j,原帖總結(jié)了所有節(jié)點中除了 i,ji,ji,j 外的任意節(jié)點 xxxiii 的距離 ddd 于到 jjj 的距離 d′d'd 之間的關(guān)系。

本文是對上貼中最后留白部分的推論,我寫這個的時候程序還沒寫(主要是擔心寫不出ac,先寫寫推導過程拿一點平時分orz)

約定

在zzxdl的帖子中兩點之間的距離用 distdistdist 表示,文中用 ddd 表示,且 d(x,x)=0,d′(x,x)=0d(x,x)=0,d'(x,x)=0d(x,x)=0,d(x,x)=0

正文

對于圖 G(E,V)G(E,V)G(E,V),取一條邊 i?ji-ji?j,邊上的兩點分別為 i,ji,ji,j,設節(jié)點 iii 的所有子樹編號為 1,…,n1,\ldots,n1,,njjj 節(jié)點所有子樹編號為1,…,m1,\ldots,m1,,m,對于 iii 節(jié)點的第 kkk 個子樹上所有節(jié)點的集合為 SikS_{ik}Sik?,其中所有到 iii 距離為偶數(shù)的節(jié)點的集合為 EikE_{ik}Eik? ,距離為奇數(shù)的節(jié)點的集合為 OikO_{ik}Oik?。于節(jié)點 jjj 同理。

那么有:
?kEjk=?kOik?{j}?kOjk=?kEik∪{i}\begin{aligned} \bigcup_k{E_{jk}}=\bigcup_k{O_{ik}}-\{j\}\\ \bigcup_k{O_{jk}}=\bigcup_k{E_{ik}}\cup\{i\}\\ \end{aligned} k??Ejk?=k??Oik??{j}k??Ojk?=k??Eik?{i}?
令:
Oi=?kOikOj=?kOjkEi=?kEikEj=?kEjksumi=∑u≠id′(u,i)sumj=∑u≠jd′(u,j)\begin{aligned} &O_i=\bigcup_k{O_{ik}} & O_j=\bigcup_k{O_{jk}}\\ &E_i=\bigcup_k{E_{ik}} & E_j=\bigcup_k{E_{jk}}\\ &sum_i=\sum_{u\neq i}{d'(u,i)}\\&sum_j=\sum_{u\neq j}{d'(u,j)} \end{aligned} ?Oi?=k??Oik?Ei?=k??Eik?sumi?=u?=i?d(u,i)sumj?=u?=j?d(u,j)?Oj?=k??Ojk?Ej?=k??Ejk?
顯然,結(jié)合上文的推導:
sumi=∑u∈Eid′(u,i)+∑u∈Oid′(u,i)sumj=∑u∈Ejd′(u,j)+∑u∈Ojd′(u,j)=∑u∈Oi?{j}d′(u,j)+∑u∈Ei+{i}d′(u,j)=∑u∈Oid′(u,j)+∑u∈Eid′(u,j)+1\begin{aligned} sum_i&=\sum_{u\in E_i}{d'(u,i)}+\sum_{u\in O_i}{d'(u,i)}\\ sum_j&=\sum_{u\in E_j}{d'(u,j)}+\sum_{u\in O_j}{d'(u,j)}\\ &=\sum_{u\in O_i-\{j\}}{d'(u,j)}+\sum_{u\in E_i+\{i\}}{d'(u,j)}\\ &=\sum_{u\in O_i}{d'(u,j)}+\sum_{u\in E_i}{d'(u,j)}+1\\ \end{aligned} sumi?sumj??=uEi??d(u,i)+uOi??d(u,i)=uEj??d(u,j)+uOj??d(u,j)=uOi??{j}?d(u,j)+uEi?+{i}?d(u,j)=uOi??d(u,j)+uEi??d(u,j)+1?
由于 (i,j)∈E(i,j)\in E(i,j)E,所以有且僅有唯一的 p∈{1,2…,n}p\in\{1,2\ldots,n\}p{1,2,n},使得其所對應的子樹中所有點的集合滿足:
j∈SipEip+Oip=Sip\begin{aligned} j&\in S_{ip}\\ E_{ip}+O_{ip}&=S_{ip} \end{aligned} jEip?+Oip??Sip?=Sip??
那么:
sumj=∑u∈Oi?Oipd′(u,j)+∑u∈Ei?Eipd′(u,j)+1+∑u∈Oipd′(u,j)+∑u∈Eipd′(u,j)=∑u∈Oi?Oipd′(u,i)+∑u∈Ei?Eipd′(u,i)+1+∣Ei∣?∣Eip∣+∑u∈Oipd′(u,i)?∣Oip∣+∑u∈Eipd′(u,i)=∑u∈Eid′(u,i)+∑u∈Oid′(u,i)+∣Ei∣?∣Sip∣+1=sumi+∣Ei∣?∣Sip∣+1\begin{aligned} sum_j&=\sum_{u\in O_i-O_{ip}}{d'(u,j)}+\sum_{u\in E_i-E_{ip}}{d'(u,j)}+1+\sum_{u\in O_{ip}}{d'(u,j)}+\sum_{u\in E_{ip}}{d'(u,j)}\\ &=\sum_{u\in O_i-O_{ip}}{d'(u,i)}+\sum_{u\in E_i-E_{ip}}{d'(u,i)}+1+|E_i|-|E_{ip}|+\sum_{u\in O_{ip}}{d'(u,i)}-|O_{ip}|+\sum_{u\in E_{ip}}{d'(u,i)}\\ &=\sum_{u\in E_i}{d'(u,i)}+\sum_{u\in O_i}{d'(u,i)}+|E_i|-|S_{ip}|+1\\ &=sum_i+|E_i|-|S_{ip}|+1 \end{aligned} sumj??=uOi??Oip??d(u,j)+uEi??Eip??d(u,j)+1+uOip??d(u,j)+uEip??d(u,j)=uOi??Oip??d(u,i)+uEi??Eip??d(u,i)+1+Ei??Eip?+uOip??d(u,i)?Oip?+uEip??d(u,i)=uEi??d(u,i)+uOi??d(u,i)+Ei??Sip?+1=sumi?+Ei??Sip?+1?

由此再進行一次深度優(yōu)先搜索即可得到答案。

貼上代碼

#include <iostream> #include <vector> using namespace std;#define N 200 // 2000000 #define HALF(x) (((x)&1) + ((x)>>1)) // 除二并向上取整vector<int> edge[N]; /* oddR 所有節(jié)點到根節(jié)點的奇數(shù)點的個數(shù) evenR 所有節(jié)點到根節(jié)點的偶數(shù)點的個數(shù) sizeTree 以r為根的數(shù)中每一個幾點所代表的子樹的節(jié)點個數(shù) */ int oddR, evenR, sizeTree[N]; int disRoot[N]; // 節(jié)點到根的距離 long long sum[N], sumUp;int E(int i); // 到節(jié)點i的距離為偶數(shù)的點的個數(shù) int O(int i); // 到節(jié)點i的距離為奇數(shù)的點的個數(shù) int dfs1(int i, int f); // 給出所有點的子樹的規(guī)模 void dfs2(int i, int f, int r, int depth); // 給出所有點的奇偶節(jié)點的數(shù)量 void dfs3(int i, int f); // 轉(zhuǎn)移計算int main(void) {int n, a, b, r;cin >> n;while (n-- > 1){scanf("%d%d", &a, &b); getchar();edge[a].push_back(b);edge[b].push_back(a);}r = a;dfs1(r, 0);dfs2(r, 0, r, 1);sumUp += sum[r];dfs3(r, 0);cout << sumUp / 2 << endl;return 0; }void dfs3(int i, int f) {for (int j = 0; j < edge[i].size(); j++){int tmp = edge[i][j];if (tmp != f){sum[tmp] = sum[i] + E(i) - sizeTree[tmp] + 1;sumUp += sum[tmp];dfs3(tmp, i);}}return; }int E(int i) { return disRoot[i] % 2 == 0 ? evenR : oddR - 1; } int O(int i) { return disRoot[i] % 2 == 0 ? oddR : evenR + 1; }void dfs2(int i, int f, int r, int depth) {for (int j = 0; j < edge[i].size(); j++){int tmp = edge[i][j];if (tmp != f){if (depth & 1 == 1) // 距離根節(jié)點奇數(shù)距離oddR++;else evenR++; // 距離根節(jié)點偶數(shù)距離disRoot[tmp] = depth;sum[r] += HALF(depth);dfs2(tmp, i, r, depth + 1);}}return; }int dfs1(int i, int f) {for (int j = 0; j < edge[i].size(); j++){int tmp = edge[i][j];if (tmp != f)sizeTree[i] += dfs1(tmp, i);}sizeTree[i]++;return sizeTree[i]; }

總結(jié)

以上是生活随笔為你收集整理的北京理工大学小学期乐学 t23树上统计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。