P3320 SDOI2015 尋寶遊戲 題解

2022-10-11 09:21:08 字數 1097 閱讀 7686

題面

需要動態維護乙個點集的極小聯通子圖邊權和。可以發現,將點集 \(\\) 中的點按照 dfs 序從小到大排序之後,\(dist(a_1,a_2)+dist(a_2,a_3)+\ldots+dist(a_,a_k)+dist(a_k,a_1)\) 恰好等於我們要維護的那個邊權和的兩倍。所以就開乙個set,在加入和刪除的時候加上或刪去prenxt的貢獻即可。

const int n=1e5+13;

struct edgee[n<<1];

int n,m,h[n],tot;

ll dis[n];

inline void add_edge(int u,int v,int w);h[u]=tot;}

int fa[n],dep[n],siz[n],son[n],top[n],id[n],dfs_clock;

void dfs1(int u,int f,int deep)

}void dfs2(int u,int topf)

}inline int lca(int u,int v));

if((++it)!=t.end()) nxt=it->x;

if(pre) sum-=dist(pre,x);if(nxt) sum-=dist(nxt,x);if(pre&&nxt) sum+=dist(pre,nxt);

t.erase((node));

} else);

it=t.find((node));

int pre=0,nxt=0;

if(it!=t.begin()) pre=(--it)->x,it=t.find((node));

if((++it)!=t.end()) nxt=it->x;

if(pre) sum+=dist(pre,x);if(nxt) sum+=dist(nxt,x);if(pre&&nxt) sum-=dist(pre,nxt);

} it=t.end();--it;

if(it!=t.begin())

else println(sum);

} return 0;

}

P3320 SDOI2015 尋寶遊戲

我們考慮現在已知點集,如何求最後的答案。發現答案就是求所有點構成的最小生成樹的邊權和減去最小生成樹直徑。嗯 這個東西我好像不會動態維護啊。哦,發現要回到最初轉移到的村莊,那不就是兩倍的最小生成樹的邊權嗎,題目變簡單了一點。現在就是考慮動態維護最小生成樹的邊權和,我們考慮將邊權下放。那麼當前這棵樹的答...

LG3320 SDOI2015 尋寶遊戲

洛谷 不需要建虛樹的虛樹2333。貪心地想一下,起始節點肯定是在關鍵點上,訪問順序就是 dfs 序。那麼對於每次詢問,ans dis s 1,s s sum dis s i,s 用 set 維護一下就好了 include include include include include include...

Luogu 3320 SDOI2015 尋寶遊戲

一開始還真沒想到。發現從所有有寶藏的點出發繞一圈只要不刻意繞路答案都是一樣的,即我們呢要求的最後答案 ans dis x 1,x 2 dis x 2,x 3 dis x x k dis x k,x 1 不刻意繞遠路怎麼辦呢,我們把有寶藏的點按照 dfs 序,維護乙個有序的 set 就可以了。每次插入...