差分约束+spfa【模板】
相比dij,spfa优点是可处理含负边不含负圈的最短路问题,缺点是算法复杂度不太好【貌似可以使用两种优化。LLL和SLF】
差分约束就是将一些不等式转化为图中的带权边,然后求解最短路或最长路的方法
洛谷P1645https://www.luogu.org/problemnew/show/P1645
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct pot{ 4 int to; 5 int next; 6 int len; 7 }edge[5018]; 8 queue<int>pq; 9 int vis[1005]; 10 int next[1005]; 11 int dist[1005]; 12 void add(int x,int y,int z,int t){ 13 edge[t].len=z; 14 edge[t].next=next[x]; 15 edge[t].to=y; 16 next[x]=t; 17 } 18 void spfa(int x) 19 { 20 while(!pq.empty())pq.pop(); 21 dist[x]=0; 22 vis[x]=true; 23 pq.push(x); 24 while(!pq.empty()){ 25 int u=pq.front(); 26 pq.pop(); 27 vis[u]=false; 28 for(int i = next[u]; i != -1 ; i=edge[i].next) 29 { 30 int w=edge[i].to; 31 if(dist[w]<dist[u]+edge[i].len) 32 { 33 dist[w]=dist[u]+edge[i].len; 34 if(!vis[w]){ 35 vis[w]=true; 36 pq.push(w); 37 } 38 } 39 } 40 } 41 } 42 int main() 43 { 44 int n; 45 scanf("%d",&n); 46 int tot=0; 47 int mmax=0; 48 int mmin=1005; 49 memset(dist,-1,sizeof(dist)); 50 memset(next,-1,sizeof(next)); 51 memset(vis,0,sizeof(vis)); 52 for(int i = 0 ; i < n ; i++) 53 { 54 int a,b,c; 55 scanf("%d%d%d",&a,&b,&c); 56 add(a-1,b,c,tot); 57 if(a<mmin)mmin=a; 58 if(mmax<b)mmax=b; 59 tot++; 60 } 61 for(int i = mmin ; i <= mmax ; i++) 62 { 63 add(i-1,i,0,tot); 64 tot++; 65 add(i,i-1,-1,tot); 66 tot++; 67 } 68 spfa(mmin-1); 69 cout << dist[mmax]<<endl; 70 return 0; 71 }