码迷,mamicode.com
首页 > 其他好文 > 详细

[POJ3463] Sightseeing(次短路 Heap + Dijkstra)

时间:2017-05-20 19:31:43      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:tchar   传送门   tin   add   lan   jks   lin   next   ios   

传送门

 

用dijkstra比较好,spfa可能有的重复

dis[x][2]:dis[x][0]表示起点到x的最短路、dis[x][1]表示起点到x的次短路;

tot[x][2]:tot[x][0]表示起点到x的最短路条数、tot[x][1]表示起点到x的次短路的条数;

vis[x][2]对应于x和0、1功能为记录该点是否被访问!

那么如何更新最小和次小路呢?显然我们容易想到下面的方法:

1.if(x<最小)更新最小,次小;
2.else if(x==最小)更新方法数;
3.else if(x<次小)更新次小;
4.else if(x==次小)更新方法数;

 

——代码

技术分享
  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 
  9 struct heap
 10 {
 11     int x, y, z;
 12     heap(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}
 13     bool operator < (const heap &rhs) const
 14     {
 15         return y > rhs.y;
 16     }
 17 };
 18 
 19 const int MAXM = 10001, MAXN = 1001;
 20 int T, n, m, cnt;
 21 int dis[MAXN][2], head[MAXN], to[MAXM << 1], next[MAXM << 1], val[MAXM << 1], tot[MAXN][2];
 22 priority_queue <heap> q;
 23 bool vis[MAXN][2];
 24 
 25 inline int read()
 26 {
 27     int x = 0, f = 1;
 28     char ch = getchar();
 29     for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1;
 30     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0;
 31     return x * f;
 32 }
 33 
 34 inline void add(int x, int y, int z)
 35 {
 36     to[cnt] = y;
 37     val[cnt] = z;
 38     next[cnt] = head[x];
 39     head[x] = cnt++;
 40 }
 41 
 42 inline void dijkstra(int s)
 43 {
 44     int i, u, v, d, p;
 45     heap now;
 46     memset(vis, 0, sizeof(vis));
 47     memset(tot, 0, sizeof(tot));
 48     memset(dis, 127 / 3, sizeof(dis));
 49     dis[s][0] = 0;
 50     tot[s][0] = 1;
 51     q.push(heap(s, 0, 0));
 52     while(!q.empty())
 53     {
 54         now = q.top();
 55         q.pop();
 56         u = now.x;
 57         p = now.z;
 58         if(vis[u][p]) continue;
 59         vis[u][p] = 1;
 60         for(i = head[u]; i ^ -1; i = next[i])
 61         {
 62             v = to[i];
 63             if(dis[v][0] > dis[u][p] + val[i])
 64             {
 65                 dis[v][1] = dis[v][0];
 66                 tot[v][1] = tot[v][0];
 67                 dis[v][0] = dis[u][p] + val[i];
 68                 tot[v][0] = tot[u][p];
 69                 q.push(heap(v, dis[v][0], 0));
 70                 q.push(heap(v, dis[v][1], 1));
 71             }
 72             else if(dis[v][0] == dis[u][p] + val[i]) tot[v][0] += tot[u][p];
 73             else if(dis[v][1] > dis[u][p] + val[i])
 74             {
 75                 dis[v][1] = dis[u][p] + val[i];
 76                 tot[v][1] = tot[u][p];
 77                 q.push(heap(v, dis[v][1], 1));
 78             }
 79             else if(dis[v][1] == dis[u][p] + val[i]) tot[v][1] += tot[u][p];
 80         }
 81     }
 82 }
 83 
 84 int main()
 85 {
 86     int i, j, x, y, z, s, t;
 87     T = read();
 88     while(T--)
 89     {
 90         n = read();
 91         m = read();
 92         cnt = 0;
 93         memset(head, -1, sizeof(head));
 94         for(i = 1; i <= m; i++)
 95         {
 96             x = read();
 97             y = read();
 98             z = read();
 99             add(x, y, z);
100         }
101         s = read();
102         t = read();
103         dijkstra(s);
104         if(dis[t][1] == dis[t][0] + 1) tot[t][0] += tot[t][1];
105         printf("%d\n", tot[t][0]);
106     }
107 }
View Code

 

[POJ3463] Sightseeing(次短路 Heap + Dijkstra)

标签:tchar   传送门   tin   add   lan   jks   lin   next   ios   

原文地址:http://www.cnblogs.com/zhenghaotian/p/6882854.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!