香蕉OI 月之美兔(最短路)

2021-09-29 13:01:20 字數 3215 閱讀 3535

有一條線上有 n

nn 個點,有 m

mm 個人,第 i

ii 個人站在 a

ia_i

ai​ 位置,可以花乙個代價向左或者向右跳 f

if_i

fi​ 的距離。

現在乙個東西在 1

11 號人手裡,想要把這個東西交到 2

22 號人手裡。乙個人可以把東西轉交給另乙個人當且僅當兩個人在同乙個位置。

求轉交的最小代價。n,m

≤2∗1

04

n,m\le 2*10^4

n,m≤2∗

104首先有乙個顯而易見的結論:代價最小的轉交中,乙個人最多隻會拿到東西一次,也就是說不會送走了這個東西再拿回來。

那麼每個人對轉交的貢獻就是從 a

ia_i

ai​ 出發跑到乙個位置 p

1p_1

p1​ ,然後再跑到 p

2p_2

p2​ 把這個東西交給下乙個人。

所以現在已經有乙個顯而易見的暴力了,只需要把每兩個位置 p1,

p2

p_1,p_2

p1​,p2

​ 之間連邊,邊權為某個人把東西從 p

1p_1

p1​ 轉運到 p

2p_2

p2​ 的最小代價。然後跑最短路。 o(n

2∗m)

o(n^2*m)

o(n2∗m

) 然後考慮優化連邊的過程,可以把 f

if_i

fi​ 和 aim

odfi

a_i\; mod \; f_i

ai​mod

fi​ 相同的點一起建邊,假設 ∀fi

=f,∀

aimo

dfi=

r\forall f_i=f,\forall a_i\; mod\; f_i=r

∀fi​=f

,∀ai

​mod

fi​=

r。方法如下:

把所有標號為 k∗f

+r

k*f+r

k∗f+

r 的點複製一遍

複製的點之間連上邊權為 1 的邊

複製的點向原點連邊權為 0 的邊

原點向複製的點連邊權為「最近的滿足 fi=

f,ai

modf

i=

rf_i=f,a_i\; mod\; f_i=r

fi​=f,

ai​m

odfi

​=r 的點到他的距離」的邊。

走到複製的點上就表示這個東西被乙個人攜帶。(說的不是很清楚,感性理解一下就好了)

可以證明最後點數和邊數都是 o(n

m)

o(n\sqrt)

o(nm​)

的。因為想要複製一組點,就需要一組新的 f

ff 和 r

rr,最開始複製 n

nn 個點最少只需要 1

11 組 f=1

,r=0

f=1,r=0

f=1,r=

0 就行了,而後面就依次需要 2

22 組,3

33 組 ...

.....

.。所以跑最短路就好了。

#include

using

namespace std;

#define pii pair

#define mp make_pair

#define fi first

#define se second

const

int inf =

1e9+7;

const

int n =

20000+10

, sqrn =

200, m =

(n*sqrn)

<<2;

int n, m, s, t, pt;

int ncnt, dis[n*sqrn]

, id[n]

;struct nodea[n]

;int h[n*sqrn]

, ecnt, v[m]

, nxt[m]

, w[m]

;priority_queue

, greater

> que;

template

<

class

t>

inline

void

read

(t &x)

while

(isdigit

(c))

if(fl) x =

-x;}

void

_add

(int x,

int y,

int z)

bool

cmp(node x, node y)

intdijkstra()

}int ans = inf;

for(

int i =

0; i < n;

++ i)if(

abs(t-i)

%pt ==0)

ans =

min(ans, dis[i]

+abs

(t-i)

/pt)

;return ans;

}int

main()

s = a[1]

.a; t = a[2]

.a; pt = a[2]

.p;sort

(a +

1, a + m +

1, cmp)

; ncnt = n-

1; ecnt =1;

for(

int i =

1, j; i <= m; i = j)

for(

int o = a[k]

.a, tmp =

0; o >=

0; o -

= p,

++tmp)

}for

(int k = r; k < n; k +

= p)

_add

(k, id[k]

, dis[k]);

_add

(id[k]

, k,0)

;}}printf

("%d\n"

,dijkstra()

);return0;

}

香蕉oi 燃燒的火焰(最短路 狀壓)

我不會的都是好題。一張連通的圖,有k k 20 k k le 20 k k 20 個點被點燃了。每條邊有乙個權值表示從乙個點燒到另乙個點需要的時間。現在可以選擇一些點滅火,求有多少種滅火方案不會使燒完所有點的用總時間變長。正難則反,求可以使總時間邊長的滅火方案。k kk遍最短路,求出每個點u uu被...

香蕉OI 染色遊戲(容斥,樹型DP)

恢復訓練。有一棵樹,節點個數 n 1000 n le 1000 n 1000 初始每個點都是白色,每次等概率選乙個點,把他和與他直接相連的點染成黑色。求將整棵樹染成黑色的期望步數。首先,設 p ip i pi 表示染了 i ii 次還沒有把整棵樹全部染黑的概率。所求的答案可以轉化為 i 0 p i ...

牛客OI月賽12 提高組題解

牛客oi月賽12 提高組 當天晚上被 loli 要求去打了某高階oj部分原創的模擬賽,第二天看了牛客的題覺得非常清真,於是就去寫了 不難發現現場寫出 260 text 並不需要動腦子,而且 260 text 甚至還有 rk2 感覺沒打非常吃虧 a.小w的進製轉換 大概理解一下就是詢問 1 到 n 裡...