Advertisement
Guest User

Baltazar

a guest
Jan 17th, 2023
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.36 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int kN = 3e5;
  6. const int64_t INF = 1e18L;
  7. const int MODS = 4;
  8. const int mod[] = {805306457, (int)1e9 + 7, (int)1e9 + 9, 1610612741};
  9. int n, m;
  10. vector<pair<int, int>> g[1 + kN];
  11. int cnt[2][1 + kN][2][4];
  12. int64_t dp[2][1 + kN][2];
  13.  
  14. void addSelf(int &x, int y, int mod) {
  15.   x += y;
  16.   if (x >= mod) {
  17.     x -= mod;
  18.   }
  19. }
  20.  
  21. int mult(int x, int y, int mod) {
  22.   return (int64_t)x * y % mod;
  23. }
  24.  
  25. void Dijkstra(int source, int t) {
  26.   for (int v = 1; v <= n; ++v) {
  27.     dp[t][v][0] = dp[t][v][1] = INF;
  28.     for (int i = 0; i < MODS; ++i) {
  29.       cnt[t][v][0][i] = cnt[t][v][1][i] = 0;
  30.     }
  31.   }
  32.  
  33.   dp[t][source][0] = 0;
  34.   for (int i = 0; i < MODS; ++i) {
  35.     cnt[t][source][0][i] = 1;
  36.   }
  37.  
  38.   priority_queue<tuple<int64_t, int, int>, vector<tuple<int64_t, int, int>>, greater<tuple<int64_t, int, int>>> pq;
  39.   pq.emplace(0, source, 0);
  40.  
  41.   while (!pq.empty()) {
  42.     int64_t cost;
  43.     int u;
  44.     int par;
  45.     tie(cost, u, par) = pq.top();
  46.     pq.pop();
  47.  
  48.     if (cost != dp[t][u][par]) {
  49.       continue;
  50.     }
  51.  
  52.     for (const auto &it : g[u]) {
  53.       int v, w;
  54.       tie(v, w) = it;
  55.  
  56.       int64_t newCost = cost + w;
  57.       int newPar = (par + w) % 2;
  58.  
  59.       if (newCost < dp[t][v][newPar]) {
  60.         dp[t][v][newPar] = newCost;
  61.         for (int i = 0; i < MODS; ++i) {
  62.           cnt[t][v][newPar][i] = cnt[t][u][par][i];
  63.         }
  64.         pq.emplace(newCost, v, newPar);
  65.       } else if (newCost == dp[t][v][newPar]) {
  66.         for (int i = 0; i < MODS; ++i) {
  67.           addSelf(cnt[t][v][newPar][i], cnt[t][u][par][i], mod[i]);
  68.         }
  69.       }
  70.     }
  71.   }
  72. }
  73.  
  74. void testCase() {
  75.   cin >> n >> m;
  76.  
  77.   for (int v = 1; v <= n; ++v) {
  78.     g[v].clear();
  79.   }
  80.  
  81.   vector<tuple<int, int, int>> edges;
  82.  
  83.   for (int i = 0; i < m; ++i) {
  84.     int u, v, w;
  85.     cin >> u >> v >> w;
  86.  
  87.     g[u].emplace_back(v, w);
  88.     g[v].emplace_back(u, w);
  89.  
  90.     edges.emplace_back(u, v, w);
  91.   }
  92.  
  93.   Dijkstra(1, 0);
  94.   Dijkstra(n, 1);
  95.  
  96.   int64_t bestPath = INF;
  97.   int bestCounts[MODS];
  98.   int goodPar = -1;
  99.  
  100.   for (int p = 0; p < 2; ++p) {
  101.     if (dp[0][n][p] < bestPath) {
  102.       goodPar = p;
  103.       bestPath = dp[0][n][p];
  104.  
  105.       for (int i = 0; i < MODS; ++i) {
  106.         bestCounts[i] = cnt[0][n][p][i];
  107.       }
  108.     }
  109.   }
  110.  
  111.   int64_t secondBest = dp[0][n][goodPar ^ 1];
  112.   int secondCounts[MODS];
  113.   for (int i = 0; i < MODS; ++i) {
  114.     secondCounts[i] = cnt[0][n][goodPar ^ 1][i];
  115.   }
  116.  
  117.   if (secondBest != bestPath + 1) {
  118.     cout << "0\n\n";
  119.     return;
  120.   }
  121.  
  122.   vector<int> sol;
  123.  
  124.   for (int i = 0; i < m; ++i) {
  125.     int u, v, w;
  126.     tie(u, v, w) = edges[i];
  127.  
  128.     int64_t shortestPath = INF;
  129.     int paths[4];
  130.     int secondPaths[MODS] = {0, 0, 0, 0};
  131.  
  132.     for (const int &first : {u, v}) {
  133.       int second = u + v - first;
  134.  
  135.       for (int p1 = 0; p1 < 2; ++p1) {
  136.         for (int p2 = 0; p2 < 2; ++p2) {
  137.           int64_t len = dp[0][first][p1] + w + dp[1][second][p2];
  138.  
  139.           if (len < shortestPath) {
  140.             shortestPath = len;
  141.  
  142.             for (int j = 0; j < MODS; ++j) {
  143.               paths[j] = mult(cnt[0][first][p1][j], cnt[1][second][p2][j], mod[j]);
  144.             }
  145.           } else if (len == shortestPath) {
  146.             for (int j = 0; j < MODS; ++j) {
  147.               addSelf(paths[j], mult(cnt[0][first][p1][j], cnt[1][second][p2][j], mod[j]), mod[j]);
  148.             }
  149.           }
  150.  
  151.           if (len == bestPath + 1) {
  152.             for (int j = 0; j < MODS; ++j) {
  153.               addSelf(secondPaths[j], mult(cnt[0][first][p1][j], cnt[1][second][p2][j], mod[j]), mod[j]);
  154.             }
  155.           }
  156.         }
  157.       }
  158.     }
  159.  
  160.     if (shortestPath != bestPath) {
  161.       continue;
  162.     }
  163.  
  164.     bool ok = true;
  165.  
  166.     for (int j = 0; j < MODS && ok; ++j) {
  167.       if (paths[j] != bestCounts[j]) {
  168.         ok = false;
  169.       }
  170.     }
  171.  
  172.     if (!ok) {
  173.       continue;
  174.     }
  175.  
  176.     ok = false;
  177.  
  178.     for (int j = 0; j < MODS && !ok; ++j) {
  179.       if (secondCounts[j] != secondPaths[j]) {
  180.         ok = true;
  181.       }
  182.     }
  183.  
  184.     if (ok) {
  185.       sol.emplace_back(i + 1);
  186.     }
  187.   }
  188.  
  189.   cout << sol.size() << '\n';
  190.  
  191.   for (const int &id : sol) {
  192.     cout << id << ' ';
  193.   }
  194.  
  195.   cout << '\n';
  196. }
  197.  
  198. int main() {
  199.   ios_base::sync_with_stdio(false);
  200.   cin.tie(nullptr);
  201.  
  202.   int tests;
  203.   cin >> tests;
  204.  
  205.   for (int tc = 0; tc < tests; ++tc) {
  206.     testCase();
  207.   }
  208.  
  209.   return 0;
  210. }
  211.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement