zoukankan      html  css  js  c++  java
  • Codeforces 459E

    题意:给一个有向图带权图,求最长严格递增链的长度。

    分析:

    定义 dp(i) 以 节点 i 开头的最长长度,要保证上一条边很长,而且权值很小,很难把控。

    定义 f(i) 以节点 i 结尾的最长长度。 但是要严格递增,节点节点间转移也不好搞,于是以边为对象。

    首先对边排序分层,后面的边,一定大于等于前面的边,用前面一层的边,跟新后面的一层的节点。

    f[e[k].v] = max(f[e[k].v]+f[e[k].u+1])

    但是,这样是不对的,原因是严格递增这里,若在同一层里面,有1->2->3,权值是1,那么就没有做到严格递增了。

    而是累加起来了。

    这里用一个临时变量存下来,存下之前能得到最长长度。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 300000+5;
    
    struct Edge {
        int u,v,w;
        bool operator < (const Edge & rhs) const {
            return w < rhs.w;
        }
    }e[maxn];
    
    int d[maxn],f[maxn];
    
    int main(int argc, char const *argv[])
    {
        int n,m;
        scanf("%d%d",&n,&m);
    
        for(int i = 0;i<m;i++) {
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        }
    
        sort(e,e+m);
    
        for(int i=0;i<m;i++) {
            int j;
            for(j=i;e[j].w==e[i].w&&j<m;j++);
    
            for(int k=i;k<j;k++)
                d[e[k].v] = max(d[e[k].v],f[e[k].u]+1);
    
            for(int k=i;k<j;k++)
                f[e[k].v] = d[e[k].v];
            i = j-1;
        }
    
        int ans = 0;
        for (int i = 1; i <= n; ++i)
            ans = max(ans,f[i]);
    
        printf("%d
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    155. 最小栈
    160. 相交链表
    PAT 1057 Stack
    PAT 1026 Table Tennis
    PAT 1017 Queueing at Bank
    PAT 1014 Waiting in Line
    PAT 1029 Median
    PAT 1016 Phone Bills
    PAT 1010 Radix
    PAT 1122 Hamiltonian Cycle
  • 原文地址:https://www.cnblogs.com/TreeDream/p/7251310.html
Copyright © 2011-2022 走看看