51nod 1274 最长递增路径(dp)

题目链接
定义dp[i]:走到顶点i的最长路径。
为了动态规划的无后效性,得先把边按权值排序。为了不让顶点之间的dp值重复计算,得把上一次的dp值保存下来。由于需要严格递增,所以权值相同的边用到的dp值是一样的,所以可以一次把所有权值相同的边一起加入图里,然后更新答案。
d p [ u ] = m a x ( d p [ u ] , f [ v ] + 1 ) dp[u] = max(dp[u], f[v] + 1) dp[u]=max(dp[u],f[v]+1)
d p [ v ] = m a x ( d p [ v ] , f [ u ] + 1 ) dp[v] = max(dp[v], f[u] + 1) dp[v]=max(dp[v],f[u]+1)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e4 + 10, inf = 0x3f3f3f3f, mod = 1e9 + 7;
struct e{
    int u, v, c;
    bool operator < (e b) {return c < b.c;}
}a[maxn];

int f[maxn], dp[maxn];
int main()
{
    //ios::sync_with_stdio(0); cin.tie(0);
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int n, m, p = 0;
    cin >> n >> m;
    for (int i = 0; i < m; ++i){
        cin >> a[i].u >> a[i].v >> a[i].c;
    }
    sort(a, a + m);
    int i = 0, j = 1;
    while (j < m){
        while (j < m && a[j].c == a[i].c) ++j;
        //为什么要一次把所有权值相同的边都一起处理呢?
        //我们首先把权值相同的边的两个顶点原来的dp值都保存下来
        //这些dp值都是没有加入新边的dp值,而加入的这些新边的权值一定都大于图里面的任何边
        //为了保证新加的边一定会更新它的顶点的值,必须把权值相同的边一起加进来
        //为了防止重复更新需要把上一次的值保存下来用上一次的值更新
        for (int k = i; k < j; ++k) f[a[k].u] = dp[a[k].u], f[a[k].v] = dp[a[k].v];
        for (int k = i; k < j; ++k) dp[a[k].u] = max(dp[a[k].u], f[a[k].v] + 1), dp[a[k].v] = max(dp[a[k].v], f[a[k].u] + 1);
        i = j;
    }
    cout << *max_element(dp, dp + n) << endl;
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值