P1875 佳佳的魔法药水

题意:给出0~n-1号药水的价钱 我们要用最少的钱买0号药水;

  题目中会给出某两种药水的融合品

  让我们找出最少花的钱和方案数

思路:一开始做这道题的时候,想到的肯定就是最短路了,于是我朝着SPFA方面想

   可是,我在建图方面并不知道怎么建。。。。想了大概一个小时也不知道如何建图

   然后看了别人的题解,发现很多人都是用dij算法来做这道题

   用这个算法来做这道题,倒是不用考虑建图方面的内容,可以直接算;

   那么,到底怎么做呢?

   题目中让我们求最短路径和方案数,我们分别用tmp1,tmp2这两个数组来表示

   然后再用一个G【】【】来记录哪两种药水的融合品

   然后就开始跑dij算法,跑松弛点的时候,跟模板是一样的

   然后在松弛的时候,与模板略有不同

   在模板中,是跑那些还没遍历的点,根据题目中给出的路径来松弛

   而在本题中呢,是通过枚举已经松弛过的点,来松弛其他位置  (两者其实也差不多,hhhh)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e3+10;
 4 const int inf=0x3f3f3f3f;
 5 int tmp1[maxn];
 6 int tmp2[maxn];
 7 int G[maxn][maxn];
 8 int vis[maxn];
 9 int main()
10 {
11     int n;
12     scanf("%d",&n);
13     for(int i=0;i<n;i++){
14         scanf("%d",&tmp1[i]);
15         tmp2[i]=1;
16     }
17     memset(G,-1,sizeof(G));
18     int u,v,w;
19     while(scanf("%d%d%d",&u,&v,&w)!=EOF){
20       //  if(u==0) break;
21         G[u][v]=w;
22         G[v][u]=w;
23     }
24     for(int k=1;k<n;k++){
25         int tmp=inf;
26         int base;
27         for(int j=0;j<n;j++){
28             if(!vis[j]&&tmp>tmp1[j]){
29                 tmp=tmp1[j];
30                 base=j;
31             }
32         }
33         if(tmp==inf) break;
34         vis[base]=1;
35         for(int j=0;j<n;j++){
36             if(vis[j]&&G[j][base]!=-1){
37                 if(tmp1[G[j][base]]>tmp1[j]+tmp1[base]){
38                     tmp1[G[j][base]]=tmp1[j]+tmp1[base];
39                     tmp2[G[j][base]]=tmp2[j]*tmp2[base];
40                 }
41                 else if(tmp1[G[j][base]]==tmp1[j]+tmp1[base]){
42                     tmp2[G[j][base]]+=tmp2[j]*tmp2[base];
43                 }
44             }
45         }
46     }
47     printf("%d %d\n",tmp1[0],tmp2[0]);
48     return 0;
49 }
View Code

 

posted @ 2020-04-19 11:11  古比  阅读(132)  评论(0编辑  收藏  举报