题意:
解法:
直接dj最短路,对每个点开一个set,用s[x]存到达点x的所有最短路中,每种公司的编号.
转移的时候只需要判断s[x]中是否存在当前边的公司编号,如果存在那么不需要花费,否则需要花费1.
---
但是这题我小根堆,每次往里面丢入{d[v],v},结果wa了几个点,
根据别人的ac代码,发现用大根堆,每次往里面丢{-d[v],v},这样就ac了.
很奇怪,所以我怀疑这个算法可能是加算法.
code:
#include <bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=2e6+5;
vector<PI>g[maxm];
set<int>s[maxm];
int mark[maxm];
int d[maxm];
int n,m;
void dj(int st){
priority_queue<PI,vector<PI>,less<PI> >q;
for(int i=1;i<=n;i++){
d[i]=1e18;
mark[i]=0;
}
d[st]=0;
q.push({d[st],st});
while(q.size()){
int x=q.top().second;q.pop();
if(mark[x])continue;
mark[x]=1;
for(auto i:g[x]){
int v=i.first,w=(!s[x].count(i.second));
if(d[v]>d[x]+w){
d[v]=d[x]+w;
q.push({-d[v],v});
s[v].clear();
s[v].insert(i.second);
}else if(d[v]==d[x]+w){
s[v].insert(i.second);
}
}
}
}
void solve(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c;cin>>a>>b>>c;
g[a].push_back({b,c});
g[b].push_back({a,c});
}
dj(1);
int ans=d[n];
if(ans==1e18)ans=-1;
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}
版权声明:本文为weixin_44178736原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。