百度了一下这道题,看到很多博客写的都是根据差分约束,然后直接摆出三个条件,然后开始构图。
但是其实我觉得差分约束的题的难点不是写代码的过程,而是你看到题目的时候,能想到将其抽象为差分约束系统问题的过程。
这道题目如果能想到抽象成差分系统后,写代码的过程不是很难。
这次是第一次写这种题目,所以即使是看了别人的博客,也看了好久。
我觉得这篇博客写得很好,帮助我很好地理解了,这道题。
我基本上是模仿他的写法,然后自己写了一遍。直接献上代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <queue> 4 5 using namespace std; 6 7 struct edge 8 { 9 int t; 10 int value; 11 int next; 12 }line[200000]; 13 int head[50002]={0},N=1,l=50001,r=0;//head表示每个点所连接的第一条边,r表示最右端的点,l表示最左端的点,N表示即将添加的边号 14 int dist[50002]={0};//记录从最左端的点到最右端的点的距离 15 queue<int> q;//用于spfa的队列 16 int flag[50002]={0}; 17 18 void add(int s,int t,int v) 19 { 20 line[N].t = t; 21 line[N].value = v; 22 line[N].next = head[s]; 23 head[s] = N; 24 N++; 25 } 26 27 void spfa() 28 { 29 while(!q.empty()) 30 { 31 int x = q.front(); 32 q.pop(); 33 flag[x] = 0; 34 int next = head[x]; 35 while(next!=0) 36 { 37 int t = line[next].t; 38 int v = line[next].value; 39 if(dist[t] < dist[x]+v) 40 { 41 dist[t] = dist[x]+v; 42 flag[t] = 1; 43 q.push(t); 44 } 45 next = line[next].next; 46 } 47 if(x+1<=r) 48 if(dist[x+1] < dist[x]) 49 { 50 dist[x+1] = dist[x]; 51 flag[x+1] = 1; 52 q.push(x+1); 53 } 54 if(x-1>=l) 55 if(dist[x-1] < dist[x]-1) 56 { 57 dist[x-1] = dist[x]-1; 58 flag[x-1] = 1; 59 q.push(x-1); 60 } 61 } 62 } 63 64 int main() 65 { 66 int n; 67 scanf("%d",&n); 68 while(n--) 69 { 70 int s,t,v; 71 scanf("%d %d %d",&s,&t,&v); 72 add(s,t+1,v); 73 q.push(s); 74 flag[s] = 1; 75 if(s<l) 76 l = s; 77 if(r<t+1) 78 r = t+1; 79 } 80 //q.push(l); 81 flag[l] = 1; 82 spfa(); 83 printf("%d ",dist[r]); 84 return 0; 85 }