• CodeForces


    Description

    一个 (n) 个点 (m) 条边的带权有向图, (q) 次询问,询问有两种:

    • (1 v) :求 (1)(v) 的最短路。
    • (2 c l_1 l_2 cdots l_c) :把编号为 (l_1,l_2,cdots ,l_c) 的边的边权增加一。

    (n,mle 10^5,qle 2000,wle 10^9)

    Solution

    大力每次跑 dijkstra 的复杂度是 (O[q(n+m)log_2n]) 的,完蛋。

    考虑跑完 dijkstra 之后对于某条边 ((u,v,w)) ,有 (dis[v] le dis[u]+w)

    那么在原图上跑一遍 dijkstra 后就把边 ((u,v,w)) 给改成 ((u,v, dis[u]+w-dis[v])) 。这样改了以后跑最短路,意义就变成了与原图最短路的差。差是一定不会大于 (min(c,n-1)) 的。于是就可以不用优先队列,用 (n) 个普通的队列,这样就可以去掉之前复杂度里的 (log_2 n) ,变成 (O[q(n+m)]) ,就可以过(?)了。

    #include<bits/stdc++.h>
    using namespace std;
    
    template <class T> void read(T &x) {
    	x = 0; bool flag = 0; char ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar()) flag |= ch == '-';
    	for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - 48; flag ? x = ~x + 1 : 0;
    }
    
    #define N 100010
    #define rep(i, a, b) for (int i = (a); i <= (b); i++)
    #define ll long long 
    #define INF 0x3f3f3f3f3f3f3f3f
    
    struct edge { int v, w, next; }e[N];
    int head[N];
    inline void add(int u, int v, int w) {
    	static int tot; e[++tot].v = v, e[tot].w = w, e[tot].next = head[u], head[u] = tot;
    }
    
    ll dis[N];
    int dis2[N];
    
    #define pli pair<ll, int>
    priority_queue<pli, vector<pli >, greater<pli > > q;
    queue<int> q2[N];
    bool vis[N];
    
    int main() {
    	int n, m, Q; read(n), read(m), read(Q);
    	rep(i, 1, m) {
    		int u, v, w; read(u), read(v), read(w);
    		add(u, v, w);
    	}
    	q.push(pli(0, 1));
    	memset(dis, 0x3f, sizeof dis); dis[1] = 0;
    	while (!q.empty()) {
    		int u = q.top().second; q.pop();
    		if (vis[u]) continue; vis[u] = 1;
    		for (int i = head[u], v; i; i = e[i].next) if (dis[v = e[i].v] > dis[u] + e[i].w)
    			dis[v] = dis[u] + e[i].w, q.push(pli(dis[v], v));
    	}
    	while (Q--) {
    		int op, k, x; read(op), read(k);
    		if (op == 1) printf("%lld
    ", dis[k] < INF ? dis[k] : -1);
    		else {
    			rep(i, 1, k) read(x), e[x].w++;
    			memset(dis2, 0x3f, sizeof dis2);
    			q2[0].push(1); dis2[1] = 0;
    			int mx = 0;
    			rep(i, 0, mx) while (!q2[i].empty()) {
    				int u = q2[i].front(); q2[i].pop();
    				if (dis2[u] < i) continue;
    				for (int j = head[u], v, t; j; j = e[j].next)
    					if (dis2[v = e[j].v] > (t = dis2[u] + (e[j].w + dis[u] - dis[v]))) {
    						dis2[v] = t;
    						if (t <= min(n - 1, k)) q2[t].push(v), mx = max(mx, t);
    					}	
    			}
    			rep(i, 1, n) dis[i] = min(INF, dis[i] + dis2[i]);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    ALOS卫星概况
    如何安装和配置jdk6u18windowsi586.exe
    请问是否可以直接发布切片好的服务 arcgis serever
    eclipse and myeclipse
    GISer还有机会屌丝逆袭吗?
    ArcGIS中加载百度地图
    细说委托
    白话地图投影之Proj.4地图投影库简介
    让OpenLayers添加百度地图(未完版)
    白话地图投影之墨卡托投影
  • 原文地址:https://www.cnblogs.com/aziint/p/9590487.html
Copyright © 2020-2023  润新知