山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

vijosP1285 佳佳的魔法药水

vijosP1285 佳佳的魔法药水

 

链接:https://vijos.org/p/1285

 

【思路】

  图论思想。

  很巧妙。

  如A+B=C,将AB之间连边,边权为C,用以找相连物品与合成物。

  用Dijkstra的思想:找最小价值,如果相连物品中有已经得出最小价值的则共同更新其合成物。

  对于方案数用乘法原理在更新的时候顺便计算。

【代码】

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 
 6 const int maxn = 1000+10;
 7 const int INF=1<<30;
 8 
 9 int G[maxn][maxn],d[maxn],vis[maxn];
10 int tot[maxn];
11 int n;
12 
13 int main(){
14     ios::sync_with_stdio(false);
15     cin>>n;
16     for(int i=0;i<n;i++) cin>>d[i];
17     
18     for(int i=0;i<n;i++) 
19     {
20         tot[i]=1;
21         for(int j=0;j<n;j++) G[i][j]=-1;
22     }
23     
24     int u,v,w;
25     while(cin>>u>>v>>w) {
26         G[u][v]=G[v][u]=w;
27     }
28     for(int i=0;i<n;i++) {
29         int _min=INF,k;
30         for(int j=0;j<n;j++) if(!vis[j] && d[j]<_min) _min=d[k=j];
31         if(_min==INF) break; 
32         vis[k]=1;
33         for(int j=0;j<n;j++) if(vis[j] && G[k][j]>=0)  //注意是vis[j]//寻找已经得到最小价值的更新其合成物 
34            if(d[G[k][j]]>d[k]+d[j]) {
35                    d[G[k][j]]=d[k]+d[j];
36                    tot[G[k][j]]=tot[k]*tot[j];
37            }
38            else
39              if(d[G[k][j]]==d[k]+d[j])
40                 tot[G[k][j]] += tot[k]*tot[j];
41     }
42     cout<<d[0]<<" "<<tot[0]<<"\n";
43     return 0;
44 }

 

posted on 2015-10-23 17:19  hahalidaxin  阅读(205)  评论(0编辑  收藏  举报