zoukankan      html  css  js  c++  java
  • 【BZOJ 4070】【APIO 2015】雅加达的摩天楼

    http://www.lydsy.com/JudgeOnline/problem.php?id=4070
    分块建图。
    对每个(P_i)分类讨论,(P_i>sqrt N)则直接连边,边数少于(sqrt N)
    对每个横跨长度(leqsqrt N)的边,建一条“滑轨”,当(P_ileqsqrt N)时则把这个点送到滑轨上,可以到任何一个位置下来。一共要建(sqrt N)条滑轨。
    最后跑最短路就可以了,uoj上死活过不了hack数据,貌似过了的都没有建图?
    时间复杂度(O(nsqrt n)),如果spfa是(O(m))的话。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N = 30003;
    const int B = 113;
    const int Qtot = N * B - 1;
    
    int nxt[N * B * 5], to[N * B * 5], w[N * B * 5];
    int point[N * B], cnt = 0, n, m, S[N], P[N];
    
    void ins(int u, int v, int W) {
    	nxt[++cnt] = point[u]; to[cnt] = v; w[cnt] = W; point[u] = cnt;
    }
    
    bool inq[N * B];
    int dist[N * B], tot;
    queue <int> qu;
    
    int spfa(int s, int t) {
    	memset(dist, 127, sizeof(int) * (tot + 1));
    	dist[s] = 0;
    	int u, v, di; qu.push(s); inq[s] = true;
    	while (!qu.empty()) {
    		inq[u = qu.front()] = false; qu.pop();
    		for (int i = point[u]; i; i = nxt[i]) {
    			v = to[i];
    			if ((di = dist[u] + w[i]) < dist[v]) {
    				dist[v] = di;
    				if (!inq[v]) {
    					inq[v] = true;
    					qu.push(v);
    				}
    			}
    		}
    	}
    	return dist[t] == dist[0] ? -1 : dist[t];
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	int Si, Pi; tot = B * n;
    	
    	int tt = n;
    	for (int i = 1; i < B; ++i)
    		for (int j = 1; j <= n; ++j)
    			ins(++tt, j, 0);
    	
    	for (int i = 1; i < B; ++i)
    		for (int j = 1; j <= i; ++j) {
    			int tmp = j + i, st = i * n;
    			while (tmp <= n) {
    				ins(st + tmp - i, st + tmp, 1);
    				ins(st + tmp, st + tmp - i, 1);
    				tmp += i;
    			}
    		}
    	
    	for (int i = 1; i <= m; ++i) {
    		scanf("%d%d", &Si, &Pi);
    		S[i] = ++Si; P[i] = Pi;
    		if (Pi >= B) {
    			for (int tmp = Si + Pi, j = 1; tmp <= n; tmp += Pi, ++j)
    				ins(Si, tmp, j);
    			for (int tmp = Si - Pi, j = 1; tmp >= 1; tmp -= Pi, ++j)
    				ins(Si, tmp, j);
    		} else
    			ins(Si, Pi * n + Si, 0);
    	}
    	
    	printf("%d
    ", spfa(S[1], S[2]));
    	return 0;
    }
    
  • 相关阅读:
    关于session
    bootstrap的栅格系统
    js小知识点
    js获取div基础元素
    fixed固定元素
    定时器之延时触发鼠标悬浮事件
    Comparator分组测试
    List去重比较
    点击事件和双击事件
    开机自启动
  • 原文地址:https://www.cnblogs.com/abclzr/p/6733333.html
Copyright © 2011-2022 走看看