CSP S2019 D1T3 樹上的數

2021-09-29 21:17:25 字數 2260 閱讀 5370

給定乙個大小為 n

nn 的樹,它共有 n

nn 個結點與 n−1

n - 1

n−1 條邊,結點從 1∼n

1 \sim n

1∼n 編號。初始時每個結點上都有乙個 1∼n

1 \sim n

1∼n 的數字,且每個 1∼n

1 \sim n

1∼n 的數字都只在恰好乙個結點上出現。

接下來你需要進行恰好 n−1

n - 1

n−1 次刪邊操作,每次操作你需要選一條未被刪去的邊,此時這條邊所連線的兩個結點上的數字將會交換,然後這條邊將被刪去。

n −1

n - 1

n−1 次操作過後,所有的邊都將被刪去。此時,按數字從小到大的順序,將數字 1∼n

1 \sim n

1∼n 所在的結點編號依次排列,就得到乙個結點編號的排列 p

ip_i

pi​​。現在請你求出,在最優操作方案下能得到的字典序最小的 p

ip_i

pi​​。

我們不難有乙個貪心的想法:列舉每個數,將它們分別移動到盡可能小的節點上面去。

考慮把乙個數字送到另乙個數字上,對於乙個點我們一共有三種限制:

那麼這樣一來我們將刪的邊的順序排成一排,可以發現我們可以用雙向鍊錶來維護。於是我們給每個節點 u

uu 都建立乙個雙向鍊錶。

但在計算答案的過程中,一定有一些是連不到一起的,這種情況我們直接把它們看成一堆鍊錶就可以了。

於是就可以用兩次 dfs 解決這個問題:

列舉每個數字,第一次 dfs 找出它能夠到達的最小的節點,第二次 dfs 更新鍊錶。

總時間複雜度 o(n

2)

o(n^2)

o(n2) 。

各種情況的討論還是看**吧。。。太複雜了 我不想寫 寫不出來。。。

簡直是分類大討論啊。。。

#include

#include

using

namespace std;

const

int maxn =

2000

;struct edge

;edge pool[maxn *2+

5];edge *g[maxn +5]

,*ecnt;

inline

void

addedge

(int u,

int v)

int n, num[maxn +5]

;int pre[maxn +5]

[maxn +5]

, nxt[maxn +5]

[maxn +5]

;//鍊錶的前後指標

int head[maxn +5]

[maxn +5]

, tail[maxn +5]

[maxn +5]

;//鍊錶的頭節點和尾節點

int len[maxn +5]

[maxn +5]

;//鍊錶的大小

int deg[maxn +5]

;inline

void

clear()

int minp;

void

dfs1

(int u,

int fa)

}else

}else

dfs1

(nxt[u]

[fa]

, u)

;//否則只能夠按照我們之前已經確定了的路徑找}}

inline

void

merge

(int u,

int st,

int ed)

//將兩個鍊錶連在一起

bool

dfs2

(int u,

int fa)

int st = head[u]

[fa]

, ed = tail[u]

[fa];if

(fa == n +1)

}}else}}

else

dfs2

(nxt[u]

[fa]

, u)

;//按照既定路徑找下去

}return

false;}

intmain()

if(n ==1)

for(

int i =

1; i <= n; i++)}

return0;

}

CSP S2019 D2T3 樹的重心

小簡單正在學習離散數學,今天的內容是圖論基礎,在課上他做了如下兩條筆記 乙個大小為 n nn 的樹由 n nn 個結點與 n 1 n 1 n 1 條無向邊構成,且滿足任意兩個結點間有且僅有一條簡單路徑。在樹中刪去乙個結點及與它關聯的邊,樹將 為若干個子樹 而在樹中刪去一條邊 保留關聯結點,下同 樹將...

CSP S 2019 樹上的數(樹上推理)

過了這麼久看看自己要多久才能切這題,發現還是想歪了一次。先考慮暴力的做法。還是貪心的逐位確定,逐位確定判有沒有解,相當於下面的問題 樹上有一些路徑,一條路徑表示要把 x 的數字換到 y 去,問有沒有解。對於一條路徑 p 1 p 2 p m 限制如下 1.p 1 p 2 是 p 1 的所有相鄰邊中時間...

SCOI 2019 D1T1 跳躍遊戲

傳送門 有 mm m 個小球,n nn 個島。其中第乙個 最後乙個島以及中間的第 k kk 個島 1 k 1 k n 1 k是固定的,其餘島是懸浮的。一開始所有小球都在第乙個島,你的目標是把他們都移動到最後乙個島,並且使用的步數盡量小。每回合你可以移動乙個小球到它左邊或者右邊的那個平台,但是有一些限...