zoukankan      html  css  js  c++  java
  • POJ

    相交区间选尽量少的点是可以贪心的,右端点排序以后,尽量往右边放可以得到可以使得点在区间尽可能多。

    但是我只想到了O(n)的维护方法。(数据比较水,能过...

    或者是前缀和可以写sum(bi) - sum(ai-1) ≥ ci

    再加上前缀和的单调性 sum(i) - sum(i-1) ≥ 0

    以及一个点只能选一次 sum(i-1) - sum(i) ≥ -1。

    左边具有可加性的,根据对偶性:min ( sum(n) - sum(0) ) ≥ max( c )

    右边就是求一个最长路了。

    复杂度:O(VE)。

    两种复杂度都爆了,还是能过,大力出奇迹。。。

    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    #include<numeric>
    using namespace std;
    
    typedef long long ll;
    
    
    const int maxn = 50000+5;
    const int maxm = maxn*3;
    
    int dat[2][maxn];
    int * const d = dat[0]+1;
    
    int * const hd = dat[1]+1;
    int nx[maxm];
    int a[maxn], b[maxm], c[maxm];
    int ec;
    
    void add_edge(int u, int v, int w)
    {
        c[ec] = w;
        b[ec] = v;
        nx[ec] = hd[u];
        hd[u] = ec++;
    }
    
    int n;
    
    int q[maxn];
    bool inq[maxn];
    
    int spfa(int s, int t)
    {
        memset(d+s,0xff,sizeof(int)*(t-s+1));
        int top = 0;
        q[++top] = s; d[s] = 0; inq[s] = true;
        while(top){
            int u = q[top--];
            inq[u] = false;
            for(int i = hd[u]; ~i; i = nx[i]){
                int v = b[i];
                if(d[v] < d[u] + c[i]){
                    d[v] = d[u] + c[i];
                    if(!inq[v]) {
                        q[++top] = v;
                        inq[v] = true;
                    }
                }
            }
        }
        return d[t];
    }
    
    void solve()
    {
        for(int i = 0; i < n; i++){
            scanf("%d%d%d", a+i, b+i, c+i);
        }
        int s = *min_element(a,a+n)-1, t = *max_element(b,b+n);
        memset(hd+s, 0xff, sizeof(int)*(t-s+1));
        for(int i = 0; i < n; i++){
            nx[i] = hd[--a[i]];
            hd[a[i]] = i;
        }
        ec = n;
        for(int i = s; i < t; i++){
            add_edge(i,i+1,0);
            add_edge(i+1,i,-1);
        }
    
        printf("%d
    ", spfa(s,t));
    }
    
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        while(~scanf("%d",&n)){
            solve();
        }
        return 0;
    }
  • 相关阅读:
    EBS SQL > Form & Report
    oracle sql 优化分析点
    MRP 物料需求计划
    MRPII 制造资源计划
    Barcode128 应用实务
    Oracle SQL语句优化技术分析
    APPSQLAP10710 Online accounting could not be created. AP Invoice 无法创建会计分录
    Oracle数据完整性和锁机制
    ORACLE Responsibility Menu Reference to Other User
    EBS 常用 SQL
  • 原文地址:https://www.cnblogs.com/jerryRey/p/5004648.html
Copyright © 2011-2022 走看看