洛谷P1807 bfs最长路 做题笔记

洛谷P1807

代码如下:

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
#define pub push_back
#define pob pop_back
#define N 100005
vector<int>a[N];
queue<int>q;
int value[1505][1505];
long long d[N];
bool color[N];
int main()
{
	int n,m;
	cin>>n>>m;
	memset(d,-1,sizeof(d));
	for(int i=0;i<m;i++)
	{
		int t,ans,v;
		cin>>t>>ans>>v;
		a[t].pub(ans);
		value[t][ans]=max(value[t][ans],v);
		value[ans][t]=max(value[t][ans],v);
	}
	d[1]=0;
	q.push(1);
	while(!q.empty())
	{
		int ans=q.front();
		q.pop();
		for(int i=0;i<a[ans].size();i++)
		{
			int y=a[ans][i];
			if(d[y]<value[ans][y]+d[ans])
			{
			q.push(y);
			d[y]=value[ans][y]+d[ans];
		   }
		}
	}
	cout<<d[n]<<endl;
	return 0;
 } 

关于此题,需要指出几个知识点盲区和思维漏洞。
1.1 关于memset函数的使用
在之前我聊过如何用memst函数来清空数组,这里,我学会如何用memset函数赋予极大值。
固定模板:

memset(s,0x3f,sizeof());

这个0x3f和二进制的计算有关,具体我不深入,只用记住0x3f可以用于赋予最大值就行。
其次是关于memset的使用头文件应该是

#include<cstring>

如果写成:

#include<string>

就会报错。
实际上这两个头文件是两个完全不同的头文件,cstring和c语言中的string.h相一致,而string的头文件是要用string类型才使用的,这个我在之前提到过。
2.1 对AC代码的解析

	value[t][ans]=max(value[t][ans],v);
	value[ans][t]=max(value[t][ans],v);

对于此题我最大的疑惑是为什么要用max来确定最长路径,两点之间的距离不应该是固定的吗?实际上,在做这些最长(最短)路径的问题时,一定要考虑条条大路通罗马的问题。即两点之间可以有很多条路,而我们只用取其中最大或最小的就可以。
再者就是两点之间距离的表示方法,一开始我定义的是一维数组(爆炸的思维 ),这样写不能用于表示两点的距离。所以二维数组是一个完美的选择,但是如果数据多到1e5就不能用二维数组表示了。

if(d[y]<value[ans][y]+d[ans])
{
	q.push(y);
	d[y]=value[ans][y]+d[ans];
}

这里是一个加速的环节,初解我是这样写的:

q.push(y);
d[y]=max(d[y],value[ans][y]+d[ans]);

这样写会导致超时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值