题意:
求从1到n的次短路。
思路:
到某个点v的次短路,要么是从其它点u的最短路加上从u到v的边;要么是从其它点u到的次短路加上从u到v的边。
所以在更新的同时,最短路与次短路都要保存,都要更新。
坑:
首先,小根堆是 > 符号 (吐血
其次,d1[1]与d2[1]不能都初始化为0,这样会有错
比如
4 2
1 2 100
2 4 200
正确答案是500,错误情况是700
再其次,因为最短路与次短路都要保存,所以如果哪一个更新了都要放进队列里面。
代码:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 9 const int inf = 0x3f3f3f3f; 10 11 struct edge 12 { 13 int to,cost; 14 15 bool operator < (const edge &rhs) const 16 { 17 return cost > rhs.cost; 18 } 19 }; 20 21 priority_queue pq; 22 vector v[5005]; 23 vector edges; 24 25 bool vis[5005]; 26 27 int d1[5005]; 28 int d2[5005]; 29 30 void adde(int x,int y,int z) 31 { 32 edge tmp; 33 tmp.to = y; 34 tmp.cost = z; 35 36 edges.push_back(tmp); 37 38 int m = edges.size(); 39 40 v[x].push_back(m-1); 41 } 42 43 void dij(int s) 44 { 45 memset(d1,inf,sizeof(d1)); 46 memset(d2,inf,sizeof(d2)); 47 memset(vis,0,sizeof(vis)); 48 49 d1[1] = 0; 50 51 edge tmp; 52 tmp.cost = 0; 53 tmp.to = 1; 54 55 pq.push(tmp); 56 57 while (!pq.empty()) 58 { 59 edge cur = pq.top(); 60 pq.pop(); 61 62 int x = cur.to; 63 int d = cur.cost; 64 65 if (vis[x]) continue; 66 67 for (int i = 0;i < v[x].size();i++) 68 { 69 int id = v[x][i]; 70 71 int cost = edges[id].cost; 72 int to = edges[id].to; 73 74 if (d1[to] >= d + cost) 75 { 76 if (d2[to] > d1[to]) 77 { 78 d2[to] = d1[to]; 79 80 edge nex; 81 nex.cost = d2[to]; 82 nex.to = to; 83 84 pq.push(nex); 85 } 86 87 d1[to] = d + cost; 88 89 edge nex; 90 nex.cost = d1[to]; 91 nex.to = to; 92 93 pq.push(nex); 94 } 95 else 96 { 97 if (d2[to] > d + cost) 98 { 99 d2[to] = d + cost;100 101 edge nex;102 nex.cost = d2[to];103 nex.to = to;104 105 pq.push(nex);106 }107 108 }109 }110 }111 }112 113 int main()114 {115 int n,r;116 117 scanf("%d%d",&n,&r);118 119 for (int i = 0;i < r;i++)120 {121 int x,y,z;122 123 scanf("%d%d%d",&x,&y,&z);124 125 adde(x,y,z);126 adde(y,x,z);127 }128 129 dij(1);130 131 printf("%d\n",d2[n]);132 133 return 0;134 }