• Codeforces960F. Pathwalks


    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; 
    }
    
  • 相关阅读:
    Android 打开相册拍照选择多张图片显示
    Mac 打开、编辑 .bash_profile 文件
    Ionic app IOS 在Xcode 模拟运行 真机调试
    android studio 把 ionic 打包时修改应用名称、修改应用图标、修改启动画面,升级打包
    Android studio 运行打包 Ionic 项目
    ionic4 路由跳转、ionic4 路由跳转传值 NavController 返回上一页 、NavController 回到根
    Ionic4.x ion-refresher 下拉更新
    Ionic4.x ion-infinite-scroll 上拉分页加载更多
    Ionic4.x ion-infinite-scroll 上拉分页加载更多
    Ionic4.x Modal模态对话框以及 Modal 传值
  • 原文地址:https://www.cnblogs.com/lrj998244353/p/8776100.html
Copyright © 2020-2023  润新知