Codeforces960F. Pathwalks
作者:@lrj998244353
本文为作者原创,转载请注明出处:https://www.cnblogs.com/lrj998244353/p/8776100.html
目录
description
Examples
input
output
input
output
题解
代码
description
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.
题目大意:给你一张n个点m条边的带权有向图,可能有重边和自环。边会按照顺序给出。让你求出一条最长的路径,使得路径上的边满足边权和出现的时间严格递增。路径可以重复经过同一个点。
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
题解
我们按照边出现的顺序依次向图中加边,这样就保证了出现时间是递增的,只需要考虑权值就行了。
问题便转化为求出图上的最长上升子序列。
类比最长上升子序列的线段树做法,记\(f[i]\)表示以节点\(i\)为终点的最长上升路径长度,然后对图中每个点都维护一棵线段树,以边权作为区间,以\(f\)为值。每插入一条边在起点的线段数中统计答案,之后再把算出来的答案插入到终点对应的线段树中。
代码
#include<bits/stdc++.h>
#define MAXN 100010
#define lc t[rt].l
#define rc t[rt].r
namespace IO{
char buf[1<<15],*fs,*ft;
inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
inline int qr(){
int x=0,rev=0,ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=gc();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}
return rev?-x:x;}
}using namespace IO;
using namespace std;
struct Tree{int l,r,v;}t[MAXN<<5];
int tot,root[MAXN],N,M,ans,f[MAXN];
inline void Up(int rt){t[rt].v=max(t[lc].v,t[rc].v);}
void Insert(int p,int l,int r,int &rt,int v){
if(!rt)rt=++tot;
if(l==r){t[rt].v=v;return;}
int mid=l+r>>1;
if(p<=mid)Insert(p,l,mid,lc,v);
else Insert(p,mid+1,r,rc,v);
Up(rt);
}
int Query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r)return t[rt].v;
int mid=l+r>>1,ret=0;
if(L<=mid&&lc)ret=Query(L,R,l,mid,lc);
if(R>mid&&rc)ret=max(ret,Query(L,R,mid+1,r,rc));
return ret;
}
int x,y,z;
int main(){
#ifndef ONLINE_JUDGE
freopen("cf960F.in","r",stdin);
freopen("cf960F.out","w",stdout);
#endif
N=qr();M=qr();
for(int i=1;i<=M;i++){
x=qr();y=qr();z=qr()+1;
f[y]=Query(1,z-1,1,100001,root[x])+1;
ans=max(ans,f[y]);
Insert(z,1,100001,root[y],f[y]);
}
printf("%d",ans);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步