直接建图利用最短路算法去搞。
这里首先说一下最短路的几种算法以及各自的用途:
迪杰斯特拉算法:求单源最短路的算法,要求图中不能有负边,否则就破坏了这个算法的贪心策略。
SPFA:也是求单源最短路的算法,这个算法在图中有负边的时候可以用,一般如果图中没有负边不用,毕竟是将图中所有点都更新到最短的方式,时间复杂度较大。
弗洛伊德算法:求全部最短路的,如果要求两两之间的最短路用它。
那么这道题就是一个建边的问题了,要注意会出重复的边,要注意保留短边。
//图论问题,通过不同层去建立不同层之间的连线,然后还有特殊连线。将图建立起来之后利用Dijkstra算法即可
//可以用hash去保存每个层里面的点编号,然后直接连线即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int n, m, c;
//只用链式前向星存图
struct sy{
    int to;
    int next;
    int w;
} edge[maxn*10];
int head[maxn*10];
int cnt = 0;
struct Node {
    int number;
    int len;
    bool operator < (const Node& n) const
    {
        return len>n.len;
    }
};
priority_queue<Node> pq;
int ans[maxn];
int bianhao[maxn];
bool vis[maxn];
vector<int> mp[maxn];
map<pair<int, int>, int> mpr;

void add_edge(int x, int y, int w)
{
    edge[++cnt].next = head[x];
    edge[cnt].to = y;
    edge[cnt].w = w;
    head[x] = cnt;
}

void Dijkstra(int bg)
{
    memset(ans, 127, sizeof(ans));
    pq.push({bg, 0});
    ans[bg] = 0;
    while (pq.size())
    {
        int number = pq.top().number;
        pq.pop();
        if (vis[number]) continue;
//         cout<<"number="<<number<<endl;
        vis[number] = true;
        for (int i=head[number];i;i = edge[i].next)
        {
            int to = edge[i].to;
            int w = edge[i].w;
            if (ans[number]+w<ans[to])
            {
                ans[to] = ans[number]+w;
//                 cout<<"to="<<to<<" ans[to]="<<ans[to]<<endl;
                pq.push({to, ans[to]});
            }
        }
    }
    if (ans[n]>=2139062143) cout<<-1;
    else
        cout<<ans[n];
}

int main()
{
    int x, y, w;
    int l;
    cin>>n>>m>>c;
    for (int i=1;i<=n;i++)
    {
        cin>>l;
        mp[l].push_back(i);
        bianhao[i] = l;
    }
    //将层级之间连线
    for (int i=1;i<=n;i++)
    {
        int layer = bianhao[i];
        for (int j=0;j<mp[layer-1].size();j++)
        {
            mpr[{i,mp[layer-1][j]}] = c;
        }
        for (int j=0;j<mp[layer+1].size();j++)
        {
            mpr[{i, mp[layer+1][j]}] = c;
        }
    }
    //为额外的边建立
    for (int i=1;i<=m;i++)
    {
        cin>>x>>y>>w;
        if (mpr[{x,y}]!=0)
        {
            mpr[{x,y}] = min(mpr[{x,y}], w);
        }
        else
        {
            mpr[{x,y}] =  w;
        }
        if (mpr[{y,x}]!=0)
        {
            mpr[{y,x}] = min(mpr[{y,x}], w);
        }
        else
        {
            mpr[{y,x}] =  w;
        }
    }
    //遍历边开始建图
    map<pair<int, int>, int>::iterator it;
    for (it = mpr.begin();it!=mpr.end();it++)
    {
//         cout<<(*it).first.first<<' '<<(*it).first.second<<endl;
        add_edge((*it).first.first, (*it).first.second, (*it).second);
    }
    //开始迪杰斯特拉求最短路
    Dijkstra(1);
    
    return 0;
}