Snuke's Subway Trip: Dijkstra's Algorithm

Problem Statement (See: http://arc061.contest.atcoder.jp/tasks/arc061_c

Snuke's town has a subway system, consisting of N stations and M railway lines. The stations are numbered 1 through N. Each line is operated by a company. Each company has an identification number.

The i-th ( 1≤iM ) line connects station pi and qi bidirectionally. There is no intermediate station. This line is operated by company ci.

You can change trains at a station where multiple lines are available.

The fare system used in this subway system is a bit strange. When a passenger only uses lines that are operated by the same company, the fare is 1 yen (the currency of Japan). Whenever a passenger changes to a line that is operated by a different company from the current line, the passenger is charged an additional fare of 1 yen. In a case where a passenger who changed from some company A's line to another company's line changes to company A's line again, the additional fare is incurred again.

Snuke is now at station 1 and wants to travel to station N by subway. Find the minimum required fare.

 

Constraints

  • 2≤N≤10^5
  • 0≤M≤2×10^5
  • 1≤piN (1≤iM)
  • 1≤qiN (1≤iM)
  • 1≤ci≤10^6 (1≤iM)
  • piqi (1≤iM)

Input

The input is given from Standard Input in the following format:

N M
p1 q1 c1
:
pM qM cM

Output

Print the minimum required fare. If it is impossible to get to station N by subway, print -1 instead.

Sample Input 1

3 3
1 2 1
2 3 1
3 1 2

Sample Output 1

1

Use company 1's lines: 1 → 2 → 3. The fare is 1 yen.


Sample Input 2

8 11
1 3 1
1 4 2
2 3 1
2 5 1
3 4 3
3 6 3
3 7 3
4 8 4
5 6 1
6 7 5
7 8 5

Sample Output 2

2

First, use company 1's lines: 1 → 3 → 2 → 5 → 6. Then, use company 5's lines: 6 → 7 → 8. The fare is 2 yen.


Sample Input 3

2 0

Sample Output 3

-1

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 typedef long long ll_t;
 5  
 6 #define INF 1E9
 7  
 8 ll_t pack(ll_t x, ll_t y) {
 9     return x * 1E9 + y;
10 }
11  
12 using edge = pair<ll_t, int>;
13  
14 struct Dist {
15     ll_t v;
16     int d;
17     Dist(ll_t v_, int d_ = INF) : v(v_), d(d_) { } 
18     bool operator < (const Dist& rhs) const {
19         return d > rhs.d;
20     }
21 };
22  
23 int N;
24 int M;
25 unordered_map<ll_t, vector<edge>> graph;
26 unordered_map<ll_t, int> dist;
27 unordered_set<ll_t> done;
28  
29 int main() {
30     scanf("%d%d", &N, &M);
31  
32     for (int i = 1; i <= M; i++) {
33         int p, q, c;
34         scanf("%d%d%d", &p, &q, &c);
35         graph[pack(p, c)].push_back(edge(pack(q, c), 0));
36         graph[pack(q, c)].push_back(edge(pack(p, c), 0));
37         
38         graph[pack(p, c)].push_back(edge(pack(p, 0), 0));
39         graph[pack(p, 0)].push_back(edge(pack(p, c), 1));
40         graph[pack(q, c)].push_back(edge(pack(q, 0), 0));
41         graph[pack(q, 0)].push_back(edge(pack(q, c), 1));
42     }
43  
44     priority_queue<Dist> q;
45     dist[pack(1, 0)] = 0;
46     q.push(Dist(pack(1, 0), 0));
47     while (!q.empty()) {
48         Dist t = q.top();
49         q.pop();
50         if (done.count(t.v)) continue;
51         done.insert(t.v);
52  
53         for (auto& kv : graph[t.v]) {
54             ll_t u = kv.first;
55             int d = kv.second;
56             int tmp = dist[t.v] + d;
57             if (dist.count(u) == 0 || tmp < dist[u]) {
58                 dist[u] = tmp;
59                 q.push(Dist(u, tmp));
60             }
61         }
62     }
63     if (dist.count(pack(N, 0)) == 0)
64         printf("-1\n");
65     else
66         printf("%d\n", dist[pack(N, 0)]);
67     return 0;
68 }

 

posted @ 2016-09-12 01:22  william-cheung  阅读(249)  评论(0编辑  收藏  举报