POJ 3169 Layout (差分约束系统,SPFA)

第一次做差分约束系统,关键在于建模。

此题的建模很简单, 喜欢:d[j]-d[i]<=len

          不喜欢:d[j]-d[i]>=len   =>   d[i]-d[j]<=-len

代码:

#include <stdio.h>
#include <string.h>
#define maxn 1010
#define maxm 10010
#define inf 1000000000

int head[maxn], pnt[maxm], length[maxm], next[maxm];
int tot;

int dist[maxn];

int queue[maxn*maxn];
int inq[maxn];
int countq[maxn];

int n,ml,mk;
int a,b,len;

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=0; i<n; i++) {
		inq[i]=0;
		countq[i]=0;
		dist[i]=inf;
	}
	queue[qhead]=src;
	dist[src]=0;
	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]]>n) return 0;
					queue[qtail++]=pnt[idx];
				}
			}
			idx=next[idx];
		}
		inq[queue[qhead]]=0;
		qhead++;
	}
	return 1;
}

int main()
{
	scanf("%d%d%d",&n,&ml,&mk);
	
	tot=0;
	memset(head,-1,sizeof(head));
	memset(next,-1,sizeof(next));
	
	for (int i=0; i<ml; i++) {
		scanf("%d%d%d",&a,&b,&len);
		a--,b--;
		addedge(a,b,len);
	}
	for (int i=0; i<mk; i++) {
		scanf("%d%d%d",&a,&b,&len);
		a--,b--;
		addedge(b,a,-len);
	}
	if(spfa(0)) {
		if(dist[n-1]==inf) printf("-2\n");
		else printf("%d\n",dist[n-1]);
	}
	else printf("-1\n");
}

  

posted on 2011-07-24 02:30  Eucalyptus  阅读(553)  评论(0编辑  收藏  举报