usaco 2008 oct pwalk

BFS即可,不知道怎么回事,我竟然写了个SPFA——虽然也是正确的。

还需要注意细节,数组开始又小了。。。

/*
 * usaco 2008 oct pwalk.c
 * mike-w
 * 2012-10-28
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAXN 1111
#define QSIZE MAXN
#define xLOL_DEBUG
#define xLOL_GRAPH

int dst[MAXN][MAXN];
int f[2*MAXN][3], head[MAXN], h_size;
int N, Q;

int que[QSIZE], qhead, qtail, qlen;
int inq[MAXN];

int enque(int e)
{
	if(qlen==QSIZE)
		puts("queue is full!");
	que[qtail++]=e;
	if(qtail==QSIZE)
		qtail=0;
	qlen++;
	return 0;
}

int deque(void)
{
	if(qlen==0)
		puts("queue is empty!");
	int ret=que[qhead++];
	if(qhead==QSIZE)
		qhead=0;
	qlen--;
	return ret;
}

int comp(const void *e1, const void *e2)
{
	return *((int*)e1) - *((int*)e2);
}

/* note: only N-1 edges */
int build_graph(void)
{
	int i;
	h_size=2*N-2;
	qsort(f, h_size, sizeof(int[3]), comp);
	for(i=1; i<=N; i++)
		head[i]=-1;
	for(i=0; i<h_size; i++)
		if(head[f[i][0]]<0)
			head[f[i][0]]=i;
	return 0;
}

int spfa(int init, int *s)
{
	int x, tar, i;

	qhead=qtail=qlen=0;
	memset(inq, 0, sizeof(inq));
	for(i=1; i<=N; i++)
		if(i!=init)
			s[i]=-1;
	enque(init);
	inq[init]=1;
	while(qlen>0)
	{
		x=deque();
		inq[x]=0;
		for(i=head[x]; i>=0 && i<h_size && f[i][0]==x; i++)
		{
			tar=f[i][1];
			if(s[tar]==-1 || s[x]+f[i][2]<s[tar])
			{
				s[tar]=s[x]+f[i][2];
				if(!inq[tar])
					enque(tar), inq[tar]=1;
			}
		}
	}
	return 0;
}

int main(void)
{
	int i, j, t1, t2;

	scanf("%d%d", &N, &Q);
	for(i=0; i<N-1; i++)
	{
		scanf("%d%d%d", f[i], f[i]+1, f[i]+2);
		f[N-1+i][0]=f[i][1];
		f[N-1+i][1]=f[i][0];
		f[N-1+i][2]=f[i][2];
	}
	
	build_graph();

#ifdef LOL_GRAPH
	puts("\nforward star:");
	for(i=1; i<=N; i++)
	{
		printf("%-2d+\n", i);
		for(j=head[i]; j>=0 && j<h_size && f[j][0]==i; j++)
			printf("  |- %d [%2d]\n", f[j][1], f[j][2]);
	}
	puts("............................");
#endif

	for(i=1; i<=N; i++)
		spfa(i, dst[i]);
#ifdef LOL_DEBUG
	puts("shortest path:");
	for(i=1; i<=N; i++)
		for(j=1; j<=N; j++)
			printf("%d%c", dst[i][j], j==N?'\n':' ');
	puts(".............................");
#endif

	for(i=1; i<=Q; i++)
	{
		scanf("%d%d", &t1, &t2);
		printf("%d\n", dst[t1][t2]);
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值