日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Vijos - 佳佳的魔法药水(最短路)

發布時間:2023/12/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vijos - 佳佳的魔法药水(最短路) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:https://vijos.org/p/1285

背景

發完了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 <stdio.h> const int inf = 1e9; int map[1010][1010], val[1010], cnt[1010], vis[1010]; int main() {int n, a, b, c, k = 0, minn;scanf("%d", &n);for (int i = 0; i < n; i++){cnt[i] = 1;vis[i] = 0;for (int j = 0; j < n; j++)map[i][j] = -1;}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++){minn = inf;for (int j = 0; j < n; j++)if (!vis[j] && minn > val[j])minn = val[k = j];vis[k] = 1;for (int j = 0; j < n; j++){if (vis[j] && map[k][j] != -1){if (val[map[k][j]] > val[k] + val[j])val[map[k][j]] = val[k] + val[j], cnt[map[k][j]] = cnt[k] * cnt[j];else if (val[map[k][j]] == val[k] + val[j])cnt[map[k][j]] += cnt[k] * cnt[j];}} }printf("%d %d\n", val[0], cnt[0]);return 0; }

總結

以上是生活随笔為你收集整理的Vijos - 佳佳的魔法药水(最短路)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。