1 条题解

  • 0
    @ 2026-6-18 15:16:51

    // 最短路树 Dijkstra 算法 O(MlogN)
    #include<bits/stdc++.h>
    #define ll long long
    #define pli pair<ll,int>
    using namespace std;
    
    const int N=3e5+5;
    int h[N],to[N<<1],ne[N<<1],idx; ll ww[N<<1];
    void add(int u,int v,ll w){
      to[++idx]=v;ww[idx]=w;ne[idx]=h[u];h[u]=idx;
    }
    int n,m,s;
    int pre[N]; bool vis[N];
    ll d[N];
    
    void dijkstra(int s){
      memset(d,0x3f,sizeof(d)); d[s]=0;
      priority_queue <pli,vector<pli>,greater<pli> > q;
      q.push({0,s});
      while(!q.empty()){
        int u=q.top().second;q.pop();
        if(vis[u])continue; vis[u]=1;
        for(int i=h[u];i;i=ne[i]){
          int v=to[i],w=ww[i];
          if(d[v]>d[u]+w){
            d[v]=d[u]+w;
            pre[v]=i; //保存前驱边
            q.push({d[v],v});
          }
          if(d[v]==d[u]+w && w<ww[pre[i]]) pre[v]=i; //保存前驱边
        }
      }
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(int i=1,x,y,z;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
      }
      scanf("%d",&s);
      
      dijkstra(s);
      ll sum=0;
      for(int i=1;i<=n;i++)if(i!=s)sum+=ww[pre[i]]; //计算最短路树的边权和
      printf("%lld\n",sum);
      for(int i=1;i<=n;i++)if(i!=s)printf("%d ",(pre[i]+1)/2);
    }
    
    // 最短路树 Dijkstra 算法 O(MlogN)
    #include<bits/stdc++.h>
    #define ll long long
    #define pli pair<ll,int>
    using namespace std;
    
    const int N=3e5+5;
    int h[N],to[N<<1],ne[N<<1],idx; ll ww[N<<1];
    void add(int u,int v,ll w){
      to[++idx]=v;ww[idx]=w;ne[idx]=h[u];h[u]=idx;
    }
    int n,m,s;
    int pre[N]; bool vis[N];
    ll d[N];
    
    void dijkstra(int s){
      memset(d,0x3f,sizeof(d)); d[s]=0;
      priority_queue <pli,vector<pli>,greater<pli> > q;
      q.push({0,s});
      while(!q.empty()){
        int u=q.top().second;q.pop();
        if(vis[u])continue; vis[u]=1;
        for(int i=h[u];i;i=ne[i]){
          int v=to[i],w=ww[i];
          if(d[v]>=d[u]+w){
            d[v]=d[u]+w;
            pre[v]=i; //保存前驱边
            q.push({d[v],v});
          }
        }
      }
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(int i=1,x,y,z;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
      }
      scanf("%d",&s);
      
      dijkstra(s);
      ll sum=0;
      for(int i=1;i<=n;i++)if(i!=s)sum+=ww[pre[i]]; //计算最短路树的边权和
      printf("%lld\n",sum);
      for(int i=1;i<=n;i++)if(i!=s)printf("%d ",(pre[i]+1)/2);
    }
    
    • 1

    D92【模板】最短路径树 Dijkstra 算法 CF545E Paths and Trees

    信息

    ID
    12503
    时间
    200ms
    内存
    300MiB
    难度
    10
    标签
    递交数
    6
    已通过
    3
    上传者