http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/2498.html
SPFA没有用贪心去找出最优的边去优化
全部进行松弛一遍 。
有点可以检测负环 ;
关键是 邻接表打发简单;
区别:
不再是vis[]标记是否访问过;
而是用一个inque数组 来判断是否入队
注意反向建图
数据水默认1为源点n为终点
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=10005;
int n,m,first,last;
struct edge
{
int v,w;
};
vector<edge>u[maxn];
int dis[maxn];
int inque[maxn];
int pre[maxn];
void spfa()
{
queue<int>que;
for(int i=1; i<=n; i++)
dis[i]=-inf;
dis[n]=0;
que.push(n);
inque[n]=1;
while(!que.empty())
{
int temp=que.front();
que.pop();
inque[temp]=0;
for(int i=0; i<u[temp].size(); i++)
{
int to=u[temp][i].v;
if(dis[temp]>-inf&&(dis[to]<dis[temp]+u[temp][i].w||(dis[to]==dis[temp]+u[temp][i].w&&(temp<pre[to]))))
{
dis[to]=dis[temp]+u[temp][i].w;
pre[to]=temp;
if(inque[to]==0)
{
que.push(to);
inque[to]=1;
}
}
}
}
}
int main()
{
int x,y,z;
while(cin>>n>>m)
{
for(int i=1; i<=n; i++)
u[i].clear();
memset(pre,0x3f,sizeof(pre));
memset(inque,0,sizeof(inque));
while(m--)
{
cin>>x>>y>>z;
u[y].push_back({x,z});
}
spfa();
cout<<dis[1]<<endl;
int k=1;
while(k!=n)
{
cout<<k<<" "<<pre[k]<<endl;
k=pre[k];
}
}
return 0;
}