hdu-6705 path (全圖第k短路 優先隊列)

hdu-6705 path

題意:給你有向圖,求第k短路的路徑的長度(所有路徑不限制使用次數)

思路:從多校羣裏搞到的。

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <map>
#include <iterator>
#include <vector>
#include <set>
#include <bitset>
#include <stack>
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=5e4+10;
struct node
{
    ll to,len;
    node() {}
    node(ll a,ll b):to(a),len(b) {}

};
struct cmp
{
    bool operator () (const node &x,const node &y) const
    {
        return x.len>y.len;
    }
};
bool cmp1(node a,node b)
{
    return a.len<b.len;
}
priority_queue<node,vector<node>,cmp> q0;
priority_queue<int,vector<int>,less<int> >q1;///從大到小排
vector<node>ve[N];
ll a[N];
ll b[N];
void init(int n)
{
    while(!q1.empty())
        q1.pop();
    while(!q0.empty())
        q0.pop();
    for(int i=1; i<=n; i++)
        ve[i].clear();
}
int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        ll n,m,k;
        scanf("%lld%lld%lld",&n,&m,&k);
        init(n);
        for(ll i=1; i<=m; i++)
        {
            ll u,v,w;
            scanf("%lld%lld%lld",&u,&v,&w);
            q0.push({v,w});
            q1.push(w);
            ve[u].push_back(node(v,w));
        }
        for(ll i=1; i<=n; i++)///排序 從小到大
            sort(ve[i].begin(),ve[i].end(),cmp1);
        ll mx=0;
        for(ll i=0; i<k; i++)
        {
            scanf("%lld",&a[i]);
            mx=max(mx,a[i]);///找出最大的詢問
        }
        for(ll i=1; i<=mx; i++)
        {
            b[i]=q0.top().len;
            ll x=q0.top().to;
            q0.pop();
            for(int j=0; j<ve[x].size(); j++)
            {
                ll y=ve[x][j].to,len=b[i]+ve[x][j].len;
                if(q1.size()==mx)///如果已經有mx條
                {
                    if(len>q1.top())///判斷該路線長度和目前最長長度比較
                        break;
                    else
                    {
                        q1.pop();///比隊頭要小 出隊 進隊 
                        q1.push(len);
                        q0.push({y,len});
                    }
                }
                else
                {
                    q1.push(len);
                    q0.push({y,len});
                }
            }
        }
        for(ll i=0; i<k; i++)
            printf("%lld\n",b[a[i]]);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章