• 2021CCPC浙江省赛 D Shortest Path Query


    可以发现可以构建出的是一棵树,且树的深度在20层及以内

    刚开始想对于每条路径跑最短路,然后都跑一边得出答案,但是发现因为路径可以重叠,所以后面求的路径会修改一些公共路径的最短路,所以不能这么求

    考虑什么是不变的,一个点到自己的最短路一定是0,所以从每个点出发,跑它到所有子节点的最短路,这个路一定是这两个点最终的最短路,而且因为这是一个二叉树,所以复杂度为

    (T(n) = 2*T(n/2) + nlogn)
    大约是(O(n(logn)^2))
    然后对于每次询问,找所有的公共祖先,求解即可

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    typedef long long ll;
    typedef pair<ll, int> P;
    vector < P > edge[N];
    ll f[N][30];
    bool vis[N];
    void cmin(ll & a, ll b) { a = min(a, b); }
    int main() {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	memset(f, 0x3f, sizeof(f));
    	for (int i = 1; i <= m; i++) {
    		int u, v, j; ll w;
    		scanf("%d%d%lld", &u, &v, &w);
    		if (u > v)	swap(u, v);
    		edge[u].emplace_back(v, w);
    		edge[v].emplace_back(u, w);
    		for (j = 0; (v >> j) != u; j++);
    		cmin(f[v][j], w);
    	}
    	for (int i = 1; i <= n; i++) {
    		priority_queue < P, vector < P >, greater < P > > Q;
    		vector < int > c;
    		Q.emplace(0, i);
    		int j; f[i][0] = 0;
    		while (!Q.empty()) {
    			P u = Q.top(); Q.pop();
    			if (vis[u.second])	continue;
    			vis[u.second] = true; c.emplace_back(u.second);
    			for (j = 0; (u.second >> j) != i; j++);
    			cmin(f[u.second][j], u.first);
    			for (auto x:edge[u.second]) {
    				if (!vis[x.first] && x.first >= i)
    					Q.emplace(u.first + x.second, x.first);
    			}
    		}
    		for (auto x:c)	vis[x] = false;
    	}
    	int q; scanf("%d", &q);
    	while (q--) {
    		int u, v, j = 0; scanf("%d %d", &u, &v);
    		ll ans = (1ll << 60);
    		for (int i = 0; i < 28; i++) {
    			while ((v >> i) < (u >> j))	j++;
    			if ((v >> i) == (u >> j))
    				cmin(ans, f[u][j] + f[v][i]);
    		}
    		if (ans > 60ll * 1e9)	puts("-1");
    		else printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
  • 原文地址:https://www.cnblogs.com/cminus/p/14751789.html
Copyright © 2020-2023  润新知