ARC 061 E すぬけ君と地下旅行(600)

グラフの変形をする

600点問題ではない

最短経路問題なので、Dijkstraしやすいようにグラフをつくる

辺の数を少なくするため、経由地的な頂点を使う

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<vector>
  4. #include<queue>
  5. #define lol(i,n) for(int i=0;i<n;i++)
  6. #define mod 1000000007
  7. typedef long long ll;
  8. using namespace std;
  9. #include<map>
  10. typedef pair<int,int> P;
  11. vector<vector<P> >v;//辺リスト(v[i]には辺が詰まっている
  12. map<int,int> u[100010];//頂点リスト(u[頂点][路線]==vでの番号)
  13. priority_queue<P,vector<P>,greater<P> >Q;
  14. int dis[500010];
  15. int main(){
  16. vector<P> emptyvector;
  17. v.push_back(emptyvector);
  18. int n,m;
  19. cin>>n>>m;
  20. int vsize=1;
  21. for(int i=1;i<=n;i++){
  22. v.push_back(emptyvector);
  23. u[i][-1]=vsize;
  24. vsize++;
  25. }
  26. while(m--){
  27. int a,b,train;
  28. cin>>a>>b>>train;
  29. lol(p,2){
  30. if(u[a][train]==0){
  31. v.push_back(emptyvector);
  32. v[vsize].push_back(make_pair(a,0));
  33. v[a].push_back(make_pair(vsize,1));
  34. u[a][train]=vsize;
  35. a=vsize;
  36. vsize++;
  37. }
  38. else{
  39. a=u[a][train];
  40. }
  41. swap(a,b);
  42. }
  43. v[a].push_back(make_pair(b,0));
  44. v[b].push_back(make_pair(a,0));
  45. }
  46. //↓ Dijkstra
  47. lol(i,vsize)dis[i]=mod;
  48. Q.push(make_pair(0,1));
  49. while(!Q.empty()){
  50. int b=Q.top().first,a=Q.top().second;
  51. Q.pop();
  52. if(dis[a]<=b)continue;
  53. dis[a]=b;
  54. for(int i=0;i<v[a].size();i++){
  55. int pnt=v[a][i].first,cost=v[a][i].second+b;
  56. if(dis[pnt]<=cost)continue;
  57. Q.push(make_pair(v[a][i].second+b,v[a][i].first));
  58. }
  59. }
  60. int tmp=dis[u[n][-1]];
  61. cout<<(tmp==mod?-1:tmp)<<endl;
  62. return 0;
  63. }

 グラフでも計算量の確認が大事(特に辺の数)