传送门
最近在学差分约束,看到这题就想到了差分约束
利用前缀和,就可以将问题转化为差分约束
由题可得三个不等式
由于题目求的是 的最小值,所以就将不等式转化为 的形式,从 到 建一条权值为 的边,建完图跑SPFA求最长路就行了。
由于忘记了第二个不等式(其实都想到了,写的时候又忘了),并且忘了初始化,WA了好久QAQ
并且大概是由于我写的vector吧,在codevs上是能过,XJOI上就T了,反面教材.JPG
等我改天有空再写写链表的吧,毕竟不会写好像还是不行的啊。
又:这是我有史以来写过最丑的blog
#include<bits/stdc++.h>
using namespace std;
const int N=500111;
int n,m,h[N],t,w,b[N];
long long dis[N];
vector<int> a[N],v[N];
void read(int &x){
char ch=getchar();x=0;
for(;ch<'0'||ch>'9';ch=getchar());
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
}
void spfa(){
t=w=1;h[w]=0;b[0]=1;
for(int i=1;i<=n;i++) dis[i]=-0x3f3f3f3f;
while(t!=(w+1)%N){
int x=h[t];
for(int i=0;i<a[x].size();i++)
if (dis[x]+v[x][i]>dis[a[x][i]]){
dis[a[x][i]]=dis[x]+v[x][i];
if (!b[a[x][i]]){
w=(w+1)%N;
h[w]=a[x][i];
b[a[x][i]]=1;
}
}
b[x]=0;
t=(t+1)%N;
}
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;i++){
int k;read(k);
a[i].push_back(i-1);v[i].push_back(-k);
a[i-1].push_back(i);v[i-1].push_back(0);
}
for(int i=1;i<=m;i++){
int x,y,z;
read(x);read(y);read(z);
a[x-1].push_back(y);v[x-1].push_back(z);
}
spfa();
printf("%lld",dis[n]);
return 0;
}