すぬけ君の地下鉄旅行

题目链接:すぬけ君の地下鉄旅行


显然我们可以记录每个状态前一个状态通过的铁路。然后判断这一次边权值。

但是我们不能只用一个状态来记录,因为可能两个状态的dis相等,但是具体用哪个点更新是不确定的。

所以我们需要用set去存一下。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+10,M=1e6+10;
int n,m,d[N],vis[N];
int head[N],nex[M],to[M],w[M],tot;
priority_queue<pair<int,int>> q;	set<int> s[N];
inline void ade(int a,int b,int c){
	to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;
}
inline void add(int a,int b,int c){ade(a,b,c);	ade(b,a,c);}
void Dijkstra(){
	memset(d,inf,sizeof d);	d[1]=0; q.push({0,1});
	while(q.size()){
		int u=q.top().second;	q.pop();
		if(vis[u])	continue;	vis[u]=1;
		for(int i=head[u],val;i;i=nex[i]){
			val=(s[u].find(w[i])!=s[u].end()?0:1);
			if(d[to[i]]>d[u]+val){
				d[to[i]]=d[u]+val;	q.push({-d[to[i]],to[i]});
				s[to[i]].clear();	s[to[i]].insert(w[i]);
			}else if(d[to[i]]==d[u]+val)	s[to[i]].insert(w[i]);
		}
	}
}
signed main(){
	cin>>n>>m;
	for(int i=1,a,b,c;i<=m;i++)	scanf("%d %d %d",&a,&b,&c),add(a,b,c);
	Dijkstra();
	if(d[n]==inf)	d[n]=-1;
	cout<<d[n]<<endl;
	return 0;
}
发布了725 篇原创文章 · 获赞 244 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104736950
今日推荐