zoj 2974 Just Pour the Water矩阵快速幂

Just Pour the Water


Time Limit: 2 Seconds      Memory Limit: 65536 KB


Shirly is a very clever girl. Now she has two containers (A and B), each with some water. Every minute, she pours half of the water in A into B, and simultaneous pours half of the water in B into A. As the pouring continues, she finds it is very easy to calculate the amount of water in A and B at any time. It is really an easy job :).

But now Shirly wants to know how to calculate the amount of water in each container if there are more than two containers. Then the problem becomes challenging.

Now Shirly has N (2 <= N <= 20) containers (numbered from 1 to N). Every minute, each container is supposed to pour water into another K containers (K may vary for different containers). Then the water will be evenly divided into K portions and accordingly poured into anther K containers. Now the question is: how much water exists in each container at some specified time?

For example, container 1 is specified to pour its water into container 1, 2, 3. Then in every minute, container 1 will pour its 1/3 of its water into container 1, 2, 3 separately (actually, 1/3 is poured back to itself, this is allowed by the rule of the game).

Input

Standard input will contain multiple test cases. The first line of the input is a single integer T (1 <= T <= 10) which is the number of test cases. And it will be followed by T consecutive test cases.

Each test case starts with a line containing an integer N, the number of containers. The second line contains N floating numbers, denoting the initial water in each container. The following N lines describe the relations that one container(from 1 to N) will pour water into the others. Each line starts with an integer K (0 <= K <= N) followed by K integers. Each integer ([1, N]) represents a container that should pour water into by the current container. The last line is an integer M (1<= M <= 1,000,000,000) denoting the pouring will continue for M minutes.

Output

For each test case, output contains N floating numbers to two decimal places, the amount of water remaining in each container after the pouring in one line separated by one space. There is no space at the end of the line.

Sample Input

1
2
100.00 100.00
1 2
2 1 2
2

Sample Output

75.00 125.00

Note: the capacity of the container is not limited and all the pouring at every minute is processed at the same time.

题目大意:有N个容器,编号为i的容器可以把自己的水分成k份放进k个容器里,每次把1—N依次操作,求M次后各个容器里的水量。

解题思路:矩阵快速幂(注意K=0的情况,我被坑了一发)。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5
 6 const int maxn=25;
 7 double f[maxn];
 8
 9 struct Matrix
10 {
11     double a[maxn][maxn];
12     int n;
13 };
14
15 Matrix Matrix_mult(Matrix A,Matrix B)
16 {
17     Matrix C;C.n=A.n;
18     int i,j,k;
19     for(i=1;i<=A.n;i++)
20     {
21         for(j=1;j<=A.n;j++)
22         {
23             double sum=0;
24             for(k=1;k<=A.n;k++)
25                 sum+=A.a[i][k]*B.a[k][j];
26             C.a[i][j]=sum;
27         }
28     }
29     return C;
30 }
31
32 Matrix Matrix_pow(Matrix A,int m)
33 {
34     Matrix ret;ret.n=A.n;
35     memset(ret.a,0,sizeof(ret.a));
36     for(int i=1;i<=A.n;i++) ret.a[i][i]=1.0;
37     while(m)
38     {
39         if(m&1) ret=Matrix_mult(A,ret);
40         A=Matrix_mult(A,A);m>>=1;
41     }
42     return ret;
43 }
44
45 void Printf(Matrix A)
46 {
47     for(int i=1;i<=A.n;i++)
48     {
49         double ans=0;
50         for(int j=1;j<=A.n;j++)
51             ans+=A.a[i][j]*f[j];
52         printf(i==1?"%.2lf":" %.2lf",ans);
53     }
54     printf("\n");
55 }
56
57 int main()
58 {
59     int t,i,j,k,p,n,m;
60     scanf("%d",&t);
61     while(t--)
62     {
63         scanf("%d",&n);
64         for(i=1;i<=n;i++) scanf("%lf",f+i);
65         Matrix A;A.n=n;
66         for(i=1;i<=n;i++)
67         {
68             scanf("%d",&k);
69             for(j=1;j<=n;j++) A.a[j][i]=0;
70             if(k==0)
71             {
72                 A.a[i][i]=1.0;continue;
73             }
74             double c=1.0/k;
75             for(j=1;j<=k;j++)
76             {
77                 scanf("%d",&p);A.a[p][i]=c;
78             }
79         }
80         scanf("%d",&m);
81         Matrix B=Matrix_pow(A,m);
82         Printf(B);
83     }
84     return 0;
85 }

zoj 2974 Just Pour the Water矩阵快速幂,布布扣,bubuko.com

时间: 2024-10-17 15:53:51

zoj 2974 Just Pour the Water矩阵快速幂的相关文章

【ZOJ 2974】Just Pour the Water(矩阵快速幂)

传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2974 题意 给出n个杯子与初始水量同时进行操作 将其中的水同时平均分入所指定的杯子 进行x次后 输出杯子剩余水量 刚拿到这个题,第一反应是递推找规律,但是因为每个杯子的初始水量是未知的,所以能找的只是每个杯子水量与其余杯子水量的关系. 但是看到了操作次数巨大,而且最多只有20个杯子,感觉可以用快速幂去做. 我们假设矩阵a[i][j]代表第i个杯子的水有a[i][j

ZOJ 2974 Just Pour the Water

矩阵快速幂. 构造一个矩阵,$a[i][j]$表示一次操作后,$j$会从$i$那里得到水的比例.注意$k=0$的时候,要将$a[i][j]$置为$1$. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vecto

ACM-ICPC 2018 焦作赛区网络预赛 L:Poor God Water(矩阵快速幂)

God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him that some sequence of eating will make them poisonous. Every hour, God Water will eat one kind of food among meat, fish and chocolate. If there are 3 c

zoj 3538 Arrange the Schedule(矩阵快速幂)

Arrange the Schedule Time Limit: 1 Second      Memory Limit: 65536 KB In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There is a group in c

ZOJ 3256 Tour in the Castle 矩阵快速幂加速

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3256 题意:给一个n*m的棋盘,求从左上到左下的经过所有格子的方案数 在左边加一列问题就变成了求回路 由于m很大,所以我们需要按列dp 构造出矩阵后,用矩阵快速幂加速 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include&l

ZOJ 2794 Just Pour the Water 【矩阵快速幂】

给你n个杯子,每次有特定的到水规则,倒m次请问最后每个被子里还有多少水 我们很容易发现每次变化的规则相同,那么可以set 一个矩阵存放 然后多次倒水就相当于矩阵相乘,在m 范围达到(1<= M <= 1,000,000,000) 的情况下使用矩阵快速幂再好不过 这到题目注意的一点是,得使用Double 变量,如果使用FLoat会导致Wrong Answer Source Code: //#pragma comment(linker, "/STACK:16777216") /

dutacm.club Water Problem(矩阵快速幂)

Water Problem Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:1228   Accepted:121 [Submit][Status][Discuss] Description 函数 f:Z+→Z .已知 f(1),f(2) 的值,且对于任意 x>1,有 f(x+1)=f(x)+f(x?1)+sin(πx2) . 求 f(n) 的

zoj 2853 Evolution(矩阵快速幂)

Evolution is a long, long process with extreme complexity and involves many species. Dr. C. P. Lottery is currently investigating a simplified model of evolution: consider that we haveN (2 <= N <= 200) species in the whole process of evolution, inde

ZOJ 3690 &amp; HDU 3658 (矩阵快速幂+公式递推)

ZOJ 3690 题意: 有n个人和m个数和一个k,现在每个人可以选择一个数,如果相邻的两个人选择相同的数,那么这个数要大于k 求选择方案数. 思路: 打表推了很久的公式都没推出来什么可行解,好不容易有了想法结果WA到天荒地老也无法AC.. 于是学习了下正规的做法,恍然大悟. 这道题应该用递推 + 矩阵快速幂. 我们设F(n) = 有n个人,第n个人选择的数大于k的方案数: G(n) = 有n个人,第n个人选择的数小于等于k的方案数: 那么递推关系式即是: F(1)=m?k,G(1)=k F(n