[CF960F]Pathwalks
生活随笔
收集整理的這篇文章主要介紹了
[CF960F]Pathwalks
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意:給你一張$n$個點$m$條邊的帶權有向圖,可能有重邊和自環。邊會按照順序給出。讓你求出一條最長的路徑,使得路徑上的邊滿足邊權和出現的時間嚴格遞增。路徑可以重復經過同一個點。
想辦法把它轉化成序列上的最長上升序列
我們如果按順序加邊,那么邊做邊求是符合邊的出現時間遞增的要求的
所以當給你一條邊$a$->$b$邊權為$c$時,我們要在合理的復雜度內查到到$a$點邊權小于$c$的最長上升序列
然后用它去更新答案和到$b$邊權小于等于$c$的最大值
這顯然是個線段樹,然后我們再搞個動態開點,完事
代碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define M 500010 5 #define ls ch[node][0] 6 #define rs ch[node][1] 7 using namespace std; 8 int read() 9 { 10 char ch=getchar();int x=0; 11 while(ch>'9'||ch<'0') ch=getchar(); 12 while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); 13 return x; 14 } 15 int n,m,cnt,ans; 16 int root[M],val[M<<2],ch[M<<2][2]; 17 void insert(int &node,int l,int r,int k,int x) 18 { 19 if(!node) node=++cnt; 20 val[node]=max(val[node],x); 21 if(l==r) return; 22 int mid=(l+r)/2; 23 if(k<=mid) insert(ls,l,mid,k,x); 24 else insert(rs,mid+1,r,k,x); 25 } 26 int query(int node,int l,int r,int l1,int r1) 27 { 28 if(!node) return 0; 29 if(l1>r||r1<l) return 0; 30 if(l1<=l&&r1>=r) return val[node]; 31 int mid=(l+r)/2; 32 return max(query(ls,l,mid,l1,r1),query(rs,mid+1,r,l1,r1)); 33 } 34 int main() 35 { 36 n=read();m=read(); 37 for(int i=1;i<=m;i++) 38 { 39 int a=read(),b=read(),z=read()+1; 40 int x=query(root[a],1,100000,1,z-1)+1; 41 ans=max(ans,x); 42 insert(root[b],1,100001,z,x); 43 } 44 printf("%d",ans); 45 return 0; 46 }?
轉載于:https://www.cnblogs.com/Slrslr/p/9694766.html
總結
以上是生活随笔為你收集整理的[CF960F]Pathwalks的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移动端H5混合开发设置复盘与总结
- 下一篇: java自学小段 产生随机数