tle2,3,6求解

P4779 【模板】单源最短路径(标准版)

elpsconr @ 2024-04-08 01:49:06

tle三个点,求改进优化dijkstra堆优化的方式。

#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
const int N=2e5+6;
int n,m,s,idx;
int e[N<<1],h[N],w[N<<1],ans[N],ne[N<<1];
bool st[N];
void add(int a,int b,int c)
{
    e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;
}
void dijkstra(int x)
{
  priority_queue<PII,vector<PII>,greater<PII> > q;
  q.push({0,x});st[x]=1;
  while(!q.empty())
  {
    int ww=q.top().second;q.pop();
    for(int i=h[ww];~i;i=ne[i])
    {
        int j=e[i];
        if(ww==j) continue;
        if(ans[j]>ans[ww]+w[i]) 
        {
            ans[j]=ans[ww]+w[i];
            if(!st[j]) q.push({ans[j],j});
        }
    }
  }
}
int main()
{
    memset(ans,0x3f,sizeof ans);
    memset(st,0,sizeof st);
    memset(h,-1,sizeof h);
    cin>>n>>m>>s;
    ans[s]=0;
    for(int i=1;i<=m;++i)
    {
       int u,v,r;cin>>u>>v>>r;
       add(u,v,r);
    }
    dijkstra(s);
    for(int i=1;i<=n;++i)
    cout<<ans[i]<<" ";
    return 0;
}

by ricky2009 @ 2024-04-08 09:09:03

可以看出比起上一个提问有了很大进步啊

但问题是你 st 数组根本没打标记啊

一个点最多能出队 m 次了,T飞正常

最后一个问题是每次修改完权值后都要加一遍堆啊,不然怎么保证节点出队先后顺序啊


by elpsconr @ 2024-04-08 20:16:28

@ricky2009 感谢确实是这样,不过还有一点我不清楚,为什么st[j]加标记,输出并不是最短路径了,样例答案变成0 2 5 4


by ricky2009 @ 2024-04-08 22:12:42

我不知道你现在的代码是怎样的,下面只是我的猜测

比如说你入堆的时候的 ans 先后顺序和实际顺序不一样,然后出队的时候会发生用到达该点的非最短路更新相邻节点的最短路的情况 , 会导致相邻节点的最短路错误


by ricky2009 @ 2024-04-08 22:18:47

@elpsconr


|