• ZOJ1508 Interval


    /*
    *State: ZOJ1508    C++    220ms    16008
    *题目大意:
    *        有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]
    *        表示在该序列中处于[ai,bi]这个区间的整数至少有ci个。如果存在这
    *        样的序列,请求出满足题目要求的最短的序列长度是多少。如果不存在则
    *        输出 -1。输入:第一行包括一个整数n,表示区间个数,以下n行每行描述
    *        这些区间,第i+1行三个整数ai,bi,ci,由空格隔开,其中0<=ai<=bi<=50000 
    *        而且 1<=ci<=bi-ai+1。输出:一行,输出满足要求的序列的长度的最小值。
    *解题思路:
    *        与上题类似。此题一开始用了Bellman_ford去写,结果TLE了,而用spfa就220ms
    *        明显spfa要优秀很多啊。当然,稀疏图的话,还是要考虑到用Bellman_ford.
    *解题困惑:
    *        为什么不能用最短路约束来求?因为最短路求出来的是满足的最大值。
    */
    View Code
    #include <iostream>
    #include <queue>
    #include <map>
    #include <string>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int MAXN = 50005;
    const int MAXE = 1000005;
    const int inf = 0x3f3f3f3f;
    
    typedef struct _node
    {
        int u, v, w;
        int next;
    }N;
    N edge[MAXE];
    int head[MAXN], cntEdge;
    
    void init()
    {
        cntEdge = 0;
        for(int i = 0; i < MAXN; i++)
        {
            head[i] = -1;
        }
    }
    
    void addEdge(int u, int v, int w)
    {
        edge[cntEdge].v = v;
        edge[cntEdge].w = w;
        edge[cntEdge].next = head[u];
        head[u] = cntEdge++;
    }
    
    int spfa(int s, int n)
    {
        int dis[MAXN], inQ[MAXN] = {0}, inN[MAXN] = {0};
        for(int i = 0; i <= n; i++)
            dis[i] = -inf;
    
        queue<int> Q;
    
        /*for(int i = 0; i <= n; i++)
        {
            Q.push(i);
            inN[i] = 1;
            inQ[i]++;
            dis[i] = 0;
        }*/
        Q.push(s);
        inQ[s] = 1;
        inN[s]++;
        dis[s] = 0;
    
        while(!Q.empty())
        {
            int pre = Q.front();
            Q.pop();
            inQ[pre] = 0;
    
            for(int f = head[pre]; f != -1; f = edge[f].next)
            {
                int son = edge[f].v;
                int w = edge[f].w;
    
                if(dis[pre] + w > dis[son])
                {
                    dis[son] = dis[pre] + w;
                    if(!inQ[son])
                    {
                        Q.push(son);
                        inQ[son] = 1;
                        inN[son]++;
                        if(inN[son] > n + 1)
                            return -1;
                    }
                }
            }
        }
        /*for(int i = 0; i <= n; i++)
            cout << dis[i] << " ";
        cout << endl;*/
        return dis[n];
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        freopen("inZOJ1508.txt", "r", stdin);
    #endif
    
        int n;
        while(scanf("%d", &n) == 1)
        {
            init();
            int u, v, Max = -inf, w;
            for(int i = 0; i < n; i++)
            {
                scanf("%d %d %d", &u, &v, &w);
                if(u > Max)
                    Max = u;
                if(v + 1 > Max)
                    Max = v + 1;
                if(!u)
                    u++;
                addEdge(u, v + 1, w);
            }
            for(int i = 0; i <= Max; i++)
            {
                addEdge(i, i + 1, 0);
                addEdge(i + 1, i, -1);
            }
            /*for(int i = 1; i <= Max; i++)
            {
                addEdge(0, i, 0);
            }*/
            int sol = spfa(0, Max);
            printf("%d\n", sol);
        }
        return 0;
    }
  • 相关阅读:
    定时任务的分布式调度
    springmvc 静态资源 配置
    activemq 持久化
    函数式编程与面向对象编程的比较
    LeetCode 108——将有序数组转化为二叉搜索树
    LeetCode 104——二叉树中的最大深度
    LeetCode 700——二叉搜索树中的搜索
    线性代数之——四个基本子空间
    线性代数之——线性相关性、基和维数
    线性代数之——秩和解的结构
  • 原文地址:https://www.cnblogs.com/cchun/p/2667587.html
Copyright © 2020-2023  润新知