Abrar_Al_Samit

A Wedding Party (LOJ 1316)

Jul 27th, 2021 (edited)
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.73 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #include <ext/pb_ds/assoc_container.hpp>
  3. #include <ext/pb_ds/tree_policy.hpp>
  4.  
  5. using namespace std;
  6. using namespace __gnu_pbds;
  7.  
  8.  
  9. #define debug(x) cerr << '[' << (#x) << "] = " << x << '\n'
  10.  
  11. template<class T> using ordered_set = tree<T, null_type , less<T> , rb_tree_tag , tree_order_statistics_node_update> ;
  12.  
  13. void Dijkstra(int st); void Clear();
  14. void PruneShop(); void HashShop();
  15.  
  16. const int INF = 1e8 + 8;
  17. int N, M, S;
  18. int dist[500][500], dist2[15][15];
  19. pair<int,int> dp[15][1<<15];
  20. vector<int>shop, finish(15), start(15);
  21. vector<pair<int,int>>g[500];
  22.  
  23.  
  24. pair<int,int> solve(int sh, int mask) {
  25.     pair<int,int> &ret = dp[sh][mask];
  26.     if(ret.second!=-1) return dp[sh][mask];
  27.     ret = {0, 0};    
  28.     for(int i=0; i<S; ++i) if(dist2[sh][shop[i]]!=INF && (~mask >> i & 1)) {
  29.         pair<int,int>got = solve(shop[i], mask|(1<<i));
  30.         got.second += dist2[sh][shop[i]];
  31.         if(ret.first==got.first) ret = min(ret, got);
  32.         else if(ret.first<got.first) ret = got;
  33.     }
  34.     if(ret.first==0) ret.second = finish[sh];
  35.     ret.first += binary_search(shop.begin(), shop.end(), sh);
  36.     return ret;
  37. }
  38. void PlayGround(int T) {
  39.     cin >> N >> M >> S;
  40.     Clear();
  41.     for(int i=0; i<S; ++i) {
  42.         int sh; cin >> sh;
  43.         shop.push_back(sh);
  44.     }
  45.     for(int i=0; i<M; ++i) {
  46.         int u, v, w; cin >> u >> v >> w;
  47.         g[u].push_back(make_pair(v, w));
  48.     }
  49.     for(int i=0; i<S; ++i) Dijkstra(shop[i]);
  50.     Dijkstra(0);
  51.    
  52.     if(dist[0][N-1]==INF) {
  53.         cout << "Case " << T << ": Impossible\n";
  54.         return;
  55.     }
  56.     debug(dist[0][N-1]);
  57.     PruneShop();
  58.     HashShop();
  59.  
  60.     pair<int,int>ans = {-1, INT_MAX};
  61.     for(int i=0; i<S; ++i) {
  62.         pair<int,int>cand = solve(shop[i], (1<<i));
  63.         cand.second += start[shop[i]];
  64.         if(ans.first==cand.first) ans = min(ans, cand);
  65.         else if(ans.first < cand.first) ans = cand;
  66.     }
  67.     cout << "Case " << T << ": " << ans.first << ' ' << ans.second << '\n';
  68.  
  69.  
  70.     #ifndef ONLINE_JUDGE
  71.         cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
  72.     #endif
  73. }
  74. int main() {
  75.     ios_base::sync_with_stdio(0);
  76.     cin.tie(0);
  77.     cout.tie(0);
  78.     #ifndef ONLINE_JUDGE
  79.         freopen("input.txt", "r", stdin);
  80.     #endif
  81.     int T;
  82.     cin >> T;
  83.     for(int i=1; i<=T; ++i)
  84.     PlayGround(i);
  85.  
  86.     return 0;
  87. }
  88. void Clear() {
  89.     for(int i=0; i<S; ++i) {
  90.         for(int j=0; j<(1<<S); ++j) {
  91.             dp[i][j] = make_pair(-1, -1);
  92.         }
  93.     }
  94.     shop.clear();
  95.     for(int i=0; i<N; ++i) {
  96.         for(int j=0; j<N; ++j)
  97.             dist[i][j] = INF;
  98.         dist[i][i] = 0;
  99.     }
  100.     for(int i=0; i<N; ++i) g[i].clear();
  101. }
  102. void HashShop() {
  103.     map<int,int>H;
  104.     for(auto it : shop) H[it] = 1;
  105.     int cnt = 0;
  106.     for(auto &it : H) it.second = cnt++;
  107.     for(int i=0; i<S; ++i) {
  108.         for(int j=0; j<S; ++j) {
  109.             dist2[H[shop[i]]][H[shop[j]]] = dist[shop[i]][shop[j]];
  110.         }
  111.         finish[H[shop[i]]] = dist[shop[i]][N-1];
  112.         start[H[shop[i]]] = dist[0][shop[i]];
  113.     }
  114.     for(auto &it : shop) it = H[it];
  115. }
  116. void PruneShop() {
  117.     vector<int>shop2;
  118.     for(int i=0; i<S; ++i) if(dist[shop[i]][N-1]!=INF && dist[0][shop[i]]!=INF) {
  119.         shop2.push_back(shop[i]);
  120.     }
  121.     swap(shop2, shop);
  122.     shop2.clear();
  123.     S = shop.size();
  124. }
  125. void Dijkstra(int st) {
  126.     priority_queue<pair<int,int>>pq;
  127.     pq.push({0, st});
  128.     while(!pq.empty()) {
  129.         int cur = pq.top().second;
  130.         pq.pop();
  131.         for(auto it : g[cur]) if(dist[st][cur] + it.second < dist[st][it.first]) {
  132.             dist[st][it.first] = dist[st][cur] + it.second;
  133.             pq.push({-dist[st][it.first], it.first});
  134.         }
  135.     }
  136. }
Add Comment
Please, Sign In to add comment