差分约束系统,维护前缀和,根据式子d[ b ] < = d[ e + 1 ] - t,可以看出要连e和b - 1,但占用了超级源点0,所以要把区间向后移,这样就可以用超级源点0来保持图的连通性(也可
以用n + 1作为超级源点,就不用了后移了)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #define INF 2139062143 7 #define maxnn 50010 8 #define maxm 301000 9 using namespace std; 10 int n,m,maxnum=-1,minnum=INF; 11 struct node 12 { 13 int u,v,w,nex; 14 }edge[maxm]; 15 int head[maxnn],cnt=0; 16 int dis[maxnn]; 17 bool vis[maxnn]; 18 inline int read() 19 { 20 int x=0; 21 bool f=1; 22 char c=getchar(); 23 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 24 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 25 if(f) return x; 26 return 0-x; 27 } 28 inline void add(int x,int y,int z) 29 { 30 cnt++; 31 edge[cnt].u=x; 32 edge[cnt].v=y; 33 edge[cnt].w=z; 34 edge[cnt].nex=head[x]; 35 head[x]=cnt; 36 } 37 inline void spfa(int s) 38 { 39 memset(dis,127,sizeof(dis)); 40 queue<int> q; 41 q.push(s); 42 vis[s]=1;dis[s]=0; 43 while(!q.empty()) 44 { 45 int now=q.front(); 46 q.pop(); 47 vis[now]=0; 48 for(int i=head[now];i!=-1;i=edge[i].nex) 49 { 50 int to=edge[i].v; 51 if(dis[now]+edge[i].w<dis[to]) 52 { 53 dis[to]=dis[now]+edge[i].w; 54 if(!vis[to]) 55 { 56 vis[to]=1; 57 q.push(to); 58 } 59 } 60 } 61 } 62 } 63 int main() 64 { 65 int maxn=-1; 66 memset(head,-1,sizeof(head)); 67 n=read();m=read(); 68 n++; 69 for(int i=1;i<=m;i++) 70 { 71 int b,e,t; 72 b=read();e=read();t=read(); 73 b++;e++; 74 add(e,b-1,-t); //d[b]<=d[e+1]-t 75 maxn=max(maxn,e); 76 } 77 for(int i=2;i<=maxn;i++) 78 { 79 add(i-1,i,1);//d[i]<=d[i-1]+1 80 add(i,i-1,0);//d[i-1]<=d[i] 81 } 82 for(int i=1;i<=maxn;i++)add(0,i,0); 83 spfa(0); 84 int minn=INF; 85 for(int i=1;i<=n;i++)minn=min(minn,dis[i]); 86 printf("%d",dis[maxn]-minn); 87 return 0; 88 }
请各位大佬斧正(反正我不认识斧正是什么意思)