- 题目大意
如题所示获得一个物品有两种方式:
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 ",sum); }