洛谷 P1250 种树 题解

差分约束系统,维护前缀和,根据式子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 }
请各位大佬斧正(反正我不认识斧正是什么意思)
原文地址:https://www.cnblogs.com/handsome-zyc/p/11237644.html