Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <stack>
- #include <cmath>
- using namespace std;
- struct Edge {
- int from, to;
- long long w;
- Edge() {}
- Edge(int from, int to, long long w) : from(from), to(to), w(w) {}
- };
- int n, m;
- int *colors;
- bool *used;
- vector<vector<Edge>> g;
- vector<vector<Edge>> reversedG;
- vector<Edge> edges;
- stack<int> orderStack;
- long long *sum;
- const int PRECOUNT_MAX = 15000;
- void dfs(int v) {
- used[v] = true;
- for (Edge e : g[v]) {
- if (!used[e.to])
- dfs(e.to);
- }
- orderStack.push(v);
- }
- void dfs2(int v, int curColor) {
- colors[v] = curColor;
- for (Edge e : reversedG[v]) {
- if (colors[e.to] == -1)
- dfs2(e.to, curColor);
- }
- }
- vector<vector<Edge>> newG;
- void dfs3(int v) {
- used[v] = true;
- for (Edge e : g[v]) {
- if (colors[v] != colors[e.to]) {
- Edge e2(colors[v], colors[e.to], e.w);
- newG[colors[v]].push_back(e2);
- }
- if (!used[e.to])
- dfs3(e.to);
- }
- }
- long long *compWeight;
- long long *ans;
- long long getSum(long long w) {
- if (w == 0)
- return 0;
- int ans = ((int) sqrt(2 * w)) - 1;
- if ((ans + 1) * (ans + 2) / 2 <= w)
- ans++;
- if ((ans + 1) * (ans + 2) / 2 <= w)
- ans++;
- return w * (ans + 1) - sum[ans];
- }
- bool *usedComps;
- long long dfs4(int v) {
- if (ans[v] == -1LL) {
- if (newG[v].empty()) {
- ans[v] = compWeight[v];
- return ans[v];
- } else {
- long long max2 = 0;
- for (Edge e : newG[v]) {
- max2 = max(max2, e.w + dfs4(e.to));
- }
- ans[v] = max2 + compWeight[v];
- return ans[v];
- }
- } else
- return ans[v];
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin >> n >> m;
- colors = new int[n];
- used = new bool[n];
- sum = new long long[PRECOUNT_MAX];
- g.reserve(n);
- reversedG.reserve(n);
- edges.reserve(m);
- for (int i = 0; i < n; i++) {
- vector<Edge> g2;
- vector<Edge> reversedG2;
- g.push_back(g2);
- reversedG.push_back(reversedG2);
- }
- for (int i = 0; i < m; i++) {
- Edge e1;
- Edge e2;
- cin >> e1.from;
- cin >> e1.to;
- cin >> e1.w;
- e1.from--;
- e1.to--;
- e2.to = e1.from;
- e2.from = e1.to;
- e2.w = e1.w;
- g[e1.from].push_back(e1);
- reversedG[e2.from].push_back(e2);
- edges.push_back(e1);
- }
- sum[0] = 0;
- sum[1] = 1;
- long long cur = 1;
- for (int i = 2; i < PRECOUNT_MAX; i++) {
- cur = cur + (long long) i;
- sum[i] = sum[i - 1] + cur;
- }
- int start;
- cin >> start;
- start--;
- for (int i = 0; i < n; i++) {
- used[i] = false;
- colors[i] = -1;
- }
- for (int i = 0; i < n; i++)
- if (!used[i])
- dfs(i);
- int color = 0;
- while (!orderStack.empty()) {
- int curV = orderStack.top();
- orderStack.pop();
- if (colors[curV] == -1)
- dfs2(curV, color++);
- }
- newG.reserve(color);
- for (int i = 0; i < color; i++) {
- vector<Edge> newG2;
- newG.push_back(newG2);
- }
- for (int i = 0; i < n; i++) {
- used[i] = false;
- }
- for (int i = 0; i < n; i++) {
- if (!used[i])
- dfs3(i);
- }
- compWeight = new long long[color];
- ans = new long long[color];
- for (int i = 0; i < color; i++) {
- compWeight[i] = 0LL;
- ans[i] = -1LL;
- }
- for (Edge e : edges) {
- if (colors[e.from] == colors[e.to]) {
- compWeight[colors[e.from]] += getSum(e.w);
- }
- }
- usedComps = new bool[color];
- for (int i = 0; i < color; i++) {
- usedComps[i] = false;
- }
- cout << dfs4(colors[start]);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement