万卷网 > 题目详情
题型:组合题

次短路。已知有一个n个点m条边的有向图G,并且给定图中的两个点s和t,求次短路(长度严格大于最短路的最短路径)。如果不存在,输出一行“-1”。如果存在,输出两行,第一行表示此段路经的长度,第二行表示此段路的一个方案。

#include <cstdio>
#include <queue>
#include <utility>
#include <cstring>
using namespace std;

const int maxn = 2e5 + 10, maxm = 1e6 + 10, inf = 522133279;

int n, m, s, t;
int head[maxn], nxt[maxm], to[maxm], w[maxm], tot = 1;
int dis[maxn << 1], *dis2;
int pre[maxn << 1], *pre2;
bool vis[maxn << 1];

void add(int a, int b, int c) {
    ++tot;
    nxt[tot] = head[a];
    to[tot] = b;
    w[tot] = c;
    head[a] = tot;
}

bool upd(int a, int b, int d, priority_queue<pair<int, int> > &q) {
    if (d >= dis[b])return false;
    if (b < n)  ( ① );
    q.push( ② );
    dis[b] = d;
    pre[b] = a;
    return true;
}

void solve() {
    priority_queue<pair<int, int> >q;
    q.push(make_pair(0, s));
    memset(dis,  ( ③ ), sizeof(dis));
    memset(pre, -1, sizeof(pre));
    dis2 = dis + n;
    pre2 = pre + n;
    dis[s] = 0;

    while (!q.empty()) {
        int aa = q.top().second;q.pop();
        if (vis[aa])continue;
        vis[aa] = true;
        int a = aa % n;
        for (int e = head[a]; e; e = nxt[e]) {
            int b = to[e], c = w[e];
            if (aa < n) {
                if (!upd(a, b, dis[a] + c, q))
                   ( ④ );
            }
            else {
                upd(n + a, n + b, dis2[a] + c, q);
            }
        }
    }
}

void out(int a) {
    if (a != s) {
        if (a < n)
            out(pre[a]);
        else
            out( ⑤ );
    }
    printf("%d%c", a % n + 1, " \n"[a == n + t]);
}

int main() {
    scanf("%d%d%d%d", &n, &m,&s,&t);
    s--, t--;
    for (int i = 0; i < m; i++) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a - 1, b - 1, c);
    }
    solve();
    if (dis2[t] == inf)
        puts("-1");
    else {
        printf("%d\n", dis2[t]);
        out(n + t);
    }
    return 0;
}
(1).

⑤处应填()

A.

pre2[a%n]

B.

pre[a%n]

C.

pre2[a]

D.

pre[a%n]+1

(2).

④处应填()

A.

upd(a,n+b,dis[a]+c,q)

B.

upd(n+a,n+b,dis2[a]+c.q)

C.

upd(n+a,b,dis2[a]+c,q)

D.

upd(a,b,dis[a]+c,q)

(3).

③处应填()

A.

0xff

B.

0x1f

C.

0x3f

D.

0x7f

(4).

①处应填()

A.

udp(pre[b],n+b,dis[b],q)

B.

upd(a,n+b,d,q)

C.

upd(pre[b],b,dis[b],q)

D.

upd(a,b,d,q)

(5).

②处应填()

A.

make_pair(-d,b)

B.

make_pair(d,b)

C.

make_pair(b,d)

D.

make_pair(-b,d)

更新时间:2025-06-17 18:11:37 |
【知识点】 CCF非专业级别软件能力认证CSP-S/提高级

相似题推荐

简答题

T4员工招聘

2026-04-17
简答题

T1社团招新

2026-04-17
简答题

T2道路修复

2026-04-17
简答题

T3谐音替换

2026-04-16
单选题

对一个大小为16(下标0-15)的数组构建满线段树,查询区间[3,11]时,最少需要访问多少个树结点(包括路径上的父结点和完全包含在查询区间内的结点)?

A.

7

B.

8

C.

9

D.

10

2025-10-17
公众号
客服 反馈
顶部