【问题描述】
Vasya在玩一个叫做”Dwarf Tower”的游戏,这个游戏中有n个不同的物品,它们的编号为1到n。
现在Vasya想得到编号为1的物品。
获得一个物品有两种方式:
1. 直接购买该物品,第i件物品花费的钱为ci
2. 用两件其他物品合成所需的物品,一共有m种合成方式。
请帮助Vasya用最少的钱获得编号为1的物品。
【输入格式】
第一行有两个整数n,m(1<=n<=10000,0<=m<=100000),分别表示有n种物品以及m种合成方式。
接下来一行有n个整数,第i个整数ci表示第i个物品的购买价格,其中0<=ci<=10^9。
接下来m行,每行3个整数ai,xi,yi,表示用物品xi和yi可以合成物品ai。
其中(1<=ai,xi,yi<=n; ai<>xi, xi<>yi, yi<>ai)
【输出格式】
一行,一个整数表示获取物品 1 的最少花费。
输入样例:
5 3
5 0 1 2 5
5 2 3
4 2 3
1 4 5
输出样例:
2
【数据规模与约定】
60%的数据,n<=100
100%的数据,n<=10000,m<=100000
spfa
不断更新
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<climits>
#include<string>
#include<cstdlib>
#include<ctime>
#include<map>
#define LL long long
#define MOD 1000000007
using namespace std;
int cnt,val[200005],c[200005],p[200005],num[200005],nxt[200005],head[200005],n,m,i,a,x,y,dis[200005];
int h,t,ans,poi[200005],vis[200005];
void add(int p1,int p2,int p3)
{
cnt++;
p[cnt]=p3;
num[cnt]=p2;
nxt[cnt]=head[p1];
head[p1]=cnt;
}
int main()
{
freopen("dwarf.in","r",stdin);
freopen("dwarf.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&dis[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&x,&y);
add(x,a,y);
add(y,a,x);
}
h=1;
t=1;
poi[h]=1;
vis[1]=1;
for(i=2;i<=n;i++)
{
t++;
poi[t]=i;
vis[i]=1;
}
while(h<=t)
{
int hed=poi[h];
for(i=head[hed];i;i=nxt[i])
if(dis[num[i]]>dis[hed]+dis[p[i]])
{
dis[num[i]]=dis[hed]+dis[p[i]];
if(!vis[num[i]])
{
t++;
poi[t]=num[i];
vis[num[i]]=1;
}
}
vis[hed]=0;
h++;
}
printf("%d",dis[1]);
return 0;
}