Advertisement
welleyth

F. Maze

Mar 19th, 2022
781
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.08 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. using namespace __gnu_pbds;
  5. using namespace std;
  6. #define int long long
  7. #define pb push_back
  8. #define mp make_pair
  9.  
  10. #pragma GCC optimize("Ofast")
  11. #pragma GCC optimize("unroll-loops")
  12. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
  13. #pragma GCC target("avx,avx2")
  14.  
  15. constexpr int INF = (int)1e9;
  16. constexpr int N = (int)12e4 + 11;
  17. constexpr int MAXN = (int)3000 + 11;
  18. constexpr int md = (int)1e9+7;
  19.  
  20. void add(int& a,int b){
  21.     a += b;
  22.     if(a >= md) a -= md;
  23. }
  24.  
  25. mt19937 rnd(time(nullptr));
  26.  
  27. //vector<pair<int,int>> field;
  28. //vector<pair<int,int>> people;
  29.  
  30. struct DSU{
  31.     vector<int> parent;
  32.     vector<bool> ok;
  33.     vector<bool> used;
  34.     vector<vector<int>> notOk;
  35.     vector<int> mx;
  36.     DSU(){}
  37.     int n,m;
  38.     DSU(int nn,int mm){
  39.         n = nn, m = mm;
  40.         parent.resize(n*m);
  41.         ok.resize(n*m,false);
  42.         used.resize(n*m,false);
  43.         notOk.resize(n*m);
  44.         for(int i = 0; i < n*m; i++)
  45.             parent[i] = i;
  46.         for(int i = 0; i < n; i++){
  47.             ok[i*m] = 1;
  48.             ok[i*m+m-1] = 1;
  49.         }
  50.         for(int j = 0; j < m; j++){
  51.             ok[j] = 1;
  52.             ok[(n-1)*m+j] = 1;
  53.         }
  54.     }
  55.     void init(int nn,int mm){
  56.         n = nn, m = mm;
  57.         parent.resize(n*m);
  58.         ok.resize(n*m,false);
  59.         used.resize(n*m,false);
  60.         notOk.resize(n*m);
  61.         mx.resize(n*m);
  62.         for(int i = 0; i < n*m; i++)
  63.             parent[i] = i,mx[i] = 0;
  64.         for(int i = 0; i < n; i++){
  65.             ok[i*m] = 1;
  66.             ok[i*m+m-1] = 1;
  67.         }
  68.         for(int j = 0; j < m; j++){
  69.             ok[j] = 1;
  70.             ok[(n-1)*m+j] = 1;
  71.         }
  72.     }
  73.     void clear(){
  74.         for(int i = 0; i < n*m; i++)
  75.             parent[i] = i, used[i] = false, ok[i] = false, notOk[i].clear(), mx[i] = 0;
  76.         for(int i = 0; i < n; i++){
  77.             ok[i*m] = 1;
  78.             ok[i*m+m-1] = 1;
  79.         }
  80.         for(int j = 0; j < m; j++){
  81.             ok[j] = 1;
  82.             ok[(n-1)*m+j] = 1;
  83.         }
  84.     }
  85.     int get(int x){
  86.         return parent[x] == x ? x : parent[x] = get(parent[x]);
  87.     }
  88.     void union_sets(int a,int b){
  89.         used[a] = used[b] = 1;
  90.         a = get(a), b = get(b);
  91.         notOk[a].clear();
  92.         notOk[b].clear();
  93.         if(a == b)
  94.             return;
  95.         ok[a] = ok[b] = (ok[a] || ok[b]);
  96.         if(rnd() % 2)
  97.             swap(a,b);
  98.         parent[a] = b;
  99.         mx[a] = max(mx[a],mx[b]);
  100.     }
  101.     bool check(int pos){
  102.         if(used[pos] == false)
  103.             return false;
  104.         pos = get(pos);
  105.         return ok[pos];
  106.     }
  107. };
  108.  
  109. DSU d;
  110. int n,m,k;
  111.  
  112. //bool check(int t){
  113. //    d.clear();
  114. //    int ptr = 0;
  115. //    for(int i = 0; i < people.size(); i++){
  116. //        cerr << "current = " << people[i].second/m+1 << " " << people[i].second%m+1 << "\n";
  117. //        d.mx[get(people[i].second)] = max(d.mx[get(people[i].second)],people[i].first+t);
  118. //        while(ptr < field.size() && field[ptr].first <= people[i].first+t){
  119. //            int pos = field[ptr].second;
  120. //            int x = pos/m,y=pos%m;
  121. //            d.used[pos] = 1;
  122. //            if(y+1<m && d.used[pos+1] && d.mx[get(pos)] >= field[ptr].first)
  123. //                d.union_sets(pos,pos+1);
  124. //            if(y-1>=0 && d.used[pos-1])
  125. //                d.union_sets(pos,pos-1);
  126. //            if(x+1<n && d.used[pos+m])
  127. //                d.union_sets(pos,pos+m);
  128. //            if(x-1>=0 && d.used[pos-m])
  129. //                d.union_sets(pos,pos-m);
  130. //            cerr << "adding " << pos/m+1 << " " << pos%m+1 << "\n";
  131. //            ptr++;
  132. //        }
  133. //        if(d.check(people[i].second) == false){
  134. //            int p = d.get(people[i].second);
  135. //            d.notOk[p].pb(i);
  136. //            if(t == 1)
  137. //                cout << people[i].second / m+1 << " " << people[i].second%m+1 << "\n";
  138. //        }
  139. //    }
  140. //    for(int i = 0; i < n*m; i++)
  141. //        if(!d.notOk[i].empty())
  142. //            return false;
  143. //    return true;
  144. //}
  145. int a[1111][1111];
  146. int mx[1111][1111];
  147. bool ok[1111][1111];
  148. vector<pair<int,pair<int,int>>> people;
  149.  
  150. const int DX[] = {1,0,-1,0};
  151. const int DY[] = {0,1,0,-1};
  152.  
  153. bool F(int d){
  154.     for(int i = 1; i <= n; i++){
  155.         for(int j = 1; j <= m; j++){
  156.             mx[i][j] = 0;
  157.             ok[i][j] = 0;
  158.         }
  159.     }
  160.     queue<pair<int,int>> q;
  161.     for(auto& X : people){
  162.         if(mx[X.second.first][X.second.second] != 0)
  163.             continue;
  164.         q.push(mp(X.second.first,X.second.second));
  165.         mx[X.second.first][X.second.second] = X.first+d;
  166.         while(!q.empty()){
  167.             int x,y;
  168.             x = q.front().first, y = q.front().second;
  169. //            if(d == 2)
  170. //                cerr << x << " " << y << "\n";
  171.             q.pop();
  172.             for(int i = 0; i < 4; i++){
  173.                 int xn = x + DX[i], yn = y + DY[i];
  174.                 if(xn > 0 && xn <= n && yn > 0 && yn <= m && a[xn][yn] <= mx[x][y] && mx[xn][yn] < mx[x][y]){
  175.                     mx[xn][yn] = mx[x][y];
  176.                     q.push(mp(xn,yn));
  177.                 }
  178.             }
  179.         }
  180.     }
  181.  
  182.     queue<pair<int,int>> qq;
  183.     for(int i = 1; i <= n; i++){
  184.         ok[i][1] = ok[i][m] = 1;
  185.         if(mx[i][1])
  186.             qq.push(mp(i,1));
  187.         if(mx[i][m])
  188.             qq.push(mp(i,m));
  189.     }
  190.     for(int j = 1; j <= m; j++){
  191.         ok[1][j] = ok[n][j] = 1;
  192.         if(mx[1][j])
  193.             qq.push(mp(1,j));
  194.         if(mx[n][j])
  195.             qq.push(mp(n,j));
  196.     }
  197.     while(!qq.empty()){
  198.         int x = qq.front().first, y = qq.front().second;
  199.         qq.pop();
  200.         for(int i = 0; i < 4; i++){
  201.             int xn = x + DX[i], yn = y + DY[i];
  202.             if(xn > 0 && xn <= n && yn > 0 && yn <= m && !ok[xn][yn] && mx[xn][yn] == mx[x][y]){
  203.                 ok[xn][yn] = 1;
  204.                 qq.push(mp(xn,yn));
  205.             }
  206.         }
  207.     }
  208. //    for(int i = 1; i <= n; i++){
  209. //        for(int j = 1; j <= m; j++){
  210. //            cout << mx[i][j] << " ";
  211. //        }
  212. //        cout << "\n";
  213. //    }
  214.     for(auto& x : people){
  215.         if(!ok[x.second.first][x.second.second]){
  216. //            cerr << x.second.first << " " << x.second.second << "\n";
  217.             return false;
  218.         }
  219.     }
  220.     return true;
  221. }
  222.  
  223. void solve(){
  224.     cin >> n >> m >> k;
  225.  
  226.     for(int i = 1; i <= n; i++){
  227.         for(int j = 1; j <= m; j++){
  228.             cin >> a[i][j];
  229.         }
  230.     }
  231.     for(int i = 0; i < k; i++){
  232.         int x,y,s;
  233.         cin >> x >> y >> s;
  234.         people.pb(mp(s,mp(x,y)));
  235.     }
  236.     sort(people.rbegin(),people.rend());
  237.  
  238. //    cerr << F(2);
  239. //    return;
  240.  
  241.     int l = 0, r = (int)1e9;
  242.     while(r - l > 1){
  243.         int m = (r+l)>>1;
  244.         if(F(m))
  245.             r = m;
  246.         else
  247.             l = m;
  248.     }
  249.  
  250.     if(F(l))
  251.         r = l;
  252.     cout << r << "\n";
  253.  
  254.     return;
  255. }
  256. signed main(){
  257.     ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
  258.     int tests = 1;
  259. //      cin >> tests;
  260.     while(tests--){
  261.         solve();
  262.     }
  263. }
  264. /**
  265. 1 2 3 4 5 6
  266.  
  267. **/
  268.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement