一些新知识(未完全消化的)

TITLE

    • 整理:
      • 目录:
    • 未整理:
          • 曼哈顿距离与契比雪夫距离
          • 位运算(摘自usaco)
          • 对邻接表的进一步理解
          • 测试网上评测的速度

整理:

目录:

未整理:

曼哈顿距离与契比雪夫距离

曼哈顿距离: d i s = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ dis = |x_1-x_2|+|y_1-y_2| dis=x1x2+y1y2
契比雪夫距离: d i s = m a x ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ∣ ) dis = max(|x_1-x_2|,|y_1-y_2|) dis=max(x1x2,y1y2)
两者相互转换:
曼哈顿距离域转成契比雪夫距离域: ( x , y ) ⇒ ( x + y , x − y ) (x,y)\Rightarrow(x+y,x-y) (x,y)(x+y,xy)
契比雪夫距离域转成曼哈顿距离域: ( x , y ) ⇒ ( x + y 2 , x − y 2 ) (x,y)\Rightarrow(\frac{x+y}{2},\frac{x-y}{2}) (x,y)(2x+y,2xy)
之后会更模拟退火(最小圆覆盖,球覆盖,以及wyz上的松鼠聚会)…

位运算(摘自usaco)

Binary

Value Sample Meaning
x 00101100 the original x value
x & -x 00000100 extract lowest bit set
x | -x 11111100 create mask for lowest-set-bit & bits to its left
x ^ -x 11111000 create mask bits to left of lowest bit set
x & (x-1) 00101000 strip off lowest bit set
x | (x-1) 00101111 fill in all bits below lowest bit set
x ^ (x-1) 00000111 create mask for lowest-set-bit & bits to its right
~x & (x-1) 00000011 create mask for bits to right of lowest bit set
x | (x+1) 00101101 toggle lowest zero bit
x / (x&-x) 00001011 shift number right so lowest set bit is at bit 0

–> 避免遍历位操作,而是可以直接找到位的最低位,并对区间位进行O(1)运算。

对邻接表的进一步理解

在表示图的过程中我们会使用到邻接表这种数据结构,其中较为重要的一个操作便是加边操作。其伪代码为:

cnt = The number of edge having been added
procedure addedge(u,v,w)
{
	edge[v].v = v;
	edge[v].w = w;
	edge[v].next = head[u];
	head[u] = cnt++;
}

以前没好好理解这个 h e a d [ u ] = c n t head[u] = cnt head[u]=cnt++的问题,导致有次复杂图(相对于简单图)的次短路做不出来…
研究了一小会,邻接表为每个节点构建的链表有以下性质:

  • 1、对于某条从u出发的边而言,加入图中,则该头结点往后移动。所以在遍历节点链表的时候,是根据添边的顺序反向遍历的(最先加入的边的next指针指向-1)
  • 2、由第一条可知,head[u]存的是u节点链表中的最后一位,平常我们遍历的i值,其实是个指针,指向edge[i]这个节点,而edge[i].next也是一个指针。所以迭代的i作为指针,来依次访问链表中的edge[i]节点元素

完毕(另外spfa用双端队列优化的代码,其实在原spfa上改动不大,理解一下就好了)

测试网上评测的速度
//#define ONLINE_JUDGE
int main{
	#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long _begin_time = clock();
	#endif
	...//你的算法
	#ifndef ONLINE_JUDGE
    long _end_time = clock();
    printf("time = %ld ms.", _end_time - _begin_time);
	#endif
	return 0;
}

用的时候把数据存在文件里,把宏定义那一处删掉注销符号就好了。

你可能感兴趣的:(知识储备)