题意:给你一些路径,每次换路径的id时加收一块,求到终点所需的最少钱
思路:用Dijkstra跑一遍所有路径,从某条边到另一条边如果遇到不同的路径的时候cost+1,遇到相同的保留该cost
如果只是普通的跑会TLE,这时候我们需要用动态数组来存遍,以便在某个点时访问所有路径时候快点,还需要一个优先队列进行bfs操作
代码:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int vis[200005];
int cost[200005];
struct qnode
{
int v;
int c;
int nowline;
bool operator <(const qnode &r)const
{
return c>r.c;
}
};
struct Edge
{
int v,id;
Edge(int _v=0,int _id=0):v(_v),id(_id) {}
};
vector<Edge>E[200005];
void init(){
for(int i=0;i<=200005;i++){
vis[i]=0;
cost[i]=INF;
E[i].clear();
}
}
int main(){
int n,m;
while(~scanf("%d %d",&n,&m)){
init();
int d=0;
for(int i=1;i<=m;i++){
int a,b,id;
scanf("%d %d %d",&a,&b,&id);
E[a].push_back(Edge(b,id));
E[b].push_back(Edge(a,id));
}
priority_queue<qnode>que;
while(!que.empty())que.pop();
cost[1]=0;
que.push((qnode){1,0,-1});
qnode tmp;
while(!que.empty()){
tmp=que.top();
que.pop();
int x=tmp.v;
if(vis[x]){
continue;
}
vis[x]=1;
for(int i=0;i<E[x].size();i++){
int v=E[tmp.v][i].v;
int mark=0;
if(E[x][i].id!=tmp.nowline){
mark=1;
}
else{
mark=0;
}
if(!vis[v] && cost[v]>cost[x]+mark){
cost[v]=cost[x]+mark;
que.push((qnode){v,cost[v],E[x][i].id});
}
}
}
if(cost[n]>=INF){
printf("-1\n");
}
else{
printf("%d\n",cost[n]);
}
}
}