题目大意:现有n个点,每个结点有一个权值v,给出关于这些点的m条信息,每条信息(i j k)指出v[i]-v[j]>=k,最后求的是在满足以上约束条件的情况下,v[1]-v[n]的最大值是多少?(N and M not exceeding 30 000 and 150 000 respectively)
分析:可以根据题意直接建立差分约束系统,然后以1为源点用spfa求最短路。
问题:用队列TLE了,看了discuss后改为stack就A了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <string.h> #include <stack> using namespace std; #define N 30010 #define M 150100 #define INF 0x3fffffff int n,m,e; int d[N],inq[N]; int first[N],next[M],v[M],w[M]; void init() { e=0; memset(first,-1,sizeof(int)*(n+5)); } void insert(int a,int b,int c) { v[e]=b; w[e]=c; next[e]=first[a]; first[a]=e++; } void spfa() { stack<int> q; int a,b; memset(inq,0,sizeof(int)*(n+5)); for(int i=1;i<=n;i++) d[i]=INF; d[1]=0; inq[1]=1; q.push(1); while(!q.empty()) { a=q.top(),q.pop(); inq[a]=0; for(int i=first[a];i!=-1;i=next[i]) { b=v[i]; if(d[b]>d[a]+w[i]) { d[b]=d[a]+w[i]; if(!inq[b]) inq[b]=1,q.push(b); } } } printf("%d\n",d[n]); } int main() { int a,b,c; scanf("%d%d",&n,&m); init(); while(m--) { scanf("%d%d%d",&a,&b,&c); insert(a,b,c); } spfa(); return 0; }