跳转至

LGV 引理

简介

Lindström–Gessel–Viennot lemma,即 LGV 引理,可以用来处理有向无环图上不相交路径计数等问题。

前置知识:图论相关概念 中的基础部分、矩阵高斯消元求行列式

LGV 引理仅适用于 有向无环图

定义

ω(P) 表示 P 这条路径上所有边的边权之积。(路径计数时,可以将边权都设为 1)(事实上,边权可以为生成函数)

e(u,v) 表示 uv每一条 路径 Pω(P) 之和,即 e(u,v)=P:uvω(P)

起点集合 A,是有向无环图点集的一个子集,大小为 n

终点集合 B,也是有向无环图点集的一个子集,大小也为 n

一组 AB 的不相交路径 SSi 是一条从 AiBσ(S)i 的路径(σ(S) 是一个排列),对于任何 ijSiSj 没有公共顶点。

t(σ) 表示排列 σ 的逆序对个数。

引理

M=[e(A1,B1)e(A1,B2)e(A1,Bn)e(A2,B1)e(A2,B2)e(A2,Bn)e(An,B1)e(An,B2)e(An,Bn)] det(M)=S:AB(1)t(σ(S))i=1nω(Si)

其中 S:AB 表示满足上文要求的 AB 的每一组不相交路径 S

证明

由行列式定义可得

det(M)=σ(1)t(σ)i=1ne(ai,bσ(i))=σ(1)t(σ)i=1nP:aibσ(i)ω(P)

观察到 i=1nP:aibσ(i)ω(P),实际上是所有从 AB 排列为 σ 的路径组 Pω(P) 之和。

σ(1)t(σ)i=1nP:aibσ(i)ω(P)=σ(1)t(σ)P=σω(P)=P:AB(1)t(σ)i=1nω(Pi)

此处 P 为任意路径组。

U 为不相交路径组,V 为相交路径组,

P:AB(1)t(σ)i=1nω(Pi)=U:AB(1)t(U)i=1nω(Ui)+V:AB(1)t(V)i=1nω(Vi)

P 中存在一个相交路径组 Pi:a1ub1,Pj:a2ub2,则必然存在和它相对的一个相交路径组 Pi=a1ub2,Pj=a2ub1P 的其他路径与 P 相同。可得 ω(P)=ω(P),t(P)=t(P)±1

因此我们有 V:AB(1)t(σ)i=1nω(Vi)=0

det(M)=U:AB(1)t(U)i=1nω(Ui)=0

证毕[^1]。

例题

例 1 CF348D Turtles

题意:有一个 n×m 的格点棋盘,其中某些格子可走,某些格子不可走。有一只海龟从 (x,y) 只能走到 (x+1,y)(x,y+1) 的位置,求海龟从 (1,1)(n,m) 的不相交路径数对 109+7 取模之后的结果。2n,m3000

比较直接的 LGV 引理的应用。考虑所有合法路径,发现从 (1,1) 出发一定要经过 A={(1,2),(2,1)},而到达终点一定要经过 B={(n1,m),(n,m1)},则 A,B 可立即选定。应用 LGV 引理可得答案为:

|f(a1,b1)f(a1,b2)f(a2,b1)f(a2,b2)|=f(a1,b1)×f(a2,b2)f(a1,b2)×f(a2,b1)

其中 f(a,b) 为图上 ab 的路径数,带有障碍格点的路径计数问题可以直接做一个 O(nm) 的 dp,则 f 易求。最终复杂度 O(nm)

参考代码
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

using ll = long long;
constexpr int MOD = 1e9 + 7;
constexpr int SIZE = 3010;

string board[SIZE];
int dp[SIZE][SIZE];

int f(int x1, int y1, int x2, int y2) {
  memset(dp, 0, sizeof dp);

  dp[x1][y1] = board[x1][y1] == '.';
  for (int i = 1; i <= x2; i++) {
    for (int j = 1; j <= y2; j++) {
      if (board[i][j] == '#') {
        continue;
      }
      dp[i][j] = (dp[i][j] + dp[i - 1][j]) % MOD;
      dp[i][j] = (dp[i][j] + dp[i][j - 1]) % MOD;
    }
  }
  return dp[x2][y2] % MOD;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n, m;
  cin >> n >> m;

  for (int i = 1; i <= n; i++) {
    cin >> board[i];
    board[i] = " " + board[i];
  }

  ll f11 = f(1, 2, n - 1, m);
  ll f12 = f(1, 2, n, m - 1);
  ll f21 = f(2, 1, n - 1, m);
  ll f22 = f(2, 1, n, m - 1);

  ll ans = ((f11 * f22) % MOD - (f12 * f21) % MOD + MOD) % MOD;
  cout << ans << '\n';

  return 0;
}
例 2 HDU 5852 Intersection is not allowed!

题意:有一个 n×n 的棋盘,一个棋子从 (x,y) 只能走到 (x,y+1)(x+1,y),有 k 个棋子,一开始第 i 个棋子放在 (1,ai),最终要到 (n,bi),路径要两两不相交,求方案数对 109+7 取模。1n1051k100,保证 $1\le a_1