bzoj3331 壓力 圓方樹

2022-04-10 05:42:25 字數 1436 閱讀 8567

題目鏈結

圓方樹就是對於聯通無向圖中的每乙個點雙新建乙個方點,與點雙中的每個點連一條邊,然後將原來的邊刪去。將原來的點看作圓點,新建的點看作方點。所以叫做圓方樹。

1.圓方樹肯定是棵樹(廢話)。證明顯然。

2.圓方樹中與圓點相連的點肯定是方點。與方點相連的點肯定是圓點。

根據圓方樹的定義就可以知道。構建圓方樹的過程實際上就是找點雙的過程。本質上就是找割點。所以用tarjan來做就好了。將找出的點雙中的點與新建的點連邊即可。

這個題就是圓方樹的經典應用,先對於原圖構建出圓方樹。那麼對於每個從s到t的路徑。在圓方樹上兩點之間的簡單路徑上的圓點就是在原圖中必須經過的點。然後再圓方樹上差分一下就行了。

/*

* @author: wxyww

* @date: 2019-01-22 20:03:52

* @last modified time: 2019-01-22 20:42:20

*/#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int n = 200000 + 100,logn = 20;

vectore[n * 2];

ll read()

while(c>='0'&&c<='9')

return x*f;

}struct node e[n * 4];

int head[n],ejs;

void add(int u,int v)

void add(int u,int v)

int top,sta[n];

int coljs,n,m,q,cnt,dfn[n],low[n];

void tarjan(int u) }}

else low[u] = min(low[u],dfn[v]);

}}int dep[n];

int lca[n][logn];

void dfs(int u,int father)

}int lca(int x,int y)

for(int i = logn - 1;i >= 0;--i)

}if(x != y) x = lca[x][0];

return x;

}int sum[n];

void dfs2(int u,int father)

}int main()

tarjan(1);

dfs(1,0);

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

dfs2(1,0);

for(int i = 1;i <= nn;++i) printf("%d\n",sum[i]);

return 0;

}

BZOJ2125 最短路 圓方樹

思路 關於靜態仙人掌的問題,建立出圓方樹比較好求解。求出來之後處理每個圓點方點的情況,原來的是樹邊直接處理,環邊的話方點連向環上每個圓點一條邊,權值為每個節點到環的父親節點的最短距離。然後倍增預處理,查詢的時候,如果lc a lca 是圓點直接輸出,否則兩個點是環上的點,處理他們在環上的最短距離即可...

bzoj2125 圓方樹 最短路

description 給乙個n個點m條邊的連通無向圖,滿足每條邊最多屬於乙個環,有q組詢問,每次詢問兩點之間的最短路徑。input 輸入的第一行包含三個整數,分別表示n和m和q 下接m行,每行三個整數v,u,w表示一條無向邊v u,長度為w 最後q行,每行兩個整數v,u表示一組詢問 output ...

bzoj5329 圓方樹 虛樹 戰略遊戲

description 省選臨近,放飛自我的小q無心刷題,於是慫恿小c和他一起頹廢,玩起了一款戰略遊戲。這款戰略遊戲的地圖由n個城市以及m條連線這些城市的雙向道路構成,並且從任意乙個城市出發總能沿著道路走到 任意其他城市。現在小c已經占領了其中至少兩個城市,小q可以摧毀乙個小c沒占領的城市,同時摧毀...