Vijos 佳佳的魔法藥水 最短路

2021-09-05 11:15:24 字數 1677 閱讀 3765

發完了k張**,佳佳卻得到了乙個壞訊息:他的mm得病了!佳佳和大家一樣焦急萬分!治好mm的病只有一種辦法,那就是傳說中的0號藥水……怎麼樣才能得到0號藥水呢?你要知道佳佳的家境也不是很好,成本得足夠低才行……

得到一種藥水有兩種方法:可以按照魔法書上的指導自己配置,也可以到魔法商店裡去買——那裡對於每種藥水都有**,雖然有可能**很貴。在魔法書上有很多這樣的記載:1份a藥水混合1份b藥水就可以得到1份c藥水。(至於為什麼1+1=1,因為……這是魔法世界)好了,現在你知道了需要得到某種藥水,還知道所有可能涉及到的藥水的**以及魔法書上所有的配置方法,現在要問的就是:1.最少花多少錢可以配製成功這種珍貴的藥水;2.共有多少種不同的花費最少的方案(兩種可行的配置方案如果有任何乙個步驟不同則視為不同的)。假定初始時你手中並沒有任何可以用的藥水。

第一行有乙個整數n(n<=1000),表示一共涉及到的藥水總數。藥水從0~n-1順序編號,0號藥水就是最終要配製的藥水。

第二行有n個整數,分別表示從0~n-1順序編號的所有藥水在魔法商店的**(都表示1份的**)。

第三行開始,每行有3個整數a、b、c,表示1份a藥水混合1份b藥水就可以得到1份c藥水。注意,某兩種特定的藥水搭配如果能配成新藥水的話,那麼結果是唯一的。也就是說不會出現某兩行的a、b相同但c不同的情況。

輸出兩個用空格隔開的整數,分別表示得到0號藥水的最小花費以及花費最少的方案的個數。

7

10 5 6 3 2 2 3

1 2 0

4 5 1

3 6 2

10 3

1秒

最優方案有3種,分別是:直接買0號藥水;買4號藥水、5號藥水配製成1號藥水,直接買2號藥水,然後配製成0號藥水;買4號藥水、5號藥水配製成1號藥水,買3號藥水、6號藥水配製成2,然後配製成0。

這是一道最短路的變形題。我們用val[i]來表示藥水i的**、map[i][j]表示i和j可以合成的藥水、cnt[i]表示得到藥水i

的方案數。跑一遍dijkstra演算法,在鬆弛**的時候,一定是vis[j]==1的時候,因為一定要用藥水j的最小**來更新。

當val[map[k][j]]>val[k]+val[j]時,map[k][j]的方案數是k的方案數乘以j的方案數。

當val[map[k][j]]==val[k]+val[j]時,map[k][j]的方案數是加上k的方案數乘以j的方案數。

#include const int inf = 1e9;

int map[1010][1010], val[1010], cnt[1010], vis[1010];

int main()

for (int i = 0; i < n; i++)

scanf("%d", &val[i]);

while (~scanf("%d%d%d", &a, &b, &c))

map[a][b] = map[b][a] = c;

for (int i = 0; i < n; i++)

}

}printf("%d %d\n", val[0], cnt[0]);

return 0;

}

P1875 佳佳的魔法藥水 最短路,DP

好題.一開始一直在想怎麼蛇皮建圖,但是發現一直蛇不出來.正解是用類似於 dijkstra 的演算法對所有點進行鬆弛.對於每個元素記錄兩個值 似乎可以發現我們存合併狀態的陣列很像臨接矩陣?然後就可以開始蛇了.我們對於每一瓶藥水,其 cost 初值為其直接買的花費.ans 初值為 1.每一次選擇未鬆弛的...

佳佳的魔法藥水 樹型dp

發完了 k 張 佳佳卻得到了乙個壞訊息 他的 mm 得病了!佳佳和大家一樣焦急 萬分!治好 mm 的病只有一種辦法,那就是傳說中的 0 號藥水 怎麼樣才能得到 0 號藥 水呢?你要知道佳佳的家境也不是很好,成本得足夠低才行 得到一種藥水有兩種方法 可以按照魔法書上的指導自己配置,也可以到魔法商店裡去...

P1875 佳佳的魔法藥水

題意 給出0 n 1號藥水的價錢 我們要用最少的錢買0號藥水 題目中會給出某兩種藥水的融合品 讓我們找出最少花的錢和方案數 思路 一開始做這道題的時候,想到的肯定就是最短路了,於是我朝著spfa方面想 可是,我在建圖方面並不知道怎麼建。想了大概乙個小時也不知道如何建圖 然後看了別人的題解,發現很多人...