洛谷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]);
这样写会导致超时。