和POJ1716、POJ1201一样,用差分约束系统解,此题是求最大值,所以求最短路,则需要增设一个源结点,因为是求1号结点和n号结点的最大差值,不妨就以1号结点为源节点进行求最短路径(差值越大越好,所以可以假设1号得到0,求n号的最小值就可以)。此外,此题如果用SPFA+队列会超时,用SPFA+栈可以通过,时间500ms,这可能与给的数据和队列的先进先出、栈的后进先出特点有关。
#include <iostream>
#include <cstdio>
#include <cstring>
#define inf 100000000
using namespace std;
const int maxn=30010;
const int maxm=150010;
bool visit[maxn];
int num,head[maxn],dist[maxn],stack[maxn];
struct Edge
{
int t;
int w;
int next;
}edge[10*maxm];
void addEdge(int s,int t,int w)
{
edge[num].t=t;
edge[num].w=w;
edge[num].next=head[s];
head[s]=num++;
}
void SPFA()
{
int i,u,v,id,top;
top=0;
visit[1]=true;
dist[1]=0;
stack[top++]=1;
while(top>0)
{
u=stack[--top];
id=head[u];
visit[u]=false;
while(id!=-1)
{
v=edge[id].t;
if(dist[v]==inf || dist[u]+edge[id].w<dist[v])
{
dist[v]=dist[u]+edge[id].w;
if(!visit[v])
{
visit[v]=true;
stack[top++]=v;
}
}
id=edge[id].next;
}
}
}
int main()
{
int i,n,m,a,b,c;
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
num=0;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
addEdge(a,b,c);
}
memset(visit,0,sizeof(visit));
for(i=1;i<=n;i++)
dist[i]=inf;
SPFA();
printf("%d\n",dist[n]-dist[1]);
return 0;
}