免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
最近ではブログを開くには、いくつかの比較的単純なものではなく、一人のことを学びました
1、フロイドは、最小のリングを見つけます
私はこれは本当に深めることを学んだと思います ああ理解しました。我々は中間点に列挙するたびので、 、以前に関与しません 最短で、私たちがすることができます 2つの隣接する点 環を構成します。
コードは以下の通りです
for(k = 1; k <= n; k++){
for(i = 1; i <= n; i++){
for(j = 1; j <= n; j++){
if(i == j || i == k || k == j) continue;
ans = min(ans, f[i][j] + mp[i][k] + mp[k][j]);
}
}
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++) f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
}
2、迅速なパワー・マトリックス
パワーと高速原則同じですが、行列乗算に乗算。関数は配列を返すことができないので、私たちは以下の構造をカプセル化するマトリックスを使用します。
コードは以下の通りです
#include <bits/stdc++.h>
#define LL long long
#define mod 1000000007
#define mem(p) memset(&p, 0, sizeof(p))
using namespace std;
LL z = 1;
struct mat{
LL a[105][105];
int r, c;
};
mat p, ans;
int n;
mat matmul(mat x, mat y){
int i, j, k;
mat p;
mem(p);
for(i = 0; i < x.r; i++){
for(j = 0; j < y.c; j++){
for(k = 0; k < x.c; k++){
p.a[i][j] = (p.a[i][j] + z * x.a[i][k] * y.a[k][j] % mod) % mod;
}
}
}
p.r = x.r; p.c = y.c;
return p;
}
void mul(LL b){
int i, j;
while(b){
if(b & 1) ans = matmul(ans, p);
p = matmul(p, p);
b >>= 1;
}
for(i = 0; i < n; i++){
for(j = 0; j < n; j++) printf("%d ", ans.a[i][j]);
printf("\n");
}
}
int main(){
int i, j, c;
LL k;
scanf("%d%lld", &n, &k);
for(i = 0; i < n; i++)
for(j = 0; j < n; j++){
scanf("%d", &c);
p.a[i][j] = ans.a[i][j] = c;
}
p.r = ans.r = p.c = ans.c = n;
mul(k - 1);
return 0;
}