zoukankan      html  css  js  c++  java
  • P5331 [SNOI2019]通信

    题目链接

    由“每个哨站只能被后面的至多一个哨站连接”可以想到二分图网络流。我们有一个 (n^2) 暴力建图的方法:((S, x, 1, 0),(x,y',1,|a_x-a_y|),(y',T,1,0),(x,T,1,W))

    然而这样将会有 (n^2) 条边。

    不过我们发现,每个点都只会和其左边的所有点连边,因此可以想到线段树优化建图。不过每条边的权值都不一样,因此这个方法行不通。

    然后考虑类似CDQ分治一样,考虑左边对左边,左边对右边,右边对右边的影响。我们可以在当前分治区间内把左边单拎出来,右边单拎出来,这样右边就可以放心大胆地连左边了。

    然后观察边权的特殊性。由于边权是和点权差的绝对值有关,我们可以把点权都拎出来排序去重,看作一些点(一条链)。相邻的点之间流动需要耗费点权差这么多的代价。然后边数就可以变成 (O(L)) 级别的了。总边数:(O(nlogn))

    关键代码:

    void build(int L, int R) {
    	if (L == R)	return ;
    	int mid = (L + R) >> 1;
    	htot = ltot = 0;
    	for (register int i = L; i <= R; ++i)	a[++htot] = h[i];
    	a[htot + 1] = -18364123;
    	sort(a + 1, a + 1 + htot);
    	for (register int i = 1; i <= htot; ++i)
    		if (a[i] != a[i + 1])	lsh_a[++ltot] = a[i];
    	for (register int i = 1; i < ltot; ++i)
    		Addedge(ptot + i, ptot + i + 1, inf, lsh_a[i + 1] - lsh_a[i]),
    		Addedge(ptot + i + 1, ptot + i, inf, lsh_a[i + 1] - lsh_a[i]);
    	for (register int i = L; i <= mid; ++i) {
    		int p = lower_bound(lsh_a + 1, lsh_a + 1 + ltot, h[i]) - lsh_a + ptot;
    		Addedge(p, i + n, 1, 0);
    	}
    	for (register int i = mid + 1; i <= R; ++i) {
    		int p = lower_bound(lsh_a + 1, lsh_a + 1 + ltot, h[i]) - lsh_a + ptot;
    		Addedge(i, p, 1, 0);
    	}
    	ptot += ltot;
    	build(L, mid), build(mid + 1, R);
    }
    
  • 相关阅读:
    第二章-2、显示/隐藏/切换
    第二章-1、打开链接
    1、创建自定义原件库
    3、常用小例子
    2、快捷键
    IOS开发中(null)与<null>的处理
    iOS UIPageControl的操作,设置圆点大小,显示图片等
    iOS 支付回调区分支付宝和微信的方法
    iOS 字符串的操作,去掉某一个字符或者替换成其他字符
    iOS 判断当前网络状态
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13470705.html
Copyright © 2011-2022 走看看