题目
https://vjudge.net/contest/325065#problem/D
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define max(a,b) a > b ? a : b
#define min(a,b) a < b ? a : b
#define me(a,b) memset(a, b, sizeof(a))
#define iosos ios::sync_with_stdio(false)
#define fo(a,b,c) for(int a = b; a < c; a++)
using namespace std;
const int maxn = 1e5 + 10;
const int maxm = maxn << 1;
const int inf = 0x7f7f7f7f;
const double eps = 1e-6;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
struct edge {
ll u, v, dis, cur;
edge(ll a, ll b, ll c, ll d) {
u = a, v = b, dis = c;
cur = d;
}
bool operator < (const edge &b) const {
return dis > b.dis;
}
};
vector G[maxn];
int query[maxn];
int maxquery = 0;
ll ans[maxn], cnt;
int n, m, q;
void bfs() {
priority_queue q;
while(!q.empty()) q.pop();
for(int i = 1; i <= n; i++) {
if(G[i].size() > 0) {
q.push(edge(i, G[i][0].v, G[i][0].dis,1));
}
}
cnt = 0;
while(!q.empty()) {
edge u = q.top();
q.pop();
ans[++cnt] = u.dis;
if(cnt >= maxquery) break;
int v = u.v;
if(u.cur + 1 <= G[u.u].size()) {
q.push(edge(u.u, G[u.u][u.cur].v, u.dis - G[u.u][u.cur - 1].dis + G[u.u][u.cur].dis, u.cur + 1));
} //跟新末尾的u->v的u的下一条边
if(G[u.v].size() > 0) {
q.push(edge(u.v, G[u.v][0].v, u.dis + G[u.v][0].dis,1));
} //延长边,选v下面最小的边
}
}
bool cmp(const edge &a, const edge &b) {
return a.dis < b.dis;
}
int main() {
int t = read();
while(t--) {
n = read(), m = read(), q =read();
for(int i = 1; i <= n; i++) {
G[i].clear();
}
for(int i = 0; i < m; i++) {
int u , v, l;
u = read(), v = read(), l = read();
G[u].push_back(edge(u, v, l, 0));
}
for(int i = 1; i <= n; i++) {
sort(G[i].begin(), G[i].end(), cmp);
}
maxquery = -1;
for(int i = 1; i <= q; i++) {
query[i] = read();
maxquery = max(maxquery, query[i]);
}
bfs();
for(int i = 1; i <= q; i++) {
printf("%lld\n", ans[query[i]]);
}
}
return 0;
}