首页 > 其他分享 >观光 最短路次短路

观光 最短路次短路

时间:2024-08-01 16:52:25浏览次数:11  
标签:distance cnt dist idx int 短路 观光 push

// 观光.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


/*

https://www.acwing.com/problem/content/description/385/
“您的个人假期”旅行社组织了一次比荷卢经济联盟的巴士之旅。

比荷卢经济联盟有很多公交线路。

每天公共汽车都会从一座城市开往另一座城市。

沿途汽车可能会在一些城市(零或更多)停靠。

旅行社计划旅途从 S 城市出发,到 F 城市结束。

由于不同旅客的景点偏好不同,所以为了迎合更多旅客,旅行社将为客户提供多种不同线路。

游客可以选择的行进路线有所限制,要么满足所选路线总路程为 S 到 F 的最小路程,
要么满足所选路线总路程仅比最小路程多一个单位长度。

3463_1.png

如上图所示,如果 S=1,F=5,则这里有两条最短路线 1→2→5,1→3→5,长度为 6;有一条比最短路程多一个单位长度的路线 1→3→4→5,长度为 7。

现在给定比荷卢经济联盟的公交路线图以及两个城市 S 和 F,请你求出旅行社最多可以为旅客提供多少种不同的满足限制条件的线路。

输入格式
第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含两个整数 N 和 M,分别表示总城市数量和道路数量。

接下来 M 行,每行包含三个整数 A,B,L,表示有一条线路从城市 A 通往城市 B,长度为 L。

需注意,线路是 单向的,存在从 A 到 B 的线路不代表一定存在从 B 到 A 的线路,另外从城市 A 到城市 B 可能存在多个不同的线路。

接下来一行,包含两个整数 S 和 F,数据保证 S 和 F 不同,并且 S、F 之间至少存在一条线路。

输出格式
每组数据输出一个结果,每个结果占一行。

数据保证结果不超过 109。

数据范围
2≤N≤1000,
1≤M≤10000,
1≤L≤1000,
1≤A,B,S,F≤N
输入样例:
2
5 8
1 2 3
1 3 2
1 4 5
2 3 1
2 5 3
3 4 2
3 5 4
4 5 3
1 5
5 6
2 3 1
3 2 1
3 1 10
4 5 2
5 2 7
5 2 7
4 1
输出样例:
3
2
*/
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 1010, M = 10010;
int n, m, S, T;
struct ELE {
    int id, type, dist;
    bool operator > (const ELE& O) const{
        return dist > O.dist;
    }
};

int h[N], e[M], ne[M], w[M], idx;
int vis[N][2];
int dist[N][2];
int cnt[N][2];



void add(int a, int b, int c) {
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}


int solve() {
    memset(dist, 0x3f, sizeof dist);
    memset(vis, 0, sizeof vis);
    memset(cnt, 0, sizeof cnt);
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b, c; cin >> a >> b >> c;
        add(a, b, c);
    }
    cin >> S >> T;
    priority_queue<ELE, vector<ELE>, greater<ELE>> q;
    q.push({ S,0,0 });
    dist[S][0] = 0; cnt[S][0] = 1;

    while (!q.empty()) {
        auto t = q.top(); q.pop();

        int distance = t.dist; int ver = t.id; 
        int type = t.type; int count = cnt[ver][type];
        if (vis[ver][type] != 0) continue;
        vis[ver][type] = 1;

        for (int i = h[ver]; i != -1; i = ne[i]) {
            int j = e[i];
            if (dist[j][0] > distance + w[i]) {
                dist[j][1] = dist[j][0];
                cnt[j][1] = cnt[j][0];
                q.push({ j,1,dist[j][1] });
                dist[j][0] = distance + w[i];
                cnt[j][0] = count;
                q.push({ j,0,dist[j][0] });
            }
            else if (dist[j][0] == (distance + w[i])) {
                cnt[j][0] += count;
                q.push({ j,0,dist[j][0] });
            }
            else if (dist[j][1]  > (distance + w[i])) {
                dist[j][1] = (distance + w[i]);
                cnt[j][1] = count;
                q.push({ j,1,dist[j][1] });
            }
            else if (dist[j][1] == (distance + w[i])) {
                cnt[j][1] += count;
                q.push({ j,1,dist[j][1] });
            }
        }
    }

    int res = cnt[T][0];
    if (dist[T][0] + 1 == dist[T][1]) res += cnt[T][1];
    cout << res << endl;
    return res;
}


int main()
{
    int t; cin >> t;
    while (t--) {
        memset(h, -1, sizeof h);
        idx = 0;
        solve();
    }
   
 
    return 0;
}

标签:distance,cnt,dist,idx,int,短路,观光,push
From: https://www.cnblogs.com/itdef/p/18336972

相关文章

  • Luogu P1613 跑路 题解 [ 蓝 ] [ 倍增 ] [ Floyd 最短路 ] [ 状压 dp ]
    跑路:绝佳倍增好题,思路是化\(2^k\)为\(1\),倍增起预处理作用。最近不知道是撞了什么运,前一脚看的是绿题,写完之后交一发,发现直接被lxl升蓝了,血赚。思路:Floyd首先观察到每次走\(2^k\)的代价为\(1\),我们可以预处理出每次走\(2^i\)能到哪些点。但为了让这题的代码更好实......
  • 关于最短路、次短路计数
    最短路计数题意给出一个 \(N\) 个顶点 \(M\) 条边的无向无权图,顶点编号为 \(1\) 到 \(N\)。问从顶点 \(1\) 开始,到其他每个点的最短路有几条。分析我们可以用BFS计算出源点\(1\)到其他点的最短距离序列\(dis\),由于BFS弹出队列的顺序是拓扑序,因此在BFS的过......
  • 观光之旅
    //观光之旅.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///**https://www.acwing.com/problem/content/description/346/**给定一张无向图,求图中一个至少包含3个点的环,环上的节点不重复,并且环上的边的长度之和最小。该问题称为无向图的最小环问题......
  • 【变压器的开路和短路试验】提供从开路和短路试验中获得的结果电阻性和感性参数(Simuli
      ......
  • 最短路
    floyd——最短路里玩最花的dij——跑得很快spfa——差分约束&费用流01bfs——边权只有两个时候最快求最小环首先floyd中\(f[i][j][k]\)代表从i到j中间只经过编号小于等于k的节点的最小值。那么我们可以想到一个环满足i-j的优弧(类似这么叫),然后剩下一个点编号大于k,直接加上边权......
  • 【学习笔记】最短路
    【学习笔记】最短路前言:只是对一些最短路算法的实现整理。以下内容有部分摘自OI_wiki。Floyd算法求全源最短路。可以有负边权。Floyd算法的本质是动态规划。设\(dis(k,i,j)\)表示由若干个编号不超过\(k\)的节点中转后从\(i\)到\(j\)的最短路。该“动规”有两......
  • 【MATLAB源码-第159期】基于matlab的胡桃夹子优化算法(NOA)机器人栅格路径规划,输出做短
    操作环境:MATLAB2022a1、算法描述胡桃夹子优化算法(NutcrackerOptimizationAlgorithm,NOA)是一个灵感来源于胡桃夹子的故事的元启发式优化算法。这个故事中,胡桃夹子是一个能够将坚果壳轻易地破开以获取内部果仁的工具。在优化算法的语境下,这个过程被比喻为寻找问题解决方案......
  • 洛谷 模板 单源最短路径(标准版)
    原题p4779题目背景2018年7月19日,某位同学在 NOIDay1T1归程 一题里非常熟练地使用了一个广为人知的算法求最短路。然后呢?100→60;Ag→Cu;最终,他因此没能与理想的大学达成契约。小F衷心祝愿大家不再重蹈覆辙。题目描述给定一个 n 个点,m 条有向边的带非负......
  • 图的最短路径算法(SPFA,Dijkstra,Bellman_Ford)(迪杰斯特拉算法,Spfa算法,贝尔曼-福特算
    目录Dijkstra迪杰斯特拉算法写法时间复杂度例题描述输入描述输出描述样例输入用例输出用例写法Spfa算法例题描述输入描述输出描述样例输入用例输出用例写法Bellman_Ford算法(贝尔曼-福特算法)写法例题描述输入描述输出描述样例输入样例输出样例......
  • 【技巧】0/1最短路
    这是$Dijkstra$。voiddijkstra(intx){ priority_queue<pair<int,int>>que; memset(d,0x3f,sizeof(d)); d[x]=0; que.push({-d[x],x}); while(!que.empty()) { inty=que.top().second; que.pop(); e[y]=true; for(rii=f[y];i;i=way[i].h) { ......