Chieh's Blog

Because Of Coding

ZOJ Problem Set - 2853 Evolution

Chieh posted @ 2018年3月14日 20:39 in ZOJ , 322 阅读

飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1853

大致意思:(我是直接将0~n-1变为1~n)有m回合进化,每次进化有T个要求,就是i中有P(i,j)变为j,求最后n物种的数量,典型的矩阵快速幂的题目,令matrix[i][j]表示第i个物种有多少转化为第j个物种,即P(i,j),A[]为初始状态,则结果矩阵为A*(matrix)^m其中最后一列的和即为答案

//
//  main.cpp
//  zoj2853
//
//  Created by cfhaiteeh on 14/03/2018.
//  Copyright © 2018 cfhaiteeh. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define  LL long long
using namespace  std;
struct Matrix{
    double  mat[234][234];
};
int n,m,k;
Matrix MUL(Matrix a,Matrix b){
    Matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j]);
            }
        }
    }
    return c;
}
Matrix poww(Matrix a,int k){
    Matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i=1;i<=n;i++)ans.mat[i][i]=1;
    while(k!=0){
        if(k%2==1){
            ans=MUL(ans,a);
        }
        a=MUL(a,a);
        k/=2;
    }
    return ans;
}
Matrix a;
LL ai[234];
double ci[234];
void init(){
    memset(a.mat,0,sizeof(a.mat));
    for(int i=1;i<=n;i++)scanf("%lld",&ai[i]);
    int t;
    scanf("%d",&t);
    for(int i=1;i<=n;i++)ci[i]=1;
    for(int i=1;i<=t;i++){
        int u,v;
    
        double c;
        scanf("%d%d%lf",&u,&v,&c);
            u++;v++;
        ci[u]-=c;
        a.mat[u][v]+=c;
    }
    for(int i=1;i<=n;i++)a.mat[i][i]=ci[i];
}
double ans;
void play(){
    Matrix c=poww(a,m);
    ans=0;
    for(int i=1;i<=n;i++){
        ans+=ai[i]*c.mat[i][n];
    }
}
void pri(){
    printf("%.0f\n",ans);
}
int main() {
    // insert code here...
    while(scanf("%d%d",&n,&m)!=EOF){
        if(n==0&&m==0)break;
        init();
        play();
        pri();
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter