• Dynamic Shortest Path CodeForces


    大意: n结点有向有权图, m个操作, 增加若干边的权重或询问源点为1的单源最短路.

    本题一个特殊点在于每次只增加边权, 并且边权增加值很小, 询问量也很小. 我们可以用johnson的思想, 转化为差值最短路, 这样边权就在n-1以内, 可以直接暴力跑桶优化dijkstra.

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <math.h>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <bitset>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    #define hr putchar(10)
    #define pb push_back
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    #define x first
    #define y second
    #define io std::ios::sync_with_stdio(false)
    #define endl '
    '
    using namespace std;
    typedef long long ll;
    typedef pair<ll,int> pli;
    
    
    const int N = 1e5+10;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    int n, m, q;
    struct _ {int to,w;} E[N];
    vector<int> g[N];
    int vis[N], d2[N];
    ll d[N];
    priority_queue<pli,vector<pli>, greater<pli> > Q;
    queue<int> q2[N];
    
    void Dij() {
    	memset(d,0x3f,sizeof d);
    	Q.push(pli(d[1]=0,1));
    	while (Q.size()) {
    		int u = Q.top().y; Q.pop();
    		if (vis[u]) continue;
    		vis[u] = 1;
    		for (auto &&id:g[u]) {
    			auto &e = E[id];
    			ll dd = d[u]+e.w;
    			if (dd<d[e.to]) Q.push(pli(d[e.to]=dd,e.to));
    		}
    	}
    }
    void Dij2(int k) {
    	REP(i,1,k) {int t; scanf("%d", &t), ++E[t].w;}
    	memset(d2,0x3f,sizeof d2);
    	q2[0].push(1), d2[1] = 0;
    	int mx = 0;
    	REP(i,0,mx) while (q2[i].size()) {
    		int u = q2[i].front(); q2[i].pop();
    		if (d2[u]<i) continue;
    		for (auto &&id:g[u]) {
    			auto &e = E[id];
    			int dd = d2[u]+(e.w+d[u]-d[e.to]);
    			if (dd<d2[e.to]) {
    				d2[e.to] = dd;
    				if (dd<=min(n-1,k)) { 
    					q2[dd].push(e.to);
    					mx = max(mx, dd);
    				}
    			}
    		}
    	}
    	REP(i,1,n) d[i]=min(INF,d[i]+d2[i]);
    }
    
    int main() {
    	scanf("%d%d%d", &n, &m, &q);
    	REP(i,1,m) {
    		int u;
    		scanf("%d%d%d", &u, &E[i].to, &E[i].w);
    		g[u].pb(i);
    	}
    	Dij();
    	while (q--) {
    		int op, x;
    		scanf("%d%d", &op, &x);
    		if (op==1) printf("%lld
    ", d[x]<INF?d[x]:-1);
    		else Dij2(x);
    	}
    }
    
  • 相关阅读:
    缺少一个=出现的问题
    快速排序+归并排序
    ACwing简单题(14)
    浅谈#ifndef
    fstream 使用详解
    _stat函数的使用
    关于文件结构体的使用
    new的使用
    ACwing13题目
    ACwing13题
  • 原文地址:https://www.cnblogs.com/uid001/p/10628602.html
Copyright © 2020-2023  润新知