1. 程式人生 > >POJ 1201 差分約束+SPFA

POJ 1201 差分約束+SPFA

思路:
差分約束,難在建圖。(我是不會告訴你我剛學會SPFA的。。。)

把每個區間的ai–>bi連一條長度為ci的邊。
k–>k+1連一條長度為0的邊。
k+1–>k連一條長度為-1的邊。
求最長路即可。

// by SiriusRen
#include <queue>
#include <cstdio>
#include <algorithm>
#define N 55555
using namespace std;
int w[N*3],v[N*3],first[N],next[N*3],tot=2;
int n,xx,yy,zz,minn=N,maxx=0
,d[N]; bool vis[N]; queue<int>q; void add(int x,int y,int z){ w[tot]=z,v[tot]=y; next[tot]=first[x];first[x]=tot++; } void spfa(int x){ vis[x]=1,d[x]=0,q.push(x); while(!q.empty()){ int temp=q.front();q.pop(),vis[temp]=0; for(int i=first[temp];i;i=next[i]) if
(d[temp]+w[i]>d[v[i]]){ d[v[i]]=d[temp]+w[i]; if(!vis[v[i]])q.push(v[i]),vis[v[i]]=1; } } } int main(){ scanf("%d",&n); while(n--)scanf("%d%d%d",&xx,&yy,&zz),add(xx,yy+1,zz),minn=min(minn,xx),maxx=max(maxx,yy+1); for(int i=minn;i<maxx;i++)add(i,i+1
,0),add(i+1,i,-1); spfa(minn); printf("%d\n",d[maxx]); }