看CF吧智障luogu又咕了
先排序然后从小到大加边,这样就能保证是递增的了,然后边加边
d
p
dp
dp,设
f
[
i
]
f[i]
f[i]表示到
i
i
i的最大递增边数,注意是严格递增所以边权相同要放一块处理
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 300005
using namespace std;
int n,m,cnt,f[N],ans,g[N];
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
struct EDGE{
int fr,to,w;
bool operator <(const EDGE &x) const{
return w<x.w;
}
}edge[N];
inline void add(int x,int y,int z){
edge[++cnt].to=y; edge[cnt].fr=x; edge[cnt].w=z;
}
int main(){
n=rd(); m=rd();
for(int i=1;i<=m;i++){
int x=rd(),y=rd(),z=rd();
add(x,y,z);
}
sort(edge+1,edge+m+1);
for(int i=1;i<=m;){
int j;
for(j=i;j<=m;j++){
if(edge[j].w!=edge[i].w) break;
int x=edge[j].fr,y=edge[j].to;
g[y]=max(max(f[y],g[y]),f[x]+1);
}
for(int j=i;j<=m;j++){
if(edge[j].w!=edge[i].w) break;
int x=edge[j].fr,y=edge[j].to;
f[y]=max(f[y],g[y]);
}
i=j;
}
for(int i=1;i<=n;i++)
ans=max(ans,f[i]);
printf("%d\n",ans);
return 0;
}