- 题目大意
如题所示获得一个物品有两种方式:
1. 直接购买该物品,第i件物品花费的钱为ci
2. 用两件其他物品合成所需的物品,一共有m种合成方式。
问获得1号物品的最少花费。
- 解题思路
把每种合成方式当成路径(注意是有向图把每种方式弄成两条边)枚举物品,以第i个物品为起点做spfa,做n次,找出最短路,即最少花费。
- 代码\
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int N=1e5+50;
struct edge{
int v,w;
edge(){};
edge(int v,int w):v(v),w(w){};
};
vector<edge>e[N];
int d[N];
int inq[N];
int n,m;
int SPFA() {
queue<int> Q;
for(int i=1;i<=n;i++)
{
Q.push(i);
inq[i]=1;
}
while(Q.size()) {
int u = Q.front();
Q.pop();
inq[u] = 0;
for(int i = 0; i<e[u].size(); i++) {
int v = e[u][i].v, w = e[u][i].w;
if(d[w] > d[v] + d[u]) {
d[w] = d[v] + d[u];
if(!inq[w]) {
Q.push(w);
inq[w] = 1;
}
}
}
}
return d[1];
}
int main()
{
freopen("dwarf.in","r",stdin);
freopen("dwarf.out","w",stdout);
int x,y,z;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&d[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
e[y].push_back(edge(z,x));
e[z].push_back(edge(y,x));
}
int sum=SPFA();
printf("%d\n",sum);
}