POJ 1716 Integer Intervals (差分约束,SPFA)

建模方法:

用数组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]);
}

  

posted on 2011-07-24 15:18  Eucalyptus  阅读(405)  评论(0编辑  收藏  举报