《挑战程序设计竞赛》 扩展欧几里得算法 + SPFA

知识补充:

  • SPFA算法:Bellman-Ford算法的优化算法,方法是: 1.把当前点(最开始是起点)入队,并将标记是否在队列中的visit数组的当前点设为true。 2.取队列顶部元素,并弹出队列首的元素,把该元素对应的visit设为false,由该元素扩展的所有边进行更新,并把与该顶点相连的没有在队列中的顶点放入队列中,并将标记是否在队列中的顶visit数组设为true。 3.重复以上步骤,直到队列为空
  • SPFA算法可以处理负权边,但效率比优先队列优化的Dijkstra算法低。不能处理负圈,如要处理负圈,需要加一个结点入队次数计数器,如果某一个结点入队次数达到n次,则存在负圈(总共只有n - 1条边,即使把所有边都更新了一次才求出这个顶点也不至于达到n次入队,故一定是存在负圈的情况)。
  • 贝祖等式:有整数a,b和他们的最大公约数d。那么二元一次方程:
    ax+by=kd(k=1,2,3...)
    必有解。由此可知,如果d等于1,那么他们的最大公约数就为1,说明a和b互为质数。解这类方程只需先用扩展欧几里得算法解出:
    ax+by=d
    再乘以k倍即可。(a和0的最大公约数为a)。
  • 扩展欧几里得算法:目的是为了求方程:
    ax+by=gcd(a,b)
    的一解: (x,y) 。方法就是对欧几里得算法求出最大公约数后,根据数论知识易推断出的法则:
    y=x(a/b)y
    x=y
    倒推出来。

扩展欧几里得算法的代码:

int extgcd(int a, int b, int& x, int& y) {
    int d = a;
    if (b) {
        d = extgcd(b, a % b, y, x);
        y -= (a / b) * x;
    } else {
        x = 1, y = 0;
    }
    return d;
}

你可能感兴趣的:(《挑战程序设计竞赛》 扩展欧几里得算法 + SPFA)