不能走路(walk)

2022-05-13 18:13:57 字數 1836 閱讀 5356

小g 同學總是在樹上走路。小s 看不下去了,決定阻止小g 同學。

有一棵 n 個點的樹,樹上有 m 條路徑,每條路徑為 x[i]到y[i] 的樹上最短路徑(不經過相同的邊),小 s 想要摧毀樹上的 k 個點, 使得每一條路徑上都有至少乙個點被摧毀。

你只需要求出最小的k,而不用輸出摧毀了哪些點。

資料點編號

n<=

m<=115

15210015

3100154

100100

51000

1000

65000

5000

75000

5000

8100000

100000

9100000

100000

10100000

100000

【樣例輸入】

5 2

1 22 3

2 42 5

1 53 4

【樣例輸出】
如果需要用到較大的棧空間。

可以在編譯命令加上-wl,--stack=2333333333。評測時開棧。

受洛谷p1967 貨車運輸啟發,這題很像lca。

於是我們就嘗試切lca。

首先,不難發現阻斷lca是可行的,那麼是最優的嗎?

對於一顆子樹內的點,如果從該子樹的點要延伸出子樹外,那必須經過最頂端的點。

如圖,對於乙個點,若要與外面有聯絡,那必定要經過\(lca(a,b)\)。

那兩點的聯絡在子樹內呢?如果是\(c\to d\),那顯然是無關的,那\(e\to b\)呢?我們發現最優應該切\(lca(e, b)\)。

那不是就wa了嗎?不。我們發現:如果我們先切\(lca(e, b)\),到\(a\to b\)是特判一下即可。

由於資料很水,判是否聯通用暴力爬就可以了。

下面上**,剛學樹剖,於是就打了個樹剖。

#include #include using namespace std;

const int maxn = 100005;

struct edge

e[maxn<<1];

int first[maxn];

int nowm;

inline void add_edge(int from, int to)

int fa[maxn], son[maxn], dep[maxn], val[maxn];

inline void dfs1(int x)//找重鏈,標記深度與父親

}int top[maxn];

inline void dfs2(int x, int ff)//尋找重鏈的頂端

}inline void init(int s)

inline int lca(int a, int b)

return dep[a] < dep[b] ? a : b;

}struct sxd

} ask[maxn];

bool biao[maxn];

inline bool pan(int a, int b)

int main()

init(1);

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

sort(ask+1, ask+m+1);//將提問排序,從下往上阻斷

int ans = 0;

for(int i = 1; i <= m; ++i)//暴力往上爬……(竟不會t,還是最優解)

printf("%d\n", ans);

return 0;

}

Walk 解題報告

給定一棵 n 個節點的樹,每條邊的長度為 1 同時有乙個權值 w 定義一條路徑的權值為路徑上所有邊的權值的最大公約數。現在對於任意 i in 1,n 求樹上所有長度為 i 的簡單路徑中權值最大的是多少。如果不存在長度為 i 的路徑,則第 i 行輸出 0 第一行,乙個整數 n 表示樹的大小。接下來 n...

騎車與走路

問題描述 在北大校園裡,沒有自行車,上課辦事很不方便,但實際上,並非去辦任何事情都是騎車快,因為騎車總是要找車,開鎖,停車,鎖車,這要耽誤一些時間 假設找到自行車的時間27秒,停車鎖車的時間為23秒 步行每秒1.2公尺,騎車每秒3.0公尺,請判斷坐不同的距離去辦事,是騎車快還是走路快。關於輸入 第一...

騎車與走路

描述 在北大校園裡,沒有自行車,上課辦事會很不方便.但實際上,並非去辦任何事情都是騎車快,因為騎車總要找車 開鎖 停車 鎖車等,這要耽誤一些時間.假設找到自行車,開鎖並車上自行車的時間為27秒 停車鎖車的時間為23秒 步行每秒行走1.2公尺,騎車每秒行走3.0公尺。請判斷走不同的距離去辦事,是騎車快...