Ralph is going to collect mushrooms in the Mushroom Forest.

There are m directed paths connecting n trees in the Mushroom Forest. On each path grow some mushrooms. When Ralph passes a path, he collects all the mushrooms on the path. The Mushroom Forest has a magical fertile ground where mushrooms grow at a fantastic speed. New mushrooms regrow as soon as Ralph finishes mushroom collection on a path. More specifically, after Ralph passes a path the i-th time, there regrow i mushrooms less than there was before this pass. That is, if there is initially x mushrooms on a path, then Ralph will collect x mushrooms for the first time, x - 1 mushrooms the second time, x - 1 - 2 mushrooms the third time, and so on. However, the number of mushrooms can never be less than 0.

For example, let there be 9 mushrooms on a path initially. The number of mushrooms that can be collected from the path is 9, 8, 6 and 3when Ralph passes by from first to fourth time. From the fifth time and later Ralph can't collect any mushrooms from the path (but still can pass it).

Ralph decided to start from the tree s. How many mushrooms can he collect using only described paths?

Input

The first line contains two integers n and m (1 ≤ n ≤ 106, 0 ≤ m ≤ 106), representing the number of trees and the number of directed paths in the Mushroom Forest, respectively.

Each of the following m lines contains three integers xy and w (1 ≤ x, y ≤ n, 0 ≤ w ≤ 108), denoting a path that leads from tree x to tree y with w mushrooms initially. There can be paths that lead from a tree to itself, and multiple paths between the same pair of trees.

The last line contains a single integer s (1 ≤ s ≤ n) — the starting position of Ralph.

Output

Print an integer denoting the maximum number of the mushrooms Ralph can collect during his route.

Examples
input
2 2
1 2 4
2 1 4
1
output
16
input
3 3
1 2 4
2 3 3
1 3 8
1
output
8

先处理环,用Tarjan缩点然后用一个数组记录这个环的贡献值,然后对缩点后的有向无环图做一个最长路。
环的贡献是每条边的贡献之和,可以预处理每次二分得到。
#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define ll long long
#define lowbit(x) (x&(-x))
#define eps 0.00000001
#define pn printf("\n")
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std; const int maxn = 1e6+7; struct edge{
int to, next, w;
}e[maxn];
int tot, head[maxn];
int dfn[maxn], low[maxn], Stack[maxn];
bool inStack[maxn];
int top, Index, scc;
int Belong[maxn]; struct node{
int v;
ll w;
node(int _v=0,ll _w=0):v(_v),w(_w){}
};
vector <node> E[maxn<<1];
ll val[maxn << 1]; ll sub[maxn], pre[maxn];
int arr_cnt; ll binary_search(ll x)
{
ll l = 0, r = arr_cnt, mid;
while(l < r)
{
mid = (l + r) >> 1;
if(sub[mid] > x) r = mid;
else l = mid + 1;
}
return l - 1;
} void init()
{
tot = 0;
memset(head,-1,sizeof head);
for(arr_cnt=1; sub[arr_cnt-1] <= 1e8; arr_cnt++)
pre[arr_cnt] = pre[arr_cnt-1] + (sub[arr_cnt] = sub[arr_cnt-1] + arr_cnt);
} void addedge(int u,int v,int w)
{
e[tot].to = v;
e[tot].w = w;
e[tot].next = head[u];
head[u] = tot++;
} void Tarjan(int u)
{
int v;
dfn[u] = low[u] = ++Index;
Stack[top++] = u;
inStack[u] = 1; for(int i=head[u];i!=-1;i=e[i].next)
{
v = e[i].to;
if(!dfn[v])
{
Tarjan(v);
if(low[v] < low[u]) low[u] = low[v];
}else if(inStack[v] && dfn[v] < low[u])
low[u] = dfn[v];
}
if(low[u] == dfn[u])
{
scc++;
do
{
v = Stack[--top];
inStack[v] = 0;
Belong[v] = scc;
} while(u != v);
}
} void solve(int N)
{
Index = scc = top = 0;
for(int i=1;i<=N;i++)
if(!dfn[i])
Tarjan(i); //Belong[i] -> 新图中的标号
for(int i=1;i<=N;i++)
for(int j=head[i];j!=-1;j=e[j].next)
{
int u = Belong[i];
int v = Belong[e[j].to];
ll w = e[j].w;
if(u == v)
{
ll pos = binary_search(e[j].w);
if(pos >= 0)
{
w = (pos + 1) * w - pre[pos];
val[u] += w;
}
}
else
{
E[u].push_back(node(v,w));
}
}
} ll ans[maxn << 1]; ll dfs(int u)
{
if(ans[u]) return ans[u];
ll ret = 0;
for(int i=0;i<E[u].size();i++)
ret = max(ret, E[u][i].w + dfs(E[u][i].v));
return ans[u] = ret + val[u];
} int main()
{
init();
int n,m;
scanf("%d%d",&n,&m);
int u_, v_, w_, s_;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u_,&v_,&w_);
addedge(u_,v_,w_);
}
scanf("%d",&s_);
solve(n); cout << dfs(Belong[s_]) << endl;
}

  

Codeforces Round #447 (Div. 2)E. Ralph and Mushrooms的更多相关文章

  1. Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field【数论/组合数学】

    B. Ralph And His Magic Field time limit per test 1 second memory limit per test 256 megabytes input ...

  2. Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field 数学

    题目链接 题意:给你三个数n,m,k;让你构造出一个nm的矩阵,矩阵元素只有两个值(1,-1),且满足每行每列的乘积为k,问你多少个矩阵. 解法:首先,如果n,m奇偶不同,且k=-1时,必然无解: 设 ...

  3. Codeforces Round #447 (Div. 2) 题解 【ABCDE】

    BC都被hack的人生,痛苦. 下面是题解的表演时间: A. QAQ "QAQ" is a word to denote an expression of crying. Imag ...

  4. Codeforces Round #447 (Div. 2)

    我感觉这场CF还是比较毒的,虽然我上分了... Problem A  QAQ 题目大意:给你一个由小写字母构成的字符串,问你里面有多少个QAQ. 思路:找字符串中的A然后找两边的Q即可,可以枚举找Q, ...

  5. 【Codeforces Round #447 (Div. 2) B】Ralph And His Magic Field

    | [链接] 我是链接,点我呀:) [题意] 给你一个n*m矩阵,让你在里面填数字. 使得每一行的数字的乘积都为k; 且每一列的数字的乘积都为k; k只能为1或-1 [题解] 显然每个位置只能填1或- ...

  6. Codeforces Round #447 (Div. 2) 题解

    A.很水的题目,3个for循环就可以了 #include <iostream> #include <cstdio> #include <cstring> using ...

  7. Codeforces Round #447 (Div. 2) C 构造

    现在有一个长度为n的数列 n不超过4000 求出它的gcd生成set 生成方式是对<i,j> insert进去(a[i] ^ a[i+1] ... ^a[j]) i<=j 然而现在给 ...

  8. Codeforces Round #447 (Div. 2) C. Marco and GCD Sequence【构造/GCD】

    C. Marco and GCD Sequence time limit per test 1 second memory limit per test 256 megabytes input sta ...

  9. Codeforces Round #447 (Div. 2) A. QAQ【三重暴力枚举】

    A. QAQ time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

随机推荐

  1. ThreadPoolExecutor源码分析(一)

    一.前言 闲来无事,博主有重新翻看了一下jdk1.8版的ThreadPoolExecutor源码,看后写此笔记,画个圈圈,做个记录,这段源码,我看过,到处一游,嘻嘻~~ 二.ThreadPoolExe ...

  2. 关于template 的23个问题

    发现新大陆.曾经慢慢才知道的东西.原来有个集中营: 看看updated, 处理方式是这么的好 35.1 " id="link-to-faq-35_1" style=&qu ...

  3. 【VC编程技巧】窗口☞3.6以渐变效果加载对话框

    平时我们常常能够看到非常多应用程序启动过程非常酷.什么百叶窗.渐变,各种效果,今天我们看一下怎样在程序中添加这样的效果. 一.演示样例展示: watermark/2/text/aHR0cDovL2Js ...

  4. hdu4861 Couple doubi---2014 Multi-University Training Contest 1

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4861 Couple doubi Time Limit: 2000/1000 MS (Java/Othe ...

  5. ssh无法连接到远端Ubuntu的解决方法

    近日,饱受无法远程登录到新安装在VMWare上的Ubuntu虚拟机,现在发现问题所在.故记录此问题的解决方式,以备后用. 一.远程登录虚拟机的准备: Ubuntu虚拟机的联网方式应该选择Bridged ...

  6. tslib-触摸屏校准

    5.1移植tslib 5.1.1在https://github.com/kergoth/tslib下载最新的tslib 5.1.2为虚拟机里的Linux系统安装工具  sudo apt-get ins ...

  7. 逻辑运算0==x和x==0具体解释

    看很多大牛写的程序经常看到if(0==x){运行体},而自己写的程序常用if(x==0){运行体}.刚開始的时候我还非常自信的觉得这样的表达方式是等价的,大牛们仅仅是为了显摆下与众不同的格调.当读到C ...

  8. POJ2576 Tug of War 二维背包

    题目大意 一群人拔河,给出每个人的重量,要求两队人数之差不超过1人,且每队总重量之差最小. 思路 选出严格总人数一半(或+1)的人为一队,在该队重量不超过所有人总重量一半的情况下,使其重量最大. 人数 ...

  9. NUnit Console Command Line

    https://github.com/nunit/docs/wiki/Console-Command-Line The console interface runner is invoked by a ...

  10. iOS10 推送通知 UserNotifications

    简介 新框架 获取权限 获取用户设置 注册APNS,获取deviceToken 本地推送流程 远程推送流程 通知策略(Category+Action) 附件通知 代理回调 简介 iOS10新增了Use ...