这道题,第一反应就是SPFA。由于最开始的邻接表没有优化,T了三个点。后来我看了算法笔记才知道。使用SPFA的时候,要在搞一个数组,判断某个节点是否在队列中,如果不在队列中,那么才有资格入队,如果在,就不能入队了,出队的时候将这个元素设置为不在队列中,入队的时候将这个·元素设置在队列中。
下面是邻接表的AC代码~
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
#define Max 1600
#define INF -1000000
struct Node
{
int v,w;
};
int dp[Max]; //设dp表示从1这个点到其他点的最长距离
vector<Node > Graph[Max];
bool flag[Max];
void bfs(int n);
int main()
{
int n,m,u,v,w;
cin>>n>>m;
Node node;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
node.v=v;
node.w=w;
Graph[u].push_back(node);
}
fill(dp,dp+Max,INF);
bfs(n);
if(dp[n]==INF)
{
cout<<-1;
}
else
{
cout<<dp[n];
}
return 0;
}
void bfs(int n)
{
queue<int > que;
que.push(1);
flag[1]=true;
dp[1]=0;
while(!que.empty())
{
int u=que.front();
que.pop();
flag[u]=false;
for(int i=0;i<Graph[u].size();i++)
{
int v=Graph[u][i].v;
if(dp[v]<Graph[u][i].w+dp[u])
{
dp[v]=max(dp[v],Graph[u][i].w+dp[u]);
}
if(v!=n&&!flag[v])
{
que.push(v);
flag[v]=true;
}
}
}
}
下面是邻接矩阵的AC代码~
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
#define Max 1600
#define INF -1000000
struct Node
{
int v,w;
};
int dp[Max]; //设dp表示原点到当前i点的最长距离
int Graph[Max][Max];
bool flag[Max];// 判断节点是否在队列中
void bfs(int n);
int main()
{
int n,m,u,v,w;
cin>>n>>m;
fill(Graph[0],Graph[0]+Max*Max,INF);
memset(flag,false, sizeof(flag));
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
Graph[u][v]=max(Graph[u][v],w);
}
fill(dp,dp+Max,INF);
dp[1]=0;
bfs(n);
if(dp[n]!=INF)
{
cout<<dp[n];
}
else
{
cout<<-1;
}
return 0;
}
void bfs(int n)
{
queue<int > que;
que.push(1);
while(!que.empty())
{
int u=que.front();
que.pop();
flag[u]=false;//不在队列
for(int i=1;i<=n;i++)
{
if(Graph[u][i]!=INF&&dp[i]<dp[u]+Graph[u][i]) //如果u-->i之间有边
{
dp[i]=max(dp[i],dp[u]+Graph[u][i]);
if(i!=n&&!flag[i])
{
que.push(i);
}
}
}
}
}
看了一下程序时间,总体上看,邻接表要快一些。
邻接表
邻接矩阵:
祝大家早日AC~