 /**//*
题意: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
搜索
最新评论

|
|