poj 1201 Intervals【差分約束+spfa】
阿新 • • 發佈:2018-08-05
相反數 ons 最長 using cpp val 註意 interval space
設s為前綴和,首先顯然的條件是\[ s_{bi}-s_{ai-1}>=c \],然後隱含的是\[ s_i-s_{i-1}>=0 s_i-s_{i-1}<=1 \]
然後根據差分約束,就是連邊(bi,ai-1,-li),(i-1,i,1),(i,i-1,0)
spfa跑最長路最後輸出相反數即可,註意n是起點,min是終點,跑最短路(不會有負環)
#include<iostream> #include<cstdio> #include<queue> using namespace std; const int N=500005,inf=1e9; int n,s=inf,m,h[N],cnt,dis[N]; bool v[N]; struct qwe { int ne,to,va; }e[N]; int read() { int r=0,f=1; char p=getchar(); while(p>‘9‘||p<‘0‘) { if(p==‘-‘) f=-1; p=getchar(); } while(p>=‘0‘&&p<=‘9‘) { r=r*10+p-48; p=getchar(); } return r*f; } void add(int u,int v,int w) {//if(w>0)cerr<<u<<" "<<v<<" "<<w<<endl; cnt++; e[cnt].ne=h[u]; e[cnt].to=v; e[cnt].va=w; h[u]=cnt; } int main() { m=read(); for(int i=1;i<=m;i++) { int x=read()+2,y=read()+2,z=read(); add(y,x-1,-z); n=max(n,y),s=min(s,x-1); } for(int i=s+1;i<=n;i++) add(i-1,i,1),add(i,i-1,0); queue<int>q; for(int i=s;i<=n;i++) dis[i]=inf; q.push(n),v[n]=1,dis[n]=0; while(!q.empty()) { int u=q.front();//cerr<<u<<" "<<dis[u]<<endl; q.pop(); v[u]=0; for(int i=h[u];i;i=e[i].ne) if(dis[e[i].to]>dis[u]+e[i].va) { dis[e[i].to]=dis[u]+e[i].va;//cerr<<e[i].to<<" "<<e[i].va<<" "<<dis[e[i].to]<<endl; if(!v[e[i].to]) { v[e[i].to]=1; q.push(e[i].to); } } } printf("%d\n",-dis[s]); return 0; }
poj 1201 Intervals【差分約束+spfa】