Silver Cow Party (POJ - 3268)最短路 (dijkstra算法)

One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1…N
is going to attend the big cow party to be held at farm #X (1 ≤ X ≤
N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads
connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of
time to traverse.

Each cow must walk to the party and, when the party is over, return to
her farm. Each cow is lazy and thus picks an optimal route with the
shortest time. A cow’s return route might be different from her
original route to the party since roads are one-way.

Of all the cows, what is the longest amount of time a cow must spend
walking to the party and back?

Input

Line 1: Three space-separated integers, respectively: N, M,

and X Lines 2…M+1: Line i+1 describes road i with three
space-separated integers: Ai, Bi, and Ti. The described road runs from
farm Ai to farm Bi, requiring Ti time units to traverse.

Output

Line 1: One integer: the maximum of time any one cow must walk.

Sample Input

4 8 2

1 2 4

1 3 2

1 4 7

2 1 1

2 3 5

3 1 2

3 4 4

4 2 3

Sample Output

10

Hint

Cow 4 proceeds directly to the party (3 units) and returns via farms 1
and 3 (7 units), for a total of 10 time units.

这一道题还是很简单的,直接套模板,但是模板只记得一小部分的我,在这上面几乎出尽了我所能想象到的bug,所以特地写篇博客谨记;

<1>首先是超时

这道题因为用了两次的Dijkstra算法,所以在时间限制上很吃亏,所以能不用memset();就不用memset();
但是该用的时候千万不要省掉,我刚开始赋值的时候,由于初值没有赋值,导致我的值也没有赋上。

<2> 其次是赋值

for(int i=1;i<n;i++)
	{
		int w=inf,r=0;
		for(int j=1;j<=n;j++)
		{
			if(!bok[j]&&w>cmp[j])
			{
				w=cmp[j];
				r=j;
			}

这是我当初给的赋值,这是第一步的连锁反应,因为我将所有memset();取消掉了之后,再删除不删除

memset(cmp,inf,sizeof(cmp));

这个代码后出现了不同结果,再经过进一步排查后发现,是赋值的原因,赋值中出现了0,而0没有被用到过,所以就出现了结果大相径庭的原因;

最初的错误代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int book[1010][1010],book1[1010][1010];
int n,m,x;
int bok[1010];
#define inf 0x3f3f3f3f
int bis[1010],vis[1010]; 
void dijkstra(int book[1010][1010],int cmp[1010])
{
	memset(cmp,inf,sizeof(book));
	for(int i=1;i<=n;i++)
	{
		cmp[i]=book[x][i];
		//printf("cmp[%d]==%d\n",i,cmp[i]);
	}
	cmp[x]=0;
	memset(bok,0,sizeof(bok));
	bok[x]=1;
	for(int i=1;i<n;i++)
	{
		int w=inf,r=0;
		//r的值不能为0,如果为0,后面要进行continue处理;
		for(int j=1;j<=n;j++)
		{
			if(!bok[j]&&w>cmp[j])
			{
				w=cmp[j];
				r=j;
			}//这里是最后一步才发现的错误;
			//大括号的位置错了;
			bok[r]=1;
			//printf("w==%d\tr==%d\n",w,r);
			for(int j=1;j<=n;j++)
			{
				if(!bok[j]&&cmp[j]>cmp[r]+book[r][j])
				{
					cmp[j]=cmp[r]+book[r][j];
					//printf("cmp[%d]==%d\n",j,cmp[j]);
				}
			}
		}//和前面括号的位置一样,就是这个往前移;
	}
	return ;
}
int main()
{
	
	scanf("%d %d %d",&n,&m,&x);
	memset(book,inf,sizeof(book));
	memset(book1,inf,sizeof(book1));//这里过于依赖memset了;
	for(int i=0;i<m;i++)
	{
		int a,b,c;
		scanf("%d %d %d",&a,&b,&c);
		if(book[a][b]>c)
		{
			book[a][b]=c;
		    book1[b][a]=c;
		}
	}
	/*for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		printf("book[%d][%d]==%d\n",i,j,book[i][j]);
	}*/
		dijkstra(book,vis);
		dijkstra(book1,bis);
		int sum=0;
		for(int i=1;i<=n;i++)
		{
			//printf("\t%d\t%d\n",vis[i],bis[i]);
			sum=max(vis[i]+bis[i],sum);
		}
		printf("%d\n",sum);
	return 0;
}

最后更改后的代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int book[1010][1010];
int n,m,x;
int bok[1010];
#define inf 0x3f3f3f3f
int vis[1010],cmp[1010]; 
void dijkstra()
{	
	for(int i=1;i<=n;i++)
	{
		cmp[i]=book[x][i];
		bok[i]=0;	
	}
	bok[x]=1;
	for(int i=1;i<n;i++)
	{
		int w=inf,r=x;
		for(int j=1;j<=n;j++)
		{
			if(!bok[j]&&w>cmp[j])
			{
				w=cmp[j];
				r=j;
			}
		}
			bok[r]=1;
			for(int j=1;j<=n;j++)
			{
				if(!bok[j]&&cmp[j]>cmp[r]+book[r][j]&&book[r][j]<inf)
				{
					cmp[j]=cmp[r]+book[r][j];
					//printf("cmp[%d]==%d\tcmp[%d]==%d\tbook[%d][%d]=%d\n",j,cmp[j],r,cmp[r],r,j,book[r][j]);
				}
			}
	}
	return ;
}
int main()
{
	while(scanf("%d %d %d",&n,&m,&x)!=EOF)
	{
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	if(i==j)
	book[i][j]=0;
	else
	book[i][j]=inf;
	for(int i=0;i<m;i++)
	{
		int a,b,c;
		scanf("%d %d %d",&a,&b,&c);
		if(book[a][b]>c)
		{
			book[a][b]=c;
		}
	}
		dijkstra();
		for(int i=1;i<=n;i++)
		{
			vis[i]=cmp[i];
		}
		for(int i=1;i<=n;i++)矩阵置换是沿对角线进行置换
		for(int j=i+1;j<=n;j++)
		{
			int ww=book[i][j];
			book[i][j]=book[j][i];
			book[j][i]=ww;
		}
		dijkstra();
		int sum=0;
		for(int i=1;i<=n;i++)
		{
			if(i!=x)
			sum=max(vis[i]+cmp[i],sum);
		}
		printf("%d\n",sum);
		}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值