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;
}