AHOI2014 JSOI2014 騎士遊戲

2022-03-26 22:32:54 字數 1321 閱讀 3854

題目

思博貪心題寫了乙個半小時沒救了,我也沒看出這是乙個\(spfa\)來啊

設\(dp_i\)表示徹底乾掉第\(i\)只怪物的最小花費,乙個非常顯然的事情,就是對於\(k_i\)值最小的怪物滿足\(dp_i=k_i\)

非常好理解,反正到最後都要乾掉這個怪物,何必再把它乾成別的怪物

於是我們按照\(k_i\)的值先排序一下,另外維護乙個小根堆

如果堆裡沒有點或者堆頂的\(dp\)值比當前的\(k\)要大,我們直接令當前當前\(k_i\)值最小的點\(i\)的\(dp_i=k_i\),之後遍歷所有能到達點\(i\)的點\(v\),令\(s_v+=dp_i\),如果發現點\(v\)的所有出邊都被遍歷了一遍,我們就令\(dp_v=\min(s_v,k_v)\),同時把這個點加入堆中

如果堆裡有點且堆頂的\(dp\)小於於當前\(k\),就直接拿堆頂來更新

考慮這個做法的正確性,顯然當前堆中沒有節點的時候,圖中任意乙個點不可能只分解成已經處理好\(dp_i\)的點,於是我們必須引入剩下的\(k\)值最小的點

或者把堆中沒有點的情況視為初始情況,可能這樣更好理解

**

#include #define re register

#define ll long long

#define mp std::make_pair

#define min(a, b) ((a) < (b) ? (a) : (b))

const int maxn = 2e5 + 5;

struct e e[1000005];

ll dp[maxn], s[maxn], w[maxn];

int head[maxn], vis[maxn], c[maxn], p[maxn];

int n, num, top;

inline ll read()

typedef std::pairpii;

std::priority_queue, std::greater> q;

inline int cmp(int a, int b)

inline void del(int x)

}inline void add(int x, int y)

int main()

for (re int i = 1; i <= n; i++) p[i] = i;

std::sort(p + 1, p + n + 1, cmp);

int now = 1, tot = 0;

while (tot < n)

printf("%lld\n", dp[1]);

return 0;

}

AHOI2014 JSOI2014 騎士遊戲

題目背景 長期的宅男生活中,jyy又挖掘出了一款rpg遊戲。在這個遊戲中jyy會 扮演乙個英勇的騎士,用他手中的長劍去殺死入侵村莊的怪獸。題目描述 在這個遊戲中,jyy一共有兩種攻擊方式,一種是普通攻擊,一種是法術攻擊。兩種攻擊方式都會消耗jyy一些體力。採用普通攻擊進攻怪獸並不能把怪獸徹底殺死,怪...

AHOI2014 JSOI2014 騎士遊戲

傳送門 考慮 text 設 dp i 表示滅種 霧 乙隻編號為 i 的怪物的代價。那麼轉移顯然是 dp i min k i,s i sum dp 但是我們會發現這個東西是有後效性的。所以我們會想要用建圖然後跑乙個最短路什麼的來搞。於是我們觀察到上面那個 text 式子中,dp i 如果用後面那一項來...

AHOI2014 JSOI2014 宅男計畫

傳送門 我們首先要發現乙個性質 存貨天數隨買食物的次數的變化類似於單峰函式。具體證明不會啊,好像是二分加三分來證明?但是沒有找到明確的嚴格證明。感性理解一下就是 買的食物太少,很容易餓死 買太多就沒錢了,也活不長。所以我們考慮如何對於當前三分的答案如何 text 有乙個顯而易見的性質就是我們不會用 ...