POJ 1201 Intervals (差分约束,SPFA)

饿。。思路和实现方法与POJ 1716完全一样。。。

但根据北大那本图论书,此题应该有更加优化的建图和约束的方法,因此先丢垃圾桶。。。

#include <stdio.h>
#include <string.h>

#define maxn 150010
#define inf 1000000000

int head[maxn], pnt[maxn], length[maxn], next[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++;
}

int 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;
	queue[qhead]=src;
	inq[src]=1;
	countq[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]]++;
					if(countq[pnt[idx]]>max-min) return 0;
					queue[qtail++]=pnt[idx];
				}
			}
			idx=next[idx];
		}
		inq[queue[qhead]]=0;
		qhead++;
	}
	return 1;
}

int main()
{
	tot=0;
	memset(head,-1,sizeof(head));
	memset(next,-1,sizeof(next));
	
	max=0;
	min=inf;
	
	scanf("%d",&n);
	for (int i=0; i<n; i++) {
		scanf("%d%d%d",&a,&b,&len);
		addedge(b+1,a,-len);
		if(b+1>max) max=b+1;
		if(a<min) min=a;
	}
	
	for (int i=min; i<max; i++) {
		addedge(i,i+1,1);
		addedge(i+1,i,0);
	}
	
	//test
	/*for (int i=min; i<=max; i++) {
		printf("i:\n");
		int idx=head[i];
		while(~idx) {
			printf("%d %d %d\n",i,pnt[idx],length[idx]);
			idx=next[idx];
		}
	}*/
	
	spfa(max);
	printf("%d\n",dist[max]-dist[min]);
	
}

  

posted on 2011-07-24 16:37  Eucalyptus  阅读(230)  评论(0编辑  收藏  举报