Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef _DEBUG
- #define _GLIBCXX_DEBUG
- #endif
- #define _CRT_SECURE_NO_WARNINGS
- #include <ext/pb_ds/assoc_container.hpp>
- #include <bits/stdc++.h>
- using namespace __gnu_pbds;
- using namespace std;
- typedef long long ll;
- typedef vector<ll> vll;
- typedef pair<int, int> pii;
- typedef vector<int> vi;
- typedef long double ld;
- typedef tree<pair<ll, int>, null_type, less<pair<ll, int>>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
- #define mk make_pair
- #define inb push_back
- #define enb emplace_back
- #define X first
- #define Y second
- #define all(v) v.begin(), v.end()
- #define sqr(x) (x) * (x)
- #define TIME 1.0 * clock() / CLOCKS_PER_SEC
- #define y1 AYDARBOG
- //continue break pop_back return
- int solve();
- int main()
- {
- //ios_base::sync_with_stdio(0);
- //cin.tie(0);
- #define TASK "treedp"
- #ifndef _DEBUG
- //freopen(TASK".in", "r", stdin), freopen(TASK".out", "w", stdout);
- #endif
- solve();
- #ifdef _DEBUG
- fprintf(stderr, "\nTIME: %.3f\n", TIME);
- #endif
- }
- const int INF = 2e9 + 7;
- const ll LINF = 1e18;
- const int BUFSZ = (int)1e6 + 7;
- char buf[BUFSZ];
- string get_str()
- {
- scanf(" %s", buf);
- return string(buf);
- }
- struct edge
- {
- int a, b, c;
- edge() {};
- edge(int a, int b, int c) : a(a), b(b), c(c) {};
- };
- int solve()
- {
- int n, m, t;
- scanf("%d %d %d", &n, &m, &t);
- vector<vector<pair<int, char>>> g(n);
- vector<pair<int, char>> p(n);
- p[0] = mk(-1, '0');
- for (int i = 1; i < n; ++i)
- {
- int x;
- char c;
- scanf("%d %c", &x, &c);
- --x;
- g[x].inb(mk(i, c));
- }
- map<string, ll> cst;
- map<string, int> ids;
- for (int i = 0; i < m; ++i)
- {
- ll w;
- string s;
- scanf("%lld", &w);
- s = get_str();
- if (s.size() < n)
- {
- reverse(all(s));
- if (cst.find(s) == cst.end() || cst[s] > w)
- cst[s] = w, ids[s] = i + 1;
- }
- }
- vector<vll> dp(n);
- vector<vector<vector<edge>>> rec(n);
- vi cur;
- string cs;
- function<void(int)> calc = [&](int u)
- {
- cur.inb(u);
- int sz = g[u].size();
- dp[u].assign(cur.size(), LINF);
- rec[u].resize(cur.size());
- for (int i = 0; i < sz; ++i)
- {
- int to = g[u][i].X;
- cs.inb(g[u][i].Y);
- calc(to);
- cs.pop_back();
- }
- //printf("VERT: %d\n", u + 1);
- if (!g[u].empty())
- {
- vector<vll> dp1(sz, vll(cur.size(), LINF));
- vector<vector<vector<edge>>> rec1(sz, vector<vector<edge>>(cur.size()));
- dp1[0] = dp[g[u][0].X];
- rec1[0] = rec[g[u][0].X];
- for (int i = 1; i < sz; ++i)
- {
- int to = g[u][i].X;
- for (int h = 0; h < cur.size(); ++h)
- {
- for (int h1 = cur.size() - 1; h1 >= 0; --h1)
- {
- if (dp[to][h1] == LINF)
- break;
- if (dp1[i][min(h, h1)] > dp1[i - 1][h] + dp[to][h1])
- {
- dp1[i][min(h, h1)] = dp1[i - 1][h] + dp[to][h1];
- rec1[i][min(h, h1)] = rec1[i - 1][h];
- for (auto x : rec[to][h1])
- rec1[i][min(h, h1)].inb(x);
- }
- }
- }
- /*dp1[i ^ 1].assign(dp[i].size(), LINF);
- rec1[i ^ 1].clear();
- rec1[i ^ 1].resize(dp[i].size());*/
- }
- dp[u] = dp1[sz - 1];
- rec[u] = rec1[sz - 1];
- }
- else
- {
- dp[u][cur.size() - 1] = 0;
- }
- string str = cs;
- reverse(all(str));
- //cout << str << "\n";
- for (int i = 0; i < cs.size(); ++i)
- {
- ll w = LINF;
- if (cst.find(str) != cst.end())
- w = cst[str];
- if (w != LINF)
- {
- int id = ids[str], len = str.size();
- for (int j = i; j < cur.size(); ++j)
- {
- if (dp[u][i] > dp[u][j] + w)
- {
- dp[u][i] = dp[u][j] + w;
- rec[u][i] = rec[u][j];
- rec[u][i].inb(edge(cur[cur.size() - len - 1] + 1, u + 1, id));
- }
- }
- }
- str.pop_back();
- }
- cur.pop_back();
- for (int i = 1; i < (int)dp[u].size(); ++i)
- {
- if (dp[u][i - 1] < dp[u][i])
- {
- dp[u][i] = dp[u][i - 1];
- rec[u][i] = rec[u][i - 1];
- }
- }
- /*for (int i = 0; i < (int)dp[u].size(); ++i)
- printf("%lld ", dp[u][i]);
- puts("");//*/
- };
- calc(0);
- printf("%lld\n", (dp[0][0] != LINF) ? dp[0][0] : -1);
- if (dp[0][0] != LINF && t == 1)
- {
- printf("%d\n", (int)rec[0][0].size());
- for (auto x : rec[0][0])
- printf("%d %d %d\n", x.a, x.b, x.c);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement