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;
}