1. 程式人生 > >DAG上DP--CF459E

DAG上DP--CF459E

看CF吧智障luogu又咕了 先排序然後從小到大加邊,這樣就能保證是遞增的了,然後邊加邊dpdp,設f[i]f[i]表示到ii的最大遞增邊數,注意是嚴格遞增所以邊權相同要放一塊處理

#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; }