標籤:最短路 spfa
差分約束
題意倒是簡單,難的是建立約束(建邊)。可以初始化INF求最小,然後輸出-dis[maxn]。也可以初始化-INF求最大,輸出dis[maxn]。
求最大的時候:
minn為最小,maxn為最大。
輸入 u ,v len 建立約束為 u->v = len,最後在 minn和maxn之間還要建立 i->i-1=-1 , i-1->i=0。
最後求minn-1 ~maxn 的最大距離。
求最小就是 建邊不變,距離變負。
#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<cmath>#define INF 0x7fffffff#define eps 1e-6#define LL long longusing namespace std;int n,maxn,minn,m;struct lx{ int v,len;};vector<lx>g[51001];queue<int>q;void SPFA(){ bool vis[51001]; int dis[51001]; for(int i=0;i<=maxn;i++) vis[i]=0,dis[i]=-INF; vis[minn-1]=1,dis[minn-1]=0; q.push(minn-1); while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0; for(int j=0;j<g[u].size();j++) { int v=g[u][j].v; int len=g[u][j].len;// printf("v=%d,u=%d:%d>%d+%d=\n",v,u,dis[v],dis[u],len);// system("pause"); if(dis[v]<dis[u]+len) { dis[v]=dis[u]+len; if(!vis[v]) { vis[v]=1; q.push(v); } } } } printf("%d\n",dis[maxn]);// for(int i=minn-1;i<=maxn;i++)// printf("%d : %d ==\n",i,dis[i]);}int main(){ while(scanf("%d",&m)!=EOF) { minn=INF,maxn=0; for(int i=0;i<51001;i++) g[i].clear(); int u,v,len; lx now; while(m--) { scanf("%d%d%d",&u,&v,&len); maxn=max(maxn,v); minn=min(minn,u); now.v=v,now.len=len; g[u-1].push_back(now); } for(int i=minn;i<=maxn;i++) { now.v=i-1,now.len=-1; g[i].push_back(now); now.v=i,now.len=0; g[i-1].push_back(now); }// for(int i=minn-1;i<=maxn;i++)// {// printf("%d-> ",i);// for(int j=0;j<g[i].size();j++)// printf("%d:%d ",g[i][j].v,g[i][j].len);// printf("\n");// } while(!q.empty())q.pop(); SPFA(); }}
POJ 1201 Intervals