AT_dp_r Walk题解
题目描述
给定一个有 N 个顶点的简单有向图 G。顶点编号为 1,2,…,N。
对于每一对 i,j(1≤i,j≤N),是否存在从顶点 i 到顶点 j 的有向边由整数 ai,j 给出。若 ai,j=1,则表示存在从 i 到 j 的有向边;若 ai,j=0,则不存在。
请问在图 G 中,长度为 K 的有向路径共有多少条?请输出答案对 109+7 取模的结果。注意,可以多次经过同一条边的路径也要计入。
输入格式
输入通过标准输入给出,格式如下:
N K a1,1 … a1,N : aN,1 … aN,N
输出格式
请输出图 G 中长度为 K 的有向路径的总数,对 109+7 取模。
显示翻译
题意翻译
输入输出样例
输入 #1复制
4 2 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0
输出 #1复制
6
输入 #2复制
3 3 0 1 0 1 0 1 0 0 0
输出 #2复制
3
输入 #3复制
6 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0
输出 #3复制
1
输入 #4复制
1 1 0
输出 #4复制
0
输入 #5复制
10 1000000000000000000 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 0 1 0 1 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 1 1 1 0
输出 #5复制
957538352
说明/提示
限制条件
- 所有输入均为整数。
- 1≤N≤50
- 1≤K≤1018
- ai,j 仅为 0 或 1。
- ai,i=0
样例解释 1
图 G 如下所示。

长度为 2 的有向路径共有如下 6 条:
- 1→2→3
- 1→2→4
- 2→3→4
- 2→4→1
- 3→4→1
- 4→1→2
样例解释 2
图 G 如下所示。

长度为 3 的有向路径共有如下 3 条:
- 1→2→1→2
- 2→1→2→1
- 2→1→2→3
样例解释 3
图 G 如下所示。

长度为 2 的有向路径共有如下 1 条:
- 4→5→6
样例解释 5
请不要忘记将答案对 109+7 取模。
由 ChatGPT 4.1 翻译
思路
用矩阵优化即可。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,m,mod=1e9+7,lk=0;
struct mat{
long long a[105][105];
}a,b;
mat kc(mat c1,mat c2){
mat c;
memset(c.a,0,sizeof(c.a));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
c.a[i][j]=(c.a[i][j]+c1.a[i][k]*c2.a[k][j])%mod;
}
}
}
return c;
}
mat abc(mat a2,long long m2){
mat b2;
memset(b2.a,0,sizeof(b2.a));
for(int i=1;i<=n;i++){
b2.a[i][i]=1;
}
while(m2!=0){
if(m2%2==1){
b2=kc(b2,a2);
}
a2=kc(a2,a2);
m2/=2;
}
return b2;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a.a[i][j];
}
}
b=abc(a,m);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
lk=(lk+b.a[i][j])%mod;
}
}
cout<<lk<<endl;
return 0;
}

浙公网安备 33010602011771号