• HNU 1447 最长上升路径


    题意:

    给出n( <= 3e5)个点,m(<= 3e5)条带权的有向边,求权值上升的最长路径的长度。

    题解:

    1.因为求的是最长上升的路径,考虑动态规划,定义状态dp[u] 表示以u结尾上升路径最长长度。

    2.为了排除后效性那么首先对所有边从小到大排序,dp[v] = max (dp[v], dp[u] + 1)

    3.转移的条件dp[v] < dp[u] + 1因为这样保证了路径的递增,所以不能立即更新,需要把要更新的边都存下来一起更新~

    代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int N = 4e5 + 7;
    int dp[N], n, m;
    struct edge{
    	int u, v, w;
    	bool operator < (const edge &X) const{return w < X.w;}
    } e[N];
    struct node{int v, len;} K[N];
    
    int main(){
    	scanf("%d%d", &n , &m);
    	for (int i = 1; i <= m; ++i) {
    		int u, v, w;
    		scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
    	}
    	sort(e+1, e+m+1);
    	int pre = 0;
    	for (int i = 1; i <= m; ++i) {
    		if (e[i].w == e[i + 1].w && i != m) continue;
    		int cnt = 0;
    		for (int j = pre + 1; j <= i; ++j)
    			if (dp[e[j].u] + 1 > dp[e[j].v])
    				K[++cnt] = (node){e[j].v, dp[e[j].u] + 1};
    				
    		for(int j = 1;j <= cnt;++j)
    			dp[K[j].v] = max(dp[K[j].v],K[j].len);
    		pre = i;
    	}
    	int ans = 0;
    	for (int i = 1; i <= n; ++i) ans = max (ans, dp[i]);
    	printf("%d
    ", ans);
    	return 0;
    }
    

      

    总结:

    1.要好好处理后效性

  • 相关阅读:
    OpenSSH服务——密钥登录
    进程管理
    磁盘管理
    文件系统
    shell命令手册
    第一次常用命令手册
    远程连接mobaxterm安装使用
    Linux 系统CentOS 7 64 位安装
    PythonI/O进阶学习笔记_11.python的多进程
    PythonI/O进阶学习笔记_10.python的多线程
  • 原文地址:https://www.cnblogs.com/xgtao/p/5967773.html
Copyright © 2020-2023  润新知