题目链接:https://vjudge.net/problem/CodeForces-960F

You are given a directed graph with n nodes and m edges, with all edges having a certain weight.

There might be multiple edges and self loops, and the graph can also be disconnected.

You need to choose a path (possibly passing through same vertices multiple times) in the graph such that the weights of the edges are in strictly increasing order, and these edges come in the order of input. Among all such paths, you need to find the the path that has the maximum possible number of edges, and report this value.

Please note that the edges picked don't have to be consecutive in the input.

Input

The first line contains two integers n and m (1 ≤ n ≤ 100000,1 ≤ m ≤ 100000) — the number of vertices and edges in the graph, respectively.

m lines follows.

The i-th of these lines contains three space separated integers aibi and wi (1 ≤ ai, bi ≤ n, 0 ≤ wi ≤ 100000), denoting an edge from vertex ai to vertex bi having weight wi

Output

Print one integer in a single line — the maximum number of edges in the path.

Examples

Input
3 3
3 1 3
1 2 1
2 3 2
Output
2
Input
5 5
1 3 2
3 2 3
3 4 5
5 4 0
4 5 8
Output
3

Note

The answer for the first sample input is 2: . Note that you cannot traverse  because edge  appears earlier in the input than the other two edges and hence cannot be picked/traversed after either of the other two edges.

In the second sample, it's optimal to pick 1-st, 3-rd and 5-th edges to get the optimal answer: .

题意:

给出n个结点和m条带权有向边,其中可以有环、自环。一条合法的路径为:路径上边的给出次序(输入次序)和权值都满足严格递增,问最长的合法路径?

题解:

1.由于路径需满足“边的给出次序递增”,即只能从先给出的边走到后给出的边,且又需满足“权值严格单调递增”,所以就是一道类LIS的题目。

2.为每个点开一棵线段树,由于边只有1e5条,故使用动态开点就不会超内存。线段树以边权作为区间,每个结点需记录三个信息:左、右孩子,以及当前值能形成的最长路径。

3.剩下的操作与LIS或二维偏序差不多了。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 2e6+; struct node
{
int lson, rson, cnt;
void init()
{
lson = rson = -;
cnt = ;
}
}q[MAXN];
int root[MAXN], tot; void add(int &rt, int l, int r, int val, int cnt)
{
if(rt==-) //动态开点
{
rt = tot++;
q[rt].init();
}
q[rt].cnt = max(q[rt].cnt,cnt);
if(l==r) return; int mid = (l+r)>>;
if(val<=mid) add(q[rt].lson, l, mid, val, cnt);
else add(q[rt].rson, mid+, r, val, cnt);
} int query(int rt, int l ,int r, int x,int y)
{
if(rt==-) return ; //如果此处没有开点,即表明此处没有插入值,直接返回0
if(x<=l&&r<=y) return q[rt].cnt; int mid = (l+r)>>;
int ret = ;
if(x<=mid) ret = max(ret, query(q[rt].lson, l, mid, x, y));
if(y>=mid+) ret = max(ret, query(q[rt].rson, mid+, r, x, y));
return ret;
} int main()
{
int n, m;
while(scanf("%d%d",&n,&m)!=EOF)
{
tot = ;
memset(root, -, sizeof(root));
int ans = ;
for(int i = ; i<=m; i++)
{
int u, v, w;
scanf("%d%d%d",&u,&v,&w);
int max_cnt = query(root[u],-, , -,w-); //最小值为-1,防止w-1溢出范围
ans = max(ans, max_cnt+);
add(root[v], -, , w, max_cnt+);
}
printf("%d\n", ans);
}
}

最新文章

  1. iOS-----正则表达式的基础语法
  2. Ubuntu 安装和使用 Zip – rar – 7zip
  3. C++字符串与转移字符
  4. 2015GitWebRTC编译实录10
  5. Win8.1 MSDN各版本下载(64位/32位,简体中文,繁体中文,英文),X86&amp;X64,EN,CHS,CHT
  6. Android消息推送之GCM方式(一)
  7. php学习笔记——文件(1)
  8. html5--基础笔记
  9. C++枚举类型详解
  10. 微信公众号问题:{&quot;errcode&quot;:40125,&quot;errmsg&quot;:&quot;invalid appsecret, view more at http:\/\/t.cn\/LOEdzVq, hints: [ req_id: kL8J90219sg58 ]&quot;}
  11. CentOS7基本配置一
  12. LOJ6089 小Y的背包计数问题(根号优化背包)
  13. P2233 [HNOI2002]公交车路线
  14. 【推荐】asp.net 页面的生命周期
  15. 华为手机自带浏览器不支持 ES6 语法
  16. 安装Ubuntu后要做的事
  17. 【webservice】使用命令wsimport构建WebService客户端
  18. Spring boot注解(annotation)含义详解
  19. Shell输入输出重定向
  20. 什么是Base64算法?什么情况下用Base64算法?

热门文章

  1. 【音乐App】—— Vue-music 项目学习笔记:推荐页面开发
  2. Solidworks如何开启自动求解
  3. jsp页面中,动态调用系统时间的实现
  4. iOS 振动反馈
  5. VMware-Fusion-7.0.0-2103067 Pro SN:序列号+ 百度云下载地址
  6. HBase 系统架构及数据结构
  7. 四、Silverlight中使用MVVM(四)——演练
  8. 在一个JS文件中引用另一个JS文件
  9. 允许局域网内其他主机访问本地MySql数据库
  10. MariaDB mysql 比较区别 选择