Ways for Honeymoon 0_0

      No Comments on Ways for Honeymoon 0_0

Honeymoon Ways

Amit and his wife Shweta are in Singapore for their honeymoon. Shweta wants to visit every hotel present there. Amit and Shweta are in their hotel and Amit is planning out how can he fulfill Shweta’s wish.

There are N hotels there(they are staying at the hotel No. 1). There are exactly M roads connecting those hotels (It is guaranteed that any hotel can be visited from any other by roads). Each road has its length. Every day the couple visits exactly one unvisited hotel and come back. Amit wants to take the shortest distance to get to any hotel from his hotel(they use the same path to get back to their hotel).

But there is a problem, Singapore government has announced that the tourists have to choose N-1 roads to move in the city i.e Amit has to choose total N-1 roads such that they can visit all the other hotels. Also, path taken to reach any other hotel from their hotel should be the shortest. So in how many ways can Amit choose such N-1 roads.

Input :

The first line contains the number of test cases T. Then T test cases follow.
The first line of each test cases contains N and M, the number of hotels and roads respectively.
Next M lines contain A B C which denotes that there is a road of length C between hotels A and B.
The couples are staying in Hotel No. 1.

Output:

Print the number of ways modulo 

Constraints:.





Solution with Description

Problem:

Given a connected graph with N nodes and M edges, you need to find the number of distinct trees that can be formed containing all N nodes from the given graph by removing edges such that the distance between the 1st and i th node in the tree is same as the shortest path distance between the 1st and i th node in the graph, for all i.

Solution:

Try to think this using Dijkstra. See here .

In Dijkstra, we get the smallest distance from 1 to all the nodes. While updating the shortest distance of adjacent nodes of node K, also update the number of roads(cnt[adjacent node]) which directly lead to it with that distance. So if the shortest distance is same as before then we just add 1 to cnt[adjacent node] whereas if shortest distance changes then cnt[adjacent node] is made 1. Like in the sample test case: At first node 1 has a shortest distance 0. But all other nodes had the shortest distance infinite and the number of roads leading to 2 and 3 with this distance is 0. We take 1 as visited and update its adjacent nodes i.e. now the shortest distance of node 2 is 1 and node 3 is 2 and the number of roads leading to 2 and 3 with this distance is 1(cnt[2]=cnt[3]=1). Then node 2 is taken as visited and its adjacent node 3 can be reached with the same shortest distance 2, and we have to update the number of roads leading to node 3 with this shortest distance to 2(cnt[3]=2). And now we take node 3.

Then the number of ways in which the tree can be constructed is the product of cnt[i] for all i.

Expected Time Complexity: O((N + M)*log(N)) per test case

Code

  1. #include <bits/stdc++.h>
  2. typedef long long ll;
  3. using namespace std;
  4. ll minT = 1;
  5. ll maxT = 10;
  6. ll minN = 1;
  7. ll maxN = 1000;
  8. ll minM = 0;
  9. ll maxM = 1e5;
  10. ll minC = 1;
  11. ll maxC = 1000;
  12. ll mod = 1e9 + 7;
  13. const int max_n = 1100;
  14. ll inf = 1e15;
  15. class compare
  16. {
  17. public:
  18. bool operator() (const pair<ll, ll> &a, const pair<ll, ll> &b)
  19. {
  20. return (a.first > b.first);
  21. }
  22. };
  23. vector<pair<ll, ll> > v[max_n];
  24. ll cnt[max_n], minDis[max_n];
  25. priority_queue<pair<ll, ll>, vector<pair<ll, ll> >, compare > pq;
  26. bool visited[max_n];
  27. int main()
  28. {
  29. ll t, i, j, n, m, ans, chVer, chDis, nextVer, nextDis, a, b, c, siz;
  30. pair<ll, ll> tempPr;
  31. scanf("%lld", &t);
  32. assert(t>=minT && t<=maxT);
  33. while(t--)
  34. {
  35. scanf("%lld %lld", &n, &m);
  36. assert(n>=minN && n<=maxN);
  37. assert(m>=minM && m<=maxM);
  38. for(i=1;i<=n;++i)
  39. {
  40. v[i].clear();
  41. minDis[i] = inf;
  42. cnt[i] = 0LL;
  43. visited[i] = false;
  44. }
  45. for(i=0;i<m;++i)
  46. {
  47. scanf("%lld %lld %lld", &a, &b, &c);
  48. assert(a>=minN && a<=maxN && a<=n);
  49. assert(b>=minN && b<=maxN && b<=n);
  50. assert(c>=minC && c<=maxC);
  51. v[a].push_back(make_pair(c, b));
  52. v[b].push_back(make_pair(c, a));
  53. }
  54. minDis[1] = 0LL;
  55. pq.push(make_pair(minDis[1], 1LL));
  56. while(!pq.empty())
  57. {
  58. tempPr = pq.top();
  59. pq.pop();
  60. nextDis = tempPr.first;
  61. nextVer = tempPr.second;
  62. if(nextDis == inf)
  63. continue;
  64. //printf("nextVer = %lld nextDis= %lld\n", nextVer, nextDis);
  65. if(nextDis == minDis[nextVer])
  66. {
  67. ++cnt[nextVer];
  68. }
  69. if(visited[nextVer])
  70. continue;
  71. visited[nextVer] = true;
  72. siz = v[nextVer].size();
  73. for(j=0;j<siz;++j)
  74. {
  75. chDis = v[nextVer][j].first;
  76. chVer = v[nextVer][j].second;
  77. if(minDis[nextVer]+chDis <= minDis[chVer])
  78. {
  79. minDis[chVer] = minDis[nextVer]+chDis;
  80. pq.push(make_pair(minDis[chVer], chVer));
  81. }
  82. }
  83. }
  84. ans = 1LL;
  85. for(i=1;i<=n;++i)
  86. {
  87. //printf("cnt[%lld] = %lld\n", i, cnt[i]);
  88. ans = (ans * cnt[i])%mod;
  89. }
  90. printf("%lld\n", ans);
  91. }
  92. return 0;
  93. }
Give Your Reviews

Leave a Reply