题目如下
![](https://i-blog.csdnimg.cn/blog_migrate/9f11d88179a747201da098c249e878a1.png)
解题思路
认真阅读后发现是一道诈骗题,如果从1号到n号有不用的路,那一开始就炸掉,让第一条路变成1,走完第一条路,第一条路也就没有用了(无情抛弃),炸掉使第二条路变1。
所以就分成两种情况:
有不用的路:答案为走的边数。
没有不用的路:答案为n-2+第一条路的权重。
所以直接BFS即可,但是不想打BFS于是用了最短路算法,Dijkstra 算法
可以参考我之前的文章:专题三图论单源最短路
读入时记住和1号相连的边权。
然后将全部边权输入1。
输出的时候分辨一下是哪种情况即可
#include <bits/stdc++.h>
using namespace std;
const int maxn = 412345;
struct edge {
int v, w;
};
struct node {
int dis, u;
bool operator>(const node &a) const {
return dis > a.dis;
}
};
vector<edge> e[maxn];
int dis[maxn], vis[maxn];
priority_queue<node, vector<node>, greater<node> > q;
void dijkstra(int n, int s) {
memset(dis, 63, sizeof(dis));
dis[s] = 0;
q.push({0, s});
while (!q.empty()) {
int u = q.top().u;
q.pop();
if (vis[u])
continue;
vis[u] = 1;
for (auto ed : e[u]) {
int v = ed.v, w = ed.w;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
q.push({dis[v], v});
}
}
}
}
int main() {
int n, m,t;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if(a==1||b==1)
t=c;
e[a].push_back({b,1});
e[b].push_back({a,1});
}
dijkstra(n, 1);
if(dis[n]==m)
{
printf("%d",m-1+t);
}
else printf("%d", dis[n]);
}