zoukankan      html  css  js  c++  java
  • 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 }no;
     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     no.p = 0, no.dis = 0, no.id = s;
     55     Q.push(no);
     56     while(!Q.empty())
     57     {
     58         Node a = Q.top();
     59         Q.pop();
     60         if(vis[a.p][a.id])
     61             continue; //该p状态下已经确定过就跳过 
     62         vis[a.p][a.id] = 1;
     63         for(int i = head[a.id]; i != -1; i = edge[i].next)
     64         {
     65             int to = edge[i].to;
     66             if(dis[0][to] > dis[a.p][a.id] + edge[i].w) //最短路可以更新(在0或1状态下找到一条更短的路) 
     67             {
     68                 dis[1][to] = dis[0][to];  //原来的最短路成为次短路
     69                 dis[0][to] = dis[a.p][a.id] + edge[i].w;
     70                 cnt[1][to] = cnt[0][to];//次短路条数继承为原来的最短路条数 
     71                 cnt[0][to] = cnt[a.p][a.id];
     72                 no.p = 0, no.dis = dis[0][to], no.id = to;
     73                 Q.push(no);
     74                 no.p = 1, no.dis = dis[1][to], no.id = to;
     75                 Q.push(no);
     76             }
     77             else if(dis[0][to] == dis[a.p][a.id] + edge[i].w)//最短路长度一样 更新最短路条数即可 
     78             {
     79                 cnt[0][to] += cnt[a.p][a.id];
     80             }
     81             else if(dis[1][to] > dis[a.p][a.id] + edge[i].w)//找到一条长度大于最短路但小于当前次短路的路径 
     82             {//将这条路变成次短路 
     83                 dis[1][to] = dis[a.p][a.id] + edge[i].w;
     84                 cnt[1][to] = cnt[a.p][a.id];
     85                 no.p = 1, no.dis = dis[1][to], no.id = to;
     86                 Q.push(no);
     87             }
     88             else if(dis[1][to] == dis[a.p][a.id] + edge[i].w)
     89             {
     90                 cnt[1][to] += cnt[a.p][a.id];
     91             }
     92         }
     93     }
     94 }
     95 
     96 int main()
     97 {
     98     int T;
     99     scanf("%d", &T);
    100     while(T --)
    101     {
    102         init();
    103         scanf("%d%d", &n, &m);
    104         for(int i = 1; i <= m; i ++)
    105         {
    106             int a, b, c;
    107             scanf("%d%d%d", &a, &b, &c);
    108             add(a, b, c);
    109         }
    110         int s, t;
    111         scanf("%d%d", &s, &t);
    112         dij(s, t);
    113         int ans = cnt[0][t]; //ans代表最短路的条数
    114         if(dis[0][t] + 1 == dis[1][t])
    115             ans += cnt[1][t];
    116         printf("%d
    ", ans); 
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    python习题一
    华为区块链平台
    百度超级链 [Xuperchain]
    $$$Fabric v1.0 block结构与修改
    搭建 Hyperladger Fabric 基本流程
    python开发区块链【公有链】
    Asp.Net中WebServices的调用方式
    关于vs08生成解决方案慢的解决方法
    vs项目启动调试时,显示找不到文件问题
    新的公司
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/10961335.html
Copyright © 2011-2022 走看看