poj1716 Integer Intervals(差分约束)


http://poj.org/problem?id=1716

题意:m个约束条件,a b表示在[a,b]区间内有约束,求满足所有约束条件内都包含至少两个正整数的最短序列长度。


思路:所有约束条件内都包含至少两个正整数,那么我们就在每个约束条件内都约束一个<=2,和poj1201一样求最长路即可。实现方法栈63ms,队列125ms,两倍啊= =,真不稳定。两题一个最大的区别就是,上一题ai <= bi ,这一题a < b,直接导致最后必须要向右平移一个单位后才能过。讲道理a<b处理的负数应该少了啊,如果是因为起点变成负数而产生的超时为毛会发生?我不知道,只能以后遇到这题回避负数好了。。哎


#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;

const int N = 50005;
const int INF = 0x3f3f3f3f;

int dis[N], head[N], cnt, L, R;
bool instack[N];

struct node
{
    int v, w, next;
}edge[N*4];

void add(int u, int v, int w)
{
    edge[cnt] = (struct node){v, w, head[u]};
    head[u] = cnt++;
}

int spfa()
{
    memset(instack, false, sizeof(instack));
    memset(dis, -INF, sizeof(dis));
    stack<int>sta;
    dis[L] = 0;
    instack[L] = true;
    sta.push(L);
    while(!sta.empty())
    {
        int u = sta.top();
        sta.pop();
        instack[u] = false;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].v;
            if(dis[u]+edge[i].w>dis[v])
            {
                dis[v] = dis[u]+edge[i].w;
                if(!instack[v])
                {
                    instack[v] = true;
                    sta.push(v);
                }
            }
        }
    }
    return dis[R];
}

int main()
{
  //  freopen("in.txt", "r", stdin);
    int m, a, b;
    while(~scanf("%d", &m))
    {
        cnt = R = 0;
        L = INF;
        memset(head, -1, sizeof(head));
        for(int i = 1; i <= m; i++)
        {
            scanf("%d%d", &a, &b);
            a++;
            b++;
            L = min(L, a-1);
            R = max(R, b);
            add(a-1, b, 2);
        }
        for(int i = L; i <= R; i++)
        {
            add(i-1, i, 0);
            add(i, i-1, -1);
        }
        printf("%d\n", spfa());
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值