# 【ACM-ICPC 2018 徐州赛区网络预赛】E. End Fantasy VIX 血辣 （矩阵运算的推广）

Morgana is playing a game called End Fantasy VIX. In this game, characters have nn skills, every skill has its damage. And using skill has special condition. Briefly speaking, if this time you use skill "x", then next time you can use skill "y" (just like combo). There are mm conditions (xi, yiy_i), and you can't break the rules. (that means, if you don't have any condition that equals to (xx, yy), then you can't use "y" after use "x").

Now, Morgana wants to defeat the boss, he can use skills t times. In the first time he can use any skill, then he should obey the rules. Besides, he has a special armor called "Xue La", he can use this armor and add a debuff to the boss. The debuff will record damage and when it is over, the record damage will be caused again. (that means double damage) The debuff will continue TT times, and he can use this armor in any time, it won't be in conflict with skills.

Finally, Morgana wants to maximize the damage, but it is too difficult. So please help him deal with this problem.

(If Morgana can not use any skill at a time, he will finish the game and the final damage is his total damage at this time.)

### Input

First line contains 44 integers n,m,t,T (2≤n≤642 \le n \le 64, 1≤m≤n×(n−1)1 \le m \le n \times (n-1) , 1≤t≤1e9, 1≤T≤t).

In the next mm lines each line contains two integers represent condition (xi,yix_i, y_i) (xi,yi≤nx_i, y_i \le n) .

Then the next line contains nn integers represent the damage of the skills (every skill's damage is smaller than 1e81e8).

### Output

One line with one integer.

### 思路

  1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long LL;
4 const int maxn = 64;
5 int N, M, t, T, v[maxn];
6 struct Mat
7 {
8     LL A[maxn][maxn];
9     void Print() const
10     {
11         for(int i = 0;i < N;++i)
12             for(int j = 0;j < N;++j) printf("%lld%c", A[i][j], " \n"[j+1 == N]);
13         puts("");
14     }
15 };
16
17 bool tp;//因为懒得把运算符重载改成函数所以用了一个全局变量，一般认为这样写是不严谨的
18         //tp=1时表示路径长度可以小于t
19 Mat operator + (const Mat &a, const Mat &b)
20 {
21     Mat ans;
22     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
23         ans.A[i][j] = max(a.A[i][j], b.A[i][j]);
24     return ans;
25 }
26
27 Mat operator * (const Mat &a, const Mat &b)
28 {
29     Mat ans;
30     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
31     {
32         if(tp) ans.A[i][j] = max(a.A[i][j], b.A[i][j]);
33         else ans.A[i][j] = 0;
34         for(int k = 0;k < N;++k)
35         {
36             if(a.A[i][k] && b.A[k][j])
37                 ans.A[i][j] = max(ans.A[i][j], a.A[i][k] + b.A[k][j] - v[k]);
38         }
39     }
40     return ans;
41 }
42
43 Mat G, I;
44 void init()
45 {
46     scanf("%d%d%d%d", &N, &M, &t, &T);
47     int x, y;
48     while(M--)
49     {
50         scanf("%d%d", &x, &y);
51         --x, --y;
52         G.A[x][y] = 1;
53     }
54     for(int i = 0;i < N;++i) scanf("%d", &v[i]);
55     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
56     {
57         if(G.A[i][j] == 1) G.A[i][j] = v[i] + v[j];
58     }
59     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
60         I.A[i][j] = 0;
61     for(int i = 0;i < N;++i)
62         I.A[i][i] = v[i];
63 }
64
65 Mat powmod(Mat a, int n)
66 {
67     Mat ans = I;
68     while(n)
69     {
70         if(n & 1) ans = ans * a;
71         a = a * a;
72         n >>= 1;
73     }
74     return ans;
75 }
76
77 Mat powmod2(Mat a, Mat g, int n)
78 {
79     Mat ans = a, pw = I;
80     a = a * g + g * a;
81     while(n)
82     {
83         if(n & 1)
84         {
85             ans = ans + pw * a + a * pw;
86             pw = pw * g + g * pw;
87         }
88         n >>= 1;
89         a = a * g + g * a;
90         g = g * g;
91     }
92     return ans;
93 }
94
95 void work()
96 {
97     tp = false;//必须够T次
98     Mat a = powmod(G, T-1);
99     bool useXL = false;
100     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
101         if(a.A[i][j])
102         {
103             useXL = true;
104             a.A[i][j] <<= 1;
105         }
106     LL ans = 0;
107     tp = true;//可以不足t次
108     if(useXL)
109     {
110         a = powmod2(a, G, t - T);
111         for(int i = 0;i < N;++i) for(int j = 0;j < N;++j) ans = max(ans, a.A[i][j]);
112     }
113
114     a = powmod(G, t);
115     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j) ans = max(ans, a.A[i][j]);
116     printf("%lld\n", ans);
117 }
118
119 int main()
120 {
121     init();
122     work();
123     return 0;
124 }

  1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long LL;
4 const int maxn = 64;
5 int N, M, t, T, v[maxn];
6 struct Mat
7 {
8     LL A[maxn][maxn];
9     void Print() const
10     {
11         for(int i = 0;i < N;++i)
12             for(int j = 0;j < N;++j) printf("%lld%c", A[i][j], " \n"[j+1 == N]);
13         puts("");
14     }
15 };
16
17 Mat operator + (const Mat &a, const Mat &b)
18 {
19     Mat ans;
20     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
21         ans.A[i][j] = max(a.A[i][j], b.A[i][j]);
22     return ans;
23 }
24
25 Mat operator * (const Mat &a, const Mat &b)
26 {
27     Mat ans;
28     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
29     {
30         ans.A[i][j] = max(a.A[i][j], b.A[i][j]);
31         for(int k = 0;k < N;++k)
32         {
33             if(a.A[i][k] && b.A[k][j])
34                 ans.A[i][j] = max(ans.A[i][j], a.A[i][k] + b.A[k][j] - v[k]);
35         }
36     }
37     return ans;
38 }
39
40 Mat G, I;
41 void init()
42 {
43     scanf("%d%d%d%d", &N, &M, &t, &T);
44     int x, y;
45     while(M--)
46     {
47         scanf("%d%d", &x, &y);
48         --x, --y;
49         G.A[x][y] = 1;
50     }
51     for(int i = 0;i < N;++i) scanf("%d", &v[i]);
52     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
53     {
54         if(G.A[i][j] == 1) G.A[i][j] = v[i] + v[j];
55     }
56     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
57         I.A[i][j] = 0;
58     for(int i = 0;i < N;++i)
59         I.A[i][i] = v[i];
60 }
61
62 Mat powmod(Mat a, int n)
63 {
64     Mat ans = I;
65     while(n)
66     {
67         if(n & 1) ans = ans * a;
68         a = a * a;
69         n >>= 1;
70     }
71     return ans;
72 }
73
74 Mat powmod2(Mat a, Mat g, int n)
75 {
76     Mat ans = a, pw = I;
77     a = a * g + g * a;
78     while(n)
79     {
80         if(n & 1)
81         {
82             ans = ans + pw * a + a * pw;
83             pw = pw * g + g * pw;
84         }
85         n >>= 1;
86         a = a * g + g * a;
87         g = g * g;
88     }
89     return ans;
90 }
91
92 void work()
93 {
94     Mat a = powmod(G, T-1);
95     bool useXL = false;
96     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j)
97         if(a.A[i][j])
98         {
99             useXL = true;
100             a.A[i][j] <<= 1;
101         }
102     LL ans = 0;
103     if(useXL)
104     {
105         a = powmod2(a, G, t - T);
106         for(int i = 0;i < N;++i) for(int j = 0;j < N;++j) ans = max(ans, a.A[i][j]);
107     }
108
109     a = powmod(G, t);
110     for(int i = 0;i < N;++i) for(int j = 0;j < N;++j) ans = max(ans, a.A[i][j]);
111     printf("%lld\n", ans);
112 }
113
114 int main()
115 {
116     init();
117     work();
118     return 0;
119 }

posted @ 2018-09-10 00:06  Asm.Definer  阅读(661)  评论(0编辑  收藏  举报