E - すぬけ君の地下鉄旅行 / Snuke's Subway Trip
Time limit : 3sec / Memory limit : 256MB
Score : 600 points
Problem Statement
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≤i≤M ) 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≤105
- 0≤M≤2×105
- 1≤pi≤N (1≤i≤M)
- 1≤qi≤N (1≤i≤M)
- 1≤ci≤106 (1≤i≤M)
- pi≠qi (1≤i≤M)
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
思路:一眼看上去就是个图论题,我们考虑普通建图,无法保证是否换乘。考虑重新建图,我们对于每一个点,建一些“虚点”,对于每一个地铁网的联通块内部,路径为0,外部路径为1,再跑一个DFS即可。
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<vector>
#define pa pair<int,int>
using namespace std;
const int MAXN=1000010;
int dis[MAXN];
vector <pa> g[MAXN];
vector <int> new_g[MAXN],all[MAXN];
int visit[MAXN],ptr[MAXN];
queue <int> q;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
u--,v--;
g[u].push_back(make_pair(c,v));
g[v].push_back(make_pair(c,u));
all[c].push_back(u);
all[c].push_back(v);
}
for (int i=0;i<n;i++)
{
sort(g[i].begin(),g[i].end());
visit[i]=-1;
}
int newn=n;
for (int i=0;i<MAXN;i++)
{
if (all[i].empty())
{
continue;
}
for (int it=0;it<all[i].size();it++)
{
int v=all[i][it];
if (visit[v]==i)
{
continue;
}
q.push(v);
visit[v]=i;
while (!q.empty())
{
int x=q.front();
q.pop();
while (ptr[x]<(int)g[x].size())
{
int c=g[x][ptr[x]].first;
if (c!=i)
{
break;
}
int u=g[x][ptr[x]].second;
if (visit[u]!=i)
{
visit[u]=i;
q.push(u);
}
ptr[x]++;
}
new_g[x].push_back(newn);
new_g[newn].push_back(x);
}
newn++;
}
}
for (int i=0;i<newn;i++)
{
dis[i]=-2;
}
q.push(0);
dis[0]=0;
while (!q.empty())
{
int x=q.front();
q.pop();
for (int i=0;i<new_g[x].size();i++)
{
int u=new_g[x][i];
if (dis[u]==-2)
{
dis[u]=dis[x]+1;
q.push(u);
}
}
}
cout<<dis[n-1]/2;
return 0;
}