zoj2853 Evolution
给定一个进化的矩阵图,问在m次之后最终的物种有多少个,实际上这和线性代数及其应用里的一个例题是一样的...总之就相当于煞笔的套个矩阵不断去乘m次,然后每次都会根据得到进化后各物种的个数,矩阵快速幂求一下就好了。
#include<cstdio> #include<cstdlib> #include<iostream> #include<string> #include<set> #include<algorithm> #include<vector> #include<queue> #include<list> #include<cmath> #include<cstring> #include<map> #include<stack> using namespace std; #define INF 0x3f3f3f3f #define maxn 205 #define ull unsigned long long #define ll long long #define hashmod 99999839 #define mod 9997 #define pi acos(-1) double z; int n,m,t,x,y; double c[2][maxn]; struct rec{ double a[maxn][maxn]; rec(){ for(int i = 0;i < n;++i){ for(int j = 0;j < n;++j){ a[i][j] = 0; } } } void init(){ for(int i = 0;i < n;++i){ for(int j = 0;j < n;++j){ if(i == j) a[i][j] = 1.0; } } } rec operator*(const rec& p){ rec ans; for(int i = 0;i < n;++i){ for(int j = 0;j < n;++j){ for(int k = 0;k < n;++k){ ans.a[i][j] += a[i][k] * p.a[k][j]; } } } return ans; } }; void solve(rec p){ rec ans; ans.init(); while(m){ if(m & 1){ ans = ans * p; } p = p * p; m >>= 1; } for(int i = 0;i < n;++i){ c[1][n-1] += c[0][i] * ans.a[i][n-1]; }- printf("%.0f\n",c[1][n-1]); } int main(){ // freopen("a.in","r",stdin); // freopen("b.out","w",stdout); while(~scanf("%d%d",&n,&m) && n + m){ for(int i = 0;i < n;++i){ c[1][i] = 0; } for(int i = 0;i < n;++i){ scanf("%lf",&c[0][i]); } scanf("%d",&t); rec p; p.init(); while(t--){ scanf("%d%d%lf",&x,&y,&z); p.a[x][y] += z; p.a[x][x] -= z; } solve(p); } return 0; }