UOJ126 NOI2013 快餐店(基環樹dp)

2021-08-19 02:04:31 字數 2708 閱讀 7888

題目鏈結

思路:

現在圖中保證一定只有乙個環,這個基環樹,也就是說去掉環上的任意一條邊,它能形成一棵樹,先看最長路徑不在環上的情況,那麼最長路徑就是在環上的點為根的子樹中了,這個求下樹的直徑即可。看在環上的,如果最長路徑在環上,最長路徑一定有一條環上的邊沒有經過, 假設(u

,v) (u,

v)

是沒有經過地邊, 可以將環斷開成鏈,兩倍環長度,然後考慮將(u

,v) (u,

v)

斷開,那麼現在經過環上的路徑的最長長度就是su

m[i]

+len

[i]−

sum[

j]+l

en[j

] sum

[i]+

len[

i]−s

um[j

]+le

n[j]

,sum sum

陣列是鏈上的乙個距離字首和,le

n[i]

l en

[i

]是以鏈上

i i

這個節點為根的子樹距離

i' role="presentation">i

i最遠的距離,那麼只需要維護su

m[i]

+len

[i] sum

[i]+

len[

i]

,−sum[i

]+le

n[i]

− su

m[i]

+len

[i

]的最大值就行了,可以直接用集合存,因為下次掃瞄斷開

v v

和下乙個點的時候過期節點可以直接刪除,而且能夠保證取到的兩個值的最大值之和(下標不同)就是不經過(u

,v)' role="presentation">(u,

v)(u

,v)的最大路徑長度。

#include

typedef

long

long ll;

const ll maxn = 2e5 + 10;

const ll inf = 1e18 + 10;

using

namespace

std;

struct p

bool

operator

< (p p) const

};typedef pairpa;

ll n, m, t, kase = 1;

vector

g[maxn];

ll vis[maxn], pre[maxn], is[maxn];

ll dis[maxn], len[maxn];

ll sum[maxn], res[maxn];

pa find_circle(ll x, ll fa)

return ans;

}void find_id(ll x, ll fa, ll root, ll dis, ll &sum, ll &id)

for(ll i = 0; i < g[x].size(); i++)

}void cir_list(pa now, vector

&vec)

}while(y)

memset(is, 0, sizeof is);

for(ll i = 0; i < vec.size(); i++) is[vec[i]] = 1;

}void deal_with(ll root, ll x, ll fa, ll d)

}vector

lst;

set st1, st2;

p q1[20], q2[20];

ll solve()

ll kst = inf;

for(ll i = 0; i < lst.size(); i++) deal_with(lst[i], lst[i], lst[i], 0);

ll sz = lst.size();

for(ll i = 0; i < lst.size() / 2; i++) swap(lst[i], lst[sz - 1 - i]);

for(ll i = 0; i < sz; i++) lst.push_back(lst[i]);

for(ll i = 0; i < lst.size(); i++)

set::iterator it1;

set::iterator it2;

for(ll i = 0; i < lst.size(); i++)

while(cnt2 < 2)

for(ll j = 0; j < cnt1; j++)

}kst = min(kst, now);

ll las_id = i - sz + 1;

st1.erase(p(las_id, sum[las_id] + len[lst[las_id]]));

st2.erase(p(las_id, -sum[las_id] + len[lst[las_id]]));

}return max(ans, kst);

}int main()

memset(vis, 0, sizeof vis);

ll ans = solve();

printf("%.1f\n", (double)ans / 2);

}return

0;}

動態規劃 NOI2013 快餐店

第一行包含乙個整數n,表示城市c中的建築和道路數目。接下來n行,每行3個整數,ai,bi,li 1 i n li 0 表示一條道路連線了建築ai與bi,其長度為li 僅包含乙個實數,四捨五入保留恰好一位小數,表示最佳快餐店選址距離最遠使用者的距離。注意 你的結果必須恰好有一位小數,小數字數不正確不得...

UOJ 122 NOI2013 樹的計數

uoj 122 noi2013 樹的計數 試題描述 我們知道一棵有根樹可以進行深度優先遍歷 dfs 以及廣度優先遍歷 bfs 來生成這棵樹的 dfs 序以及 bfs 序。兩棵不同的樹的 dfs 序有可能相同,並且它們的 bfs 序也有可能相同,例如下面兩棵樹的 dfs 序都是 1 2 4 5 3,b...

樹DP 基環樹 NOI2013 快餐店

小 t 打算在城市 c 開設一家外送快餐店。送餐到某乙個地點的時間與外賣店到該地點之間最短路徑長度是成正比的,小 t 希望快餐店的位址選在離最遠的顧客距離最近的地方。快餐店的顧客分布在城市 c 的 n 個建築中,這 n個建築通過恰好 n 條雙向道路連線起來,不存在任何兩條道路連線了相同的兩個建築。任...