图论-平方图

图论-平方图

问题

此文我们讨论一下对一个邻接矩阵进行平方,三次方,n次方的意义和相应的邻接链表的算法。

首先我们定义 k × k k \times k k×k邻接矩阵 G G G,则元素

G x y 2 = ∑ i = 1 k G x k ⋅ G k y G^{2}_{xy}= \sum_{i=1}^{k}G_{xk} \cdot G_{ky} Gxy2=i=1kGxkGky

因此邻接矩阵平方相乘的意义是得到平方图,即有向图 G = ( V , E ) G=(V,E) G=(V,E)平方图是图 G 2 = ( V , E 2 ) G^{2}=(V,E^{2}) G2=(V,E2),边 ( u , v ) ∈ E 2 (u,v) \in E^{2} (u,v)E2的充分必要条件的图 G G G包含一条路径最多由两条边构成从 u u u v v v的路径。如果不包含自环(对角线元素为1)那就去掉“最多”。

同理,三次方相乘就是存在一条路径(最多)三条边可达;n次方就是存在一条路径(最多)n条边可达。

这就是矩阵相乘和图论之间的关系。

相应的,邻接链表也可以写出该算法。遍历每一个u点的邻接链表得到k点,其中存在边 ( u , k ) (u,k) (u,k),然后再遍历k的邻接链表得到节点v,则存在边 ( k , v ) (k,v) (k,v),则在图 G 2 G^{2} G2中一定存在边 ( u , v ) (u,v) (u,v)

例题

P1057

平方图+矩阵快速幂

#include <bits/stdc++.h>

using namespace std;

struct Matrix
{
    int arr[35][35];
    int size;

    Matrix(int s):size(s)
    {
        for(int i = 0; i<size; i++)
            for(int j=0; j<size; j++)
                arr[i][j] = 0;
    }

    void one()
    {
        for(int i = 0; i<size; i++)
            arr[i][i] = 1;
    }

    Matrix operator*(const Matrix& m)
    {
        Matrix res(size);
        for(int i = 0; i<size; i++)
            for(int j = 0; j<size; j++)
                for(int k =0; k<size; k++)
                    res.arr[i][j]+= arr[i][k] * m.arr[k][j];
        return res;
    }
};

int main()
{
    int n,m;
    cin >> n >> m;
    Matrix A(n);
    for(int i = 0; i<n; i++)
    {
        A.arr[i][(i+1) %n] = A.arr[i][(i-1+n) %n] = 1;
    }

    Matrix ans(n);
    ans.one();

    for(; m != 0; m >>= 1)
    {
        if((m&1) == 1) ans = ans * A;
        A = A * A;
    }

    cout << ans.arr[0][0];
    return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值