How many ways??
生活随笔
收集整理的這篇文章主要介紹了
How many ways??
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://acm.hdu.edu.cn/showproblem.php?pid=2157
題解:經典矩陣算法。把給定的圖轉為鄰接矩陣,即A(i,j)=1當且僅當存在一條邊i->j。令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),實際上就等于從點i到點j恰好經過2條邊的路徑數(枚舉k為中轉點)。類似地,C*A的第i行第j列就表示從i到j經過3條邊的路徑數。同理,假設要求經過k步的路徑數,我們僅僅須要二分求出A^k就可以。
參考文章:矩陣快速冪
/* *@Author: STZG *@Language: C++ */ #include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<deque> #include<stack> #include<cmath> #include<list> #include<map> #include<set> //#define DEBUG #define RI register int #define endl "\n" using namespace std; typedef long long ll; //typedef __int128 lll; const int N=100000+10; const int M=100000+10; const int MOD=1e9+7; const double PI = acos(-1.0); const double EXP = 1E-8; const int INF = 0x3f3f3f3f; int t,n,m,k,p,l,r,u,v; int ans,cnt,flag,temp,sum; int s[25][25]; int b[25][25]; int a[25][25]; char str; struct node{}; void Matrix(int a[25][25],int b[25][25]){int c[25][25];memset(c,0,sizeof(c));for(int i=0;i<n;i++){for(int j=0;j<n;j++){for(int k=0;k<n;k++){c[i][j]=(c[i][j]+a[i][k]*b[k][j])%1000;}}}for(int i=0;i<n;i++){for(int j=0;j<n;j++){a[i][j]=c[i][j];}} } int power(int A,int B,int k){for(int i=0;i<n;i++){for(int j=0;j<n;j++){a[i][j]=(i==j);b[i][j]=s[i][j];}}while(k){if(k&1)Matrix(a,b);Matrix(b,b);k>>=1;}return a[A][B]; } int main() { #ifdef DEBUGfreopen("input.in", "r", stdin);//freopen("output.out", "w", stdout); #endif//ios::sync_with_stdio(false);//cin.tie(0);//cout.tie(0);//while(~scanf("%d%d",&n,&m)&&n+m){memset(s,0,sizeof(s));for(int i=1;i<=m;i++){scanf("%d%d",&u,&v);s[u][v]=1;}scanf("%d",&t);for(int i=1;i<=t;i++){scanf("%d%d%d",&u,&v,&k);cout<<power(u,v,k)<<endl;}}#ifdef DEBUGprintf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC); #endif//cout << "Hello world!" << endl;return 0; }?
總結
以上是生活随笔為你收集整理的How many ways??的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Rightmost Digit
- 下一篇: Raising Modulo Numbe