这是一个很好的 最短路的问题 。 很好。
题意: 给你n 个商品 m 中换法 a,b,c a可以用 b 或者c 来换 当然 也可以花钱买。 问你 想要得到1的最小花费。
思路: 其实如果抽象一下 就是一个 边权 可以改变的最短路问题。 既然 c 和 b 可以换来a 那么如果我们知道 c和b 的花费
比 a 的花费小的话 , 那么我们就可以 用b 和 c 来松弛 a 那么就相当于 从 c 建一条 边权为b的花费 的路 走到a ,也相当于 从b 建一条 c的花费的 路到a , 那么再想 如果 a 被 松弛过了 ,那么他是否也可以去松弛别的点呢。 答案是肯定的。 所以我们这里就可以用 spfa 去不断地松弛每一点。
代码:
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
#define M 100005
#define N 10005
using namespace std;
typedef long long ll;
const ll inf=1e18+5;
struct node
{
int u,v;
};
int cnt;
int head[N];
vector< node >ve[N];
int vis[N];//,dis[N];
int n,m;
ll c[N];
/*
void add(int u,int v1,int v2)
{
edge[++cnt].v1=v1;
edge[cnt].v2=v2;
edge[cnt].next=head[u];
head[u]=cnt;
return ;
}*/
void spfa()
{
queue< int >q;
int u,v1,v2;
for(int i=1;i<=n;i++)
{
q.push(i);
vis[i]=1;
}
while(!q.empty())
{
u=q.front(); q.pop();
vis[u]=0;
//printf("u: %d \n",u);
int sz=ve[u].size();
for(int i=0;i<sz;i++)
{
int v=ve[u][i].v;
int w=c[ve[u][i].u];
if(c[v]>c[u]+w)
{
c[v]=c[u]+w;
if(vis[v]==0)
{
vis[v]=1;
q.push(v);
}
}
}
}
return ;
}
int main()
{
freopen("dwarf.in","r",stdin);
freopen("dwarf.out","w",stdout);
cin>>n>>m;
int u,v1,v2;
cnt=0;
memset(head,-1,sizeof(head));
//memset(dis,inf ,sizeof(dis));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) cin>>c[i];
node tmp;
for(int i=1;i<=m;i++)
{
cin>>u>>v1>>v2;
tmp.u=v1; tmp.v=u;
ve[v2].push_back(tmp);
tmp.u=v2;
ve[v1].push_back(tmp);
//ve.push_back(u);
//add(u,v1,v2);
}
spfa();
printf("%lld\n",c[1]);
return 0;
}