ARC061 E – Snuke‘s Subway Trip(思维+最短路),可能是假算法

  • Post author:
  • Post category:其他




题意:

在这里插入图片描述

在这里插入图片描述



解法:

直接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 版权协议,转载请附上原文出处链接和本声明。