zoukankan      html  css  js  c++  java
  • 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.要好好处理后效性

  • 相关阅读:
    [资料]PHP中的__autoload
    [转]php 5.3新增的闭包语法介绍function() use() {}
    [资料]PHP中的ReflectionClass
    [资料]PHP中的命名空间
    Mysql Event
    PHP转换成对像
    [转]Win7自带便签怎么恢复内容
    [转]Windows7便笺妙用
    [转]ASP.NET下MVC1.0>2.0>3.0>4.0
    PHP类动态属性问题
  • 原文地址:https://www.cnblogs.com/xgtao/p/5967773.html
Copyright © 2011-2022 走看看