直接建图利用最短路算法去搞。
这里首先说一下最短路的几种算法以及各自的用途:
迪杰斯特拉算法:求单源最短路的算法,要求图中不能有负边,否则就破坏了这个算法的贪心策略。
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;
}

京公网安备 11010502036488号