HDU 1688 Sightseeing 【输出最短路+次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688

题目大意:给n个点,m条有向边。再给出起点s, 终点t。求出s到t的最短路条数+次短路条数。

思路:

1.最短路和次短路是紧密相连的,在最短路松弛操作中,当我们找到一条更短的路径,也就意味着之前的路径不再是最短路,而成为了次短路,利用这个关系可以实现状态的转移。

2.好久没写优先队列了,都忘记了加个 priority_queue, 这样才能写重载,才能排序。

注释在代码里:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 #define mem(a, b) memset(a, b, sizeof(a))
  5 const int inf = 0x3f3f3f3f;
  6 using namespace std;
  7
  8 int n, m;
  9 int tot, head[1100];
 10 int dis[2][1100], cnt[2][1100];//dis数组记录最短路 0 和次短路 1 距离,cnt数组记录最短路 0 和次短路 1 条数
 11 int vis[2][1100];
 12
 13 struct Edge
 14 {
 15     int to, next;
 16     int w;
 17 }edge[100010];
 18
 19 void add(int a, int b, int w)
 20 {
 21     edge[++ tot].to = b;
 22     edge[tot].w = w;
 23     edge[tot].next = head[a];
 24     head[a] = tot;
 25 }
 26
 27 struct Node//优先队列优化结构体,id为点的序号, dis为源点到该点的距离 p区分属于最短路还是次短路
 28 {
 29     int id, dis, p;
 30     bool operator < (const Node &a)const
 31     {
 32         return dis > a.dis;
 33     }
 34 }node[1100];
 35
 36 void init()
 37 {
 38     mem(head, -1), tot = 0;
 39     mem(vis, 0);  //代表源点到该点的距离未被确定
 40 }
 41
 42 void dij(int s, int t)
 43 {
 44     priority_queue<Node> Q;
 45     while(!Q.empty())
 46         Q.pop();
 47     for(int i = 1; i <= n; i ++) //初始化
 48     {
 49         dis[0][i] = dis[1][i] = inf;
 50         cnt[0][i] = cnt[1][i] = 0;
 51     }
 52     dis[0][s] = 0;
 53     cnt[0][s] = 1;//源点到自己的最短路条数为1
 54     Node temp;
 55     temp.p = 0, temp.dis = 0, temp.id = s;
 56     Q.push(temp);
 57     while(!Q.empty())
 58     {
 59         Node a = Q.top();
 60         Q.pop();
 61         if(vis[a.p][a.id])
 62             continue; //该p状态下已经确定过就跳过
 63         vis[a.p][a.id] = 1;
 64         for(int i = head[a.id]; i != -1; i = edge[i].next)
 65         {
 66             int to = edge[i].to;
 67             if(dis[0][to] > dis[a.p][a.id] + edge[i].w) //最短路可以更新(在0或1状态下找到一条更短的路)
 68             {
 69                 dis[1][to] = dis[0][to];  //原来的最短路成为次短路
 70                 dis[0][to] = dis[a.p][a.id] + edge[i].w;
 71                 cnt[1][to] = cnt[0][to];//次短路条数继承为原来的最短路条数
 72                 cnt[0][to] = cnt[a.p][a.id];
 73                 temp.p = 0, temp.dis = dis[0][to], temp.id = to;
 74                 Q.push(temp);
 75                 temp.p = 1, temp.dis = dis[1][to], temp.id = to;
 76                 Q.push(temp);
 77             }
 78             else if(dis[0][to] == dis[a.p][a.id] + edge[i].w)//最短路长度一样 更新最短路条数即可
 79             {
 80                 cnt[0][to] += cnt[a.p][a.id];
 81             }
 82             else if(dis[1][to] > dis[a.p][a.id] + edge[i].w)//找到一条长度大于最短路但小于当前次短路的路径
 83             {//将这条路变成次短路
 84                 dis[1][to] = dis[a.p][a.id] + edge[i].w;
 85                 cnt[1][to] = cnt[a.p][a.id];
 86                 temp.p = 1, temp.dis = dis[1][to], temp.id = to;
 87                 Q.push(temp);
 88             }
 89             else if(dis[1][to] == dis[a.p][a.id] + edge[i].w)
 90             {
 91                 cnt[1][to] += cnt[a.p][a.id];
 92             }
 93         }
 94     }
 95 }
 96
 97 int main()
 98 {
 99     int T;
100     scanf("%d", &T);
101     while(T --)
102     {
103         init();
104         scanf("%d%d", &n, &m);
105         for(int i = 1; i <= m; i ++)
106         {
107             int a, b, c;
108             scanf("%d%d%d", &a, &b, &c);
109             add(a, b, c);
110         }
111         int s, t;
112         scanf("%d%d", &s, &t);
113         dij(s, t);
114         int ans = cnt[0][t]; //ans代表最短路的条数
115         if(dis[0][t] + 1 == dis[1][t])
116             ans += cnt[1][t];
117         printf("%d\n", ans);
118     }
119     return 0;
120 }

原文地址:https://www.cnblogs.com/yuanweidao/p/10961335.html

时间: 2024-10-03 05:56:07

HDU 1688 Sightseeing 【输出最短路+次短路条数】的相关文章

hdu 1688 Sightseeing【最短路,次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:求最短路和次短路条数如果次短路长度=最短路长度+1 这输出次短路条数+最短路条数,否则输出最短路条数 分析:这是到模版题,献上模版: #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<

HDU 1688 Sightseeing

题目链接:Sightseeing 题意:求最短路和比最短路长度+1的所有路径条数. 附代码:用数组记录最短和次短路径的长度和条数,一次更新,直到没有边可以更新. #include <stdio.h> #include <string.h> #include <iostream> #include <vector> using namespace std; #define maxn 1010 struct Node { int to, val; Node(in

HDU1688 Sightseeing(SPFA 求最短路与次短路的路径条数)可用作模板

Sightseeing Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 718    Accepted Submission(s): 293 Problem Description Tour operator Your Personal Holiday organises guided bus trips across the Bene

HDU 3191 次短路长度和条数

http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html http://blog.csdn.net/me4546/article/details/6584448 维护最短路长度d[i][0]和次短路d[i][1],最短路条数dp[i][0]和次短路dp[i][1] #include <iostream> #include <string> #include <cstring> #include <cs

hdu 1688 Sightseeing (最短路径)

Sightseeing Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 639    Accepted Submission(s): 249 Problem Description Tour operator Your Personal Holiday organises guided bus trips across the Benel

POJ 3255 &amp;&amp; HDU 1688 &amp;&amp; HDU 3191 次短路问题

POJ 3255 Roadblocks Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7627   Accepted: 2798 Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old h

POJ_3463_Sightseeing(最短路/次短路条数)

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7421   Accepted: 2659 Description Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. O

HDU 1596 find the safest road (最短路)

find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6973    Accepted Submission(s): 2469 Problem Description XX星球有很多城市,每个城市之间有一条或多条飞行通道,但是并不是所有的路都是很安全的,每一条路有一个安全系数s,s是在 0 和 1

HDU 2066-一个人的旅行(最短路Dijkstra)

一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19349    Accepted Submission(s): 6763 Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰