zoukankan      html  css  js  c++  java
  • Codeforces 960F Pathwalks ( LIS && 树状数组 )

    题意 : 给出若干个边,每条边按照给出的顺序编号,问你找到一条最长的边权以及边的编号同时严格升序的一条路径,要使得这条路径包含的边尽可能多,最后输出边的条数

    分析 : 

    这题和 LIS 很相似,不同的是加多了一个需要边和边相连这一条件

    考虑使用树状数组求 LIS 的方法来考虑这题

    如果你还不知道 LIS 还能用树状数组做 ==> Click here

    由于有了只有能够构成路径的边才能搭配成子序列这一限制

    我们将原本一维的树状数组开成二维

    增加的维度表示以某个图中顶点为结尾这一状态

    定义二维树状数组 c[Node][Weight]

    表示以顶点(图中的顶点) Node 为结尾、边权为 Weight 时候的 LIS 长度

    然后对于边  (a、b、w) 用 c[a][w] + 1 去更新 c[b][w] 即可

    更新过程类似树状数组求解 LIS 问题一样

    最后就是这题貌似还能用主席树等可持久化数据结构做

    待我研究后补上.......

    #include<bits/stdc++.h>
    #define lowbit(i) (i & (-i))
    using namespace std;
    const int maxn = 1e5 + 5;
    const int INF = 0x3f3f3f3f;
    map<int, int> c[maxn];///1e5的二维数组开不下、采用map来代替开
    int N, M;
    
    int query(int i, int w)
    {
        int ret = 0;
        while(w > 0){
            ret = max(ret, c[i][w]);
            w -= lowbit(w);
        }
        return ret;
    }
    
    void update(int i, int w, int val)///update的时候注意w不能为 0
    {
        while(w < maxn){
            c[i][w] = max(c[i][w], val);
            w += lowbit(w);
        }
    }
    
    int main(void)
    {
        scanf("%d %d", &N, &M);
        int a, b, w, MX = -INF;
        for(int i=1; i<=M; i++){
            scanf("%d %d %d", &a, &b, &w);
            MX = max(MX, ++w);
            update(b, w, query(a, w-1)+1);
        }
    
        int ans = 0;
        for(int i=1; i<=N; i++)
            ans = max(ans, query(i, MX));
    
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    redhat yum ISO 本地源
    md5sum的使用
    查看进程内存使用情况
    常见User-Agent大全
    aggregate和annotate使用
    Django logging配置
    Django 开发调试工具:Django-debug-toolbar
    浏览器的同源策略及跨域解决方案
    Python contenttypes组件
    Dajngo admin
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/8779522.html
Copyright © 2011-2022 走看看