差分约束系统。
求最小值,用最长路来解决。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; const int maxn=50010; const int INF=0x7fffffff; struct abc { int startt; int endd; int costt; } node[4*maxn]; vector<abc>ljb[maxn]; int tott,n,zd,zx; int dist[maxn],ff[maxn],summ[maxn]; void SPFA() { queue<int>Q; while(!Q.empty()) Q.pop(); int i; for(i=zx; i<=zd+1; i++) dist[i]=-INF; memset(ff,0,sizeof(ff)); memset(summ,0,sizeof(summ)); dist[zx]=0; ff[zx]=1; Q.push(zx); while(!Q.empty()) { int hh=Q.front(); Q.pop(); summ[hh]++; ff[hh]=0; for(i=0; i<ljb[hh].size(); i++) { abc noww; noww=ljb[hh][i]; if(dist[hh]+noww.costt>dist[noww.endd]) { dist[noww.endd]=dist[hh]+noww.costt; if(ff[noww.endd]==0) { ff[noww.endd]=1; Q.push(noww.endd); } } } } } int main() { int i,u,v,c; while(~scanf("%d",&n)) { for(i=0; i<maxn; i++) ljb[i].clear(); zd=-INF; zx=INF; tott=1; for(i=0; i<n; i++) { scanf("%d%d%d",&u,&v,&c); if(v>zd) zd=v; if(u<zx) zx=u; node[tott].startt=u; node[tott].endd=v+1; node[tott].costt=c; ljb[u].push_back(node[tott]); tott++; } for(i=zx; i<=zd; i++) { node[tott].startt=i+1; node[tott].endd=i; node[tott].costt=-1; ljb[i+1].push_back(node[tott]); tott++; node[tott].startt=i; node[tott].endd=i+1; node[tott].costt=0; ljb[i].push_back(node[tott]); tott++; } SPFA(); printf("%d ",dist[zd+1]-dist[zx]); } return 0; }