グラフの変形をする
600点問題ではない
最短経路問題なので、Dijkstraしやすいようにグラフをつくる
辺の数を少なくするため、経由地的な頂点を使う
- #include<iostream>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #define lol(i,n) for(int i=0;i<n;i++)
- #define mod 1000000007
- typedef long long ll;
- using namespace std;
- #include<map>
- typedef pair<int,int> P;
- vector<vector<P> >v;//辺リスト(v[i]には辺が詰まっている
- map<int,int> u[100010];//頂点リスト(u[頂点][路線]==vでの番号)
- priority_queue<P,vector<P>,greater<P> >Q;
- int dis[500010];
- int main(){
- vector<P> emptyvector;
- v.push_back(emptyvector);
- int n,m;
- cin>>n>>m;
- int vsize=1;
- for(int i=1;i<=n;i++){
- v.push_back(emptyvector);
- u[i][-1]=vsize;
- vsize++;
- }
- while(m--){
- int a,b,train;
- cin>>a>>b>>train;
- lol(p,2){
- if(u[a][train]==0){
- v.push_back(emptyvector);
- v[vsize].push_back(make_pair(a,0));
- v[a].push_back(make_pair(vsize,1));
- u[a][train]=vsize;
- a=vsize;
- vsize++;
- }
- else{
- a=u[a][train];
- }
- swap(a,b);
- }
- v[a].push_back(make_pair(b,0));
- v[b].push_back(make_pair(a,0));
- }
- //↓ Dijkstra ↓
- lol(i,vsize)dis[i]=mod;
- Q.push(make_pair(0,1));
- while(!Q.empty()){
- int b=Q.top().first,a=Q.top().second;
- Q.pop();
- if(dis[a]<=b)continue;
- dis[a]=b;
- for(int i=0;i<v[a].size();i++){
- int pnt=v[a][i].first,cost=v[a][i].second+b;
- if(dis[pnt]<=cost)continue;
- Q.push(make_pair(v[a][i].second+b,v[a][i].first));
- }
- }
- int tmp=dis[u[n][-1]];
- cout<<(tmp==mod?-1:tmp)<<endl;
- return 0;
- }
グラフでも計算量の確認が大事(特に辺の数)