 /**//*
題意:N種物種,有初始個數 T種轉化過程 a b c表示每一次轉化,將有a*c轉變為b
問經過M次轉化后,最后編號N-1的物種的個數 rounded-to 四舍五入
構造轉化矩陣A
(num[0],num[1], num[N-1])*A = 結果
A[a][a]-=c;
A[a][b]+=c;
A初始為單位矩陣
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN = 201;
const double eps = 1e-15;//題目100,000,000,所以*1e-8就為1了
int N,M;
double num[201];
double A[MAXN][MAXN],z[MAXN][MAXN];

void mul(double A[][MAXN],double B[][MAXN])//A=A*B
  {
//直接開個數組,然后賦值更簡單!
double R[MAXN][MAXN];
memset(R,0,sizeof(R));
for(int k=0;k<N;k++)
for(int i=0;i<N;i++)
if(A[i][k]>eps)//
for(int j=0;j<N;j++)
R[i][j]+=A[i][k]*B[k][j];
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
A[i][j]=R[i][j];
}
 /**//*
這種遞歸的應該比那種非遞歸的快
*/
void power(double m[][MAXN],int n)
  {
if(n==1)
 {
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
m[i][j]=A[i][j];
return ;
}
power(m,n/2);
mul(m,m);
if(n&1)mul(m,A);
}
int main()
  {
//freopen("in","r",stdin);
while(scanf("%d%d",&N,&M),N||M)
 {
for(int i=0;i<N;i++)
scanf("%lf",&num[i]);
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
A[i][j]=(i==j);
int T;
scanf("%d",&T);
while(T--)
 {
int a,b;
double c;
scanf("%d%d%lf",&a,&b,&c);
A[a][a]-=c;
A[a][b]+=c;
}
power(z,M);
double ans = 0;
for(int i=0;i<N;i++)
ans+=num[i]*z[i][N-1];
printf("%.0f\n",ans);
}
return 0;
}
|
|
常用鏈接
隨筆分類
Links
搜索
最新評論

|
|