Problem - 843D - Codeforces
竟然直接被我想对了。
首先这个 $O(nq)$ 貌似是可以过的,可以发现是求最短路问题。所以做法应该比较直观就是考虑每次暴力 $O(n)$ 进行更新。
如何进行更新呢?
考虑原来的最短路,不妨设为 $d(i)$,现在有新增加的路径 $add(i)$。可以发现我们可以直接通过宽搜看一下 $add(i)$ 能否进行更新。
但是我们这样还是需要优先队列,我们考虑如何模拟这个过程,可以发现每次是 $+1$,所以距离最多是增加 $n$。我们直接开桶暴力存即可,如果发现 $add(i)$ 与当前信息不符合可以直接剪枝,复杂度是 $O(n)$ 的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
   | #include <bits/stdc++.h> using namespace std; namespace Legendgod { 	namespace Read {
  		#ifdef Fread 		const int Siz = (1 << 21) + 5; 		char *iS, *iT, buf[Siz]; 		#define gc() ( iS == iT ? (iT = (iS = buf) + fread(buf, 1, Siz, stdin), iS == iT ? EOF : *iS ++) : *iS ++ ) 		#define getchar gc 		#endif 		template <typename T> 		void r1(T &x) { 		    x = 0; 			char c(getchar()); 			int f(1); 			for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; 			for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48); 			x *= f; 		} 		template <typename T, typename...Args> 		void r1(T &x, Args&...arg) { 			r1(x), r1(arg...); 		} 		#undef getchar 	}
  using namespace Read;
  const int maxn = 2e5 + 5; int n, m, Q; vector<pair<int, int> > vc[maxn];
  void add(int u,int v,int i) {     vc[u].push_back({v, i}); }
  typedef long long int64; const int64 inf = 1e15; int64 d[maxn], w[maxn]; struct Node {     int id; int64 dis;     int operator < (const Node &z) const {         return dis > z.dis;     } };
  priority_queue<Node> q; int vis[maxn];
  void Dij() {     while(!q.empty()) q.pop();     fill(d + 1, d + n + 1, inf);     d[1] = 0;     q.push({1, 0});     while(!q.empty()) {         int u = q.top().id; q.pop();         if(vis[u]) continue;         vis[u] = 1;         for(auto i : vc[u]) {             int to = i.first; int64 wt = w[i.second];             if(d[to] > d[u] + wt) {                 d[to] = d[u] + wt;                 if(!vis[to]) q.push({to, d[to]});             }         }     } }
  queue<int> buc[maxn];
  int64 ad[maxn];
  signed main() { 	int i, j;     r1(n, m, Q);     for(i = 1; i <= m; ++ i) {         int u, v;         r1(u, v, w[i]);         add(u, v, i);     }     Dij();     for(i = 1; i <= n; ++ i) if(d[i] == inf) d[i] = -1;
      while(Q --) {         int opt, c;         r1(opt); if(opt == 1) { r1(c); printf("%lld\n", d[c]); }         else {             int c; r1(c);             for(i = 1; i <= c; ++ i) { int x; r1(x); w[x] ++; }             fill(ad + 1, ad + n + 1, c + 1);             buc[ad[1] = 0].emplace(1);             for(int _ = 0; _ <= c; ++ _) {                 for(int v; !buc[_].empty(); buc[_].pop()) {                     v = buc[_].front();                     if(ad[v] != _) continue;
                      for(auto x : vc[v]) {                         int to = x.first; int64 wt = w[x.second];                         int64 tmp = d[v] + ad[v] + wt - d[to];
                          if(tmp < ad[to]) buc[ad[to] = tmp].emplace(to);                     }                 }             }             for(i = 1; i <= n; ++ i) if(ad[i] != c + 1) d[i] += ad[i];         }     } 	return 0; }
  }
 
  signed main() { return Legendgod::main(), 0; }
 
 
   |