建模方法:
用数组dist[i]表示从点0到点i-1所包含的关键点的数目;
输入数据即可转化为:dist[b+1]-dist[a]>=2 => dist[a]-dist[b+1]<=-2
根据实际情况还有两个约束条件:
dist[i+1]-dist[i]<=1
dist[i+1]-dist[i]>=0 => dist[i]-dist[i]+1<=0
于是可以建图,SPFA。
最后输出dist[max]-dist[min]即可(max与min 为输入数据出现的最大点和最小点)
#include <stdio.h>
#include <string.h>
#define maxn 150010
#define inf 1000000000
int head[maxn], pnt[maxn], next[maxn], length[maxn];
int tot;
int dist[maxn];
int queue[10000000];
int inq[maxn];
int countq[maxn];
int n;
int a,b,len;
int max,min;
void addedge(int a,int b,int len)
{
pnt[tot]=b;
length[tot]=len;
next[tot]=head[a];
head[a]=tot++;
}
void spfa(int src)
{
int qhead=0;
int qtail=1;
for(int i=min; i<=max; i++) {
dist[i]=inf;
inq[i]=0;
countq[i]=0;
}
dist[src]=0;
inq[src]=1;
countq[src]=1;
queue[qhead]=src;
while (qhead<qtail) {
int idx=head[queue[qhead]];
while (~idx) {
if (dist[pnt[idx]] > dist[queue[qhead]] + length[idx]) {
dist[pnt[idx]] = dist[queue[qhead]] + length[idx];
if(!inq[pnt[idx]]) {
inq[pnt[idx]]=1;
countq[pnt[idx]]++;
queue[qtail++]=pnt[idx];
}
}
idx=next[idx];
}
inq[queue[qhead]]=0;
qhead++;
}
}
int main()
{
memset(head,-1,sizeof(head));
memset(next,-1,sizeof(next));
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%d%d",&a,&b);
addedge(b+1,a,-2);
if(a>max) max=a;
if(b+1>max) max=b+1;
if(a<min) min=a;
if(b<min) min=b+1;
}
for (int i=0; i<max; i++) {
addedge(i,i+1,1);
addedge(i+1,i,0);
}
spfa(max);
printf("%d\n",dist[max]-dist[min]);
}
浙公网安备 33010602011771号