整數區間(poj1716)
阿新 • • 發佈:2019-02-07
整數區間(intervals.cpp/pas)
題目描述(Description):
對於一個整數序列,給出它的若干個閉區間[a,b],表示a到b包含至少2個不同的
列中,你的任務是找到滿足所有條件的最短的序列的長度。
輸入檔案(dist.in):
第一行一個數n (1 <= n <= 10000),表示有n個區間描述,接下來n行,每行兩個
<= a < b <= 10000)表示區間,
輸出檔案(dist.out):
輸出最短的滿足條件的序列長度。
樣例(Sample):
Sample Input Case 1:
4
3 6
2 4
0 2
4 7
Sample Output Case 1:
4
/////////////////////////////////////////////////////////////////////////////////////////////////
思路:
對於差分約束的題目,關鍵在於找不等式關係。
從題目條件可以明確的看出以下關係
s[j] - s[i-1] >= 2
s[i] - s[i-1] >= 0
s[i-1] - s[i] >= -1
所以 就可以用SPFA跑最長路啦!!!
然後就對了啦!!!
/////////////////////////////////////////////////////////////////////////////////////////////////
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<iostream> using namespace std; const int inf=0x3f3f3f3f; int n,maxl=0; int head[1000000],k=0; int dis[10000+10]; int inq[10000+10]; int inq_times[10000+10]; queue<int> q; struct code { int v,w,next; }e[1000000]; void adde(int u,int v,int w) { e[k].v=v; e[k].w=w; e[k].next=head[u]; head[u]=k++; } void read() { memset(head,-1,sizeof(head)); int a,b; cin>>n; for(int i=1;i<=n;i++) { scanf("%d%d",&a,&b); adde(a,b+1,2); maxl=max(maxl,b+1); } for(int i=0;i<maxl;i++) { adde(i,i+1,0); adde(i+1,i,-1); } } void work() { memset(dis,-inf,sizeof(dis)); memset(inq,0,sizeof(inq)); dis[0]=0; inq_times[0]++; q.push(0); while(!q.empty()) { int u=q.front();q.pop(); inq[u]=0; if(inq_times[u]>maxl) { dis[maxl]=0; break; } for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].v; if(dis[v]<dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; if(!inq[v]) { inq[v]=1; q.push(v); inq_times[v]++; } } } } printf("%d\n",dis[maxl]); } int main() { read(); work(); return 0; }