zoukankan      html  css  js  c++  java
  • 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; 
    }
    
  • 相关阅读:
    [Linux] Ubuntu Server18 python3.7 虚拟环境
    [Linux] 树莓派编译python3.7.4
    [Linux] TMUX Python版本设置
    Linux 批量杀进程的命令
    arm树莓派Raspbian 下安装selenium+chrome
    树莓派Raspbian系统密码
    mac 终端查看端口命令
    selenium firefox 内存 速度优化
    [Linux] tmux 终端复用命令行工具
    通过 ssh 登录到手机 Termux
  • 原文地址:https://www.cnblogs.com/lrj998244353/p/8776100.html
Copyright © 2011-2022 走看看