根据题意得出约束条件:
s[bi]-s[ai-1] >= ci
变形可得 s[ai-1] -s[bi]<= - ci
这是显然的。
另外不要忘了对于一个连续的整数集合,它包含隐性条件
0<=s[i]-s[i-1] <= 1
综上可得:
①s[ai-1]-s[bi] <= -ci
②s[i]-s[i-1] <= 1
③s[i-1]-s[i] <= 0
最后转化为最短路问题
/*
qq:1239198605
ctgu_yyf
*/
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 999999
#define ll long long
using namespace std;
struct Edge{
int s,t,w;
};
Edge edge[50002];
int dis[50002],ma,mi,n;
void bellman()
{
bool flag=true;
while(flag)
{
flag=false;
//因为要维持 一个差分约束系统 对于一个连续的集合 所以应该满足的条件有
//1 s[bi]-s[ai-1]>=w
//2 0<=s[i]-s[i-1]<=1
for(int i=1;i<=n;i++)
if(dis[edge[i].t]>dis[edge[i].s]-edge[i].w)
{
dis[edge[i].t]=dis[edge[i].s]-edge[i].w;
flag=true;
}
//隐性条件判定
for(int i=mi;i<=ma;i++)
if(dis[i]-dis[i-1]>1)
{
dis[i]=dis[i-1]+1;
flag=true;
}
for(int i=ma;i>=mi;i--)
if(dis[i-1]>dis[i])
{
dis[i-1]=dis[i];
flag=true;
}
}
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n)
{
ma=-1;
mi=inf;
for(int i=1;i<=n;i++)
{
cin>>edge[i].t>>edge[i].s>>edge[i].w;
ma=max(ma,edge[i].s);
mi=min(mi,edge[i].t);
edge[i].t--;
}
for(int i=0;i<=ma;i++)
dis[i]=0;
bellman();
cout<<dis[ma]-dis[mi-1]<<endl;
}
return 0;
}
第一个式子在代码中化简得到的是dis[edge[i].t]<=dis[edge[i].s]-edge[i].w
因为要时刻满足这个条件 所以当他不满足的时候 需要更新它
用if(dis[edge[i].t]>dis[edge[i].s]-edge[i].w)
来判断 大于就让它取等
下面同理。