1 条题解

  • 1
    @ 2021-8-7 21:07:51

    C++ :

    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    
    
    using namespace std;
    
    typedef pair<int, int> PII;
    typedef pair<int, PII> PIII;
    const int N = 1001, M = 200001;
    
    int n, m, S, T, K;
    int h[N], rh[N], e[M], w[M], ne[M], idx;
    int dist[N], cnt[N];
    bool st[N];
    
    void add(int h[],int a,int b,int c)
    {
        e[idx] = b;
        w[idx] = c;
        ne[idx] = h[a];
        h[a] = idx++;
    }
    
    void dijkstra()
    {
        priority_queue< PII,vector<PII>,greater<PII> > heap;
        heap.push({0,T});//终点
        memset(dist, 0x3f, sizeof dist);
        dist[T] = 0;
    
        while(heap.size())
        {
            PII t = heap.top();
            heap.pop();
    
            int ver = t.second;
    //        if(st[ver]) continue;
    //        st[ver] = true;
    
            for(int i=rh[ver];i!=-1;i=ne[i])
            {
                int j = e[i];
                if(dist[j]>dist[ver]+w[i])
                {
                    dist[j] = dist[ver] + w[i];
                    heap.push({dist[j],j});
                }
            }
        }
    }
    
    int astar()
    {
        priority_queue< PIII, vector<PIII>, greater<PIII> > heap;
        // 谁的d[u]+f[u]更小 谁先出队列
        heap.push({dist[S], {0, S}});
        while(heap.size())
        {
            PIII t = heap.top();
            heap.pop();
            int ver = t.second.second,distance = t.second.first;
            cnt[ver]++;
            //如果终点已经被访问过k次了 则此时的ver就是终点T 返回答案
    
            if(cnt[T]==K) return distance;
    
            for(int i=h[ver];i!=-1;i=ne[i])
            {
                int j = e[i];
                if(cnt[j] < K)
                {
                    // 按 真实值+估计值 = d[j]+f[j] = dist[S,t] + w[t][j] + dist[j,T] 堆排
                    // 真实值 distance+w[i]
                    heap.push({distance+w[i]+dist[j],{distance+w[i],j}});
                }
            }
        }
        // 终点没有被访问k次
        return -1;
    }
    
    int main()
    {
        cin >> n >> m;
        memset(h,-1,sizeof h);
        memset(rh,-1,sizeof rh);
        while(m--)
        {
            int a,b,c;
            cin >> a >> b >> c;
            add(h,a,b,c);
            add(rh,b,a,c);
        }
        cin >> S >> T >> K;
        // 起点==终点时 则d[S→S] = 0 这种情况就要舍去 ,总共第K大变为总共第K+1大
        if (S == T) K ++ ;
        // 从各点到终点的最短路距离 作为估计函数f[u]
        dijkstra();
        cout << astar();
        return 0;
    }
    
    
    • 1

    信息

    ID
    89
    时间
    1000ms
    内存
    128MiB
    难度
    1
    标签
    递交数
    31
    已通过
    30
    上传者