差分约束。。spfa求最长路
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
const int maxn = 50010;
const int inf = 0xffffff;
struct Edge{
int u,v,w;
}e[maxn*4];
int d[maxn],next[maxn*4],first[maxn];
bool inq[maxn];
using namespace std;
int main()
{
int n,i,j,max,min,cnt=0;
while(scanf("%d",&n)!=EOF){
max=0;
min=inf;
memset(first,-1,sizeof(first));
for(i=0;i<n;i++){ //可以设计一个函数用来建立邻接表,减少代码量
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
e[i].v++;
if(min>e[i].u)
min=e[i].u;
if(max<e[i].v)
max=e[i].v;
next[i]=first[e[i].u];
first[e[i].u]=i;
}
for(i=min,j=n;i<=max;j++,i++){
e[j].u=i-1;
e[j].v=i;
e[j].w=0;
next[j]=first[e[j].u];
first[e[j].u]=j;
}
for(i=min;i<=max;j++,i++){
e[j].u=i;
e[j].v=i-1;
e[j].w=-1;
next[j]=first[e[j].u];
first[e[j].u]=j;
}
queue<int> q;
memset(inq,false,sizeof(inq));
for(i=min;i<=max;i++) d[i]=-maxn;
d[min]=0;
q.push(min);
inq[min]=true;
while(!q.empty()){
int x=q.front();
q.pop();
inq[x]=false;
for(i=first[x];i!=-1;i=next[i]){
if(d[e[i].v]<d[x]+e[i].w){
d[e[i].v]=d[x]+e[i].w;
if(!inq[e[i].v]){
inq[e[i].v]=true;
q.push(e[i].v);
}
}
}
}
printf("%d\n",d[max]);
}
return 0;
}