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

2021-09-28 21:56:03 字數 2282 閱讀 7496

我不會的都是好題。

一張連通的圖,有k(k

≤20

)k(k\le 20)

k(k≤20

)個點被點燃了。每條邊有乙個權值表示從乙個點燒到另乙個點需要的時間。

現在可以選擇一些點滅火,求有多少種滅火方案不會使燒完所有點的用總時間變長。

正難則反,求可以使總時間邊長的滅火方案。

k

kk遍最短路,求出每個點u

uu被某個欽定的點v

vv燒到用的時間,記為dis

[v][

u]

dis[v][u]

dis[v]

[u]。

假如要使燒到u

uu的時間大於原始的總時間,那麼dis

[v][

u]≤m

ax_d

is

dis[v][u]\le max\_dis

dis[v]

[u]≤

max_

dis的所有點都必須滅火。由此,對於每乙個點我們得到了乙個最小的滅火集合,而所有包含這個集合的集合同樣可以延長總時間,所以最後狀壓搞一搞就完事了。

#include

using

namespace std;

typedef

long

long ll;

const ll inf =

1e18+7

;const

int n =

1e5+

10, m =

4e5+

10, k =20;

const

int mod =

998244353

;int n, m, k, a[k]

;int h[n]

, ecnt, v[m]

, w[m]

, nxt[m]

;struct node

node

(int x, ll y)

bool

operator

<

(const node &u)

const};

priority_queue que;

ll dis[k]

[n], pd, ans;

int f[

1<;template

<

class

t>

inline

void

read

(t &x)

while

(isdigit

(c))

if(fl) x =

-x;}

void

add(

int _u,

int _v,

int _w)

inline

intfpow

(int x,

int y,

int p)

return ret;

}ll solve

(int sta, ll *dis)

while

(!que.

empty()

)}ll ret =0;

for(

int i =

1; i <= n;

++ i)

if(ret < dis[i]

) ret = dis[i]

;return ret;

}int

main()

pd =

solve((

1<, dis[0]

);for(

int i =

0; i < k;

++ i)

solve(1

<< i, dis[i]);

memset

(f,0

,sizeof

(f))

;for

(int i =

1; i <= n;

++ i)

f[now]=1

;}ans =

fpow(2

, k, mod)

;for

(int i =

1; i <(1

<;++ i)

printf

("%lld\n"

, ans *

fpow

(fpow(2

, k, mod)

, mod-

2, mod)

% mod)

;return0;

}

旅遊 狀壓 最短路

description db愛好運動,但是單純的運動會使得他很枯燥,現在他想邊跑步邊看風景。已知現在有n個風景點 編號為1號 n號 同時有m條道路將這n個風景點連線起來。這些風景點總共有3類 a,b,c 為了方便表示,我們令 a 0,b 1,c 2。db一開始在1號風景點 可以為a,b,c類 現在d...

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

有一條線上有 n nn 個點,有 m mm 個人,第 i ii 個人站在 a ia i ai 位置,可以花乙個代價向左或者向右跳 f if i fi 的距離。現在乙個東西在 1 11 號人手裡,想要把這個東西交到 2 22 號人手裡。乙個人可以把東西轉交給另乙個人當且僅當兩個人在同乙個位置。求轉交的...

POJ 3230 Travel(最短路 狀壓DP)

一張 n n 個節點 m role presentation style position relative m m條邊的圖,每個節點代表乙個城市,每條邊代表連線兩個城市,花費一定的路徑 雙向 你選擇了 h h 個城市,現在要這些城市中打工。在第 i role presentation style ...