题目链接
题解:
直接优先队列 bfs 将每条出边都压入队列会因为边数太多而 MLE,所以考虑一下减少放入队列的边。会发现每次只用压入两条边进队列。
首先将每个点边权最小的出边加入优先队列,然后 bfs 时每 pop 出一条边就将出点是这条边的点的下一条出边压入队列,同时将连接这条边的最短的边也压入队列进行 bfs 即可。
具体的优先队列中维护四个值:这条边作为出边的编号、这条边作为出边的点的编号、这条边到达的点的编号、目前为止的距离。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define PI acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
#define P pair<ll, int>
#define debug(x) cout << (#x) << ": " << (x) << " "
#define fastio ios::sync_with_stdio(false), cin.tie(0)
const int mod = 1e9 + 7;
const int M = 15 + 10;
const int N = 50000 + 10;
int t, n, m, q;
struct node {
int id, now, to, dis;
bool operator < (const node &cmp) const {
return dis > cmp.dis;
}
} ;
priority_queue<node> que;
vector<P> G[N];
int mxk, k[N], ans[N];
void bfs()
{
int cnt = 0;
while(que.size()) {
node tp = que.top(), temp;
que.pop();
ans[++cnt] = tp.dis;
if(cnt >= mxk) break;
if(tp.id + 1 < G[tp.now].size()) {
temp.dis = tp.dis - G[tp.now][tp.id].first + G[tp.now][tp.id + 1].first;
temp.id = tp.id + 1;
temp.now = tp.now;
temp.to = G[tp.now][tp.id + 1].second;
que.push(temp);
}
if(G[tp.to].size()) {
temp.dis = tp.dis + G[tp.to][0].first;
temp.id = 0;
temp.now = tp.to;
temp.to = G[tp.to][0].second;
que.push(temp);
}
}
}
signed main()
{
scanf("%d", &t);
while(t --) {
while(que.size()) que.pop();
scanf("%d %d %d", &n, &m, &q);
for(int i = 1; i <= n; i ++) G[i].clear();
for(int i = 1; i <= m; i ++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
G[u].push_back({w, v});
}
for(int i = 1; i <= n; i ++) {
if(G[i].size()) {
sort(G[i].begin(), G[i].end());
que.push({0, i, G[i][0].second, G[i][0].first});
}
}
mxk = 0;
for(int i = 1; i <= q; i ++) {
scanf("%d", &k[i]);
mxk = max(mxk, k[i]);
}
bfs();
for(int i = 1; i <= q; i ++) {
printf("%d\n", ans[k[i]]);
}
}
return 0;
}
/*
Rejoicing in hope, patient in tribulation.
*/
/*
,----------------, ,---------,
,-----------------------, ," ,"|
," ,"| ," ," |
+-----------------------+ | ," ," |
| .-----------------. | | +---------+ |
| | | | | | -==----`| |
| | | | | | | |
| | Accepted _ | | |/----|`---= | |
| | | | | ,/|==== OOO | ;
| | | | | // |(((( [33]| ,"
| `-----------------` |," .//| |(((( | ,"
+-----------------------+ // | | |,"
/_)______________(_/ //` | +---------+
___________________________/___ `,
/ oooooooooooooooo .o. oooo /, \,"-----------
/ ==ooooooooooooooo==.o. ooo= // ,`\--{)B ,"
/_==__==========__==_ooo__ooo=_/` /___________,"
*/