ccf201809-4 发表于 2018-12-14 | 分类于 题解 | 阅读数 次 链接:ccf201809-4 题解 简单的差分约束,给出的是形如,前缀和一下就是简单的差分约束 求最小字典序即前缀和最小,求最长路即可。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051#include<bits/stdc++.h>#define rep(i,x,y) for(register int i=x;i<=y;++i)#define repd(i,x,y) for(register int i=x;i>=y;--i)#define ll long longusing namespace std;const int N=1e5+7;const int inf=0x3f3f3f3f;template<typename T>inline void read(T &x){ char c;int sign=1;x=0; do{c=getchar();if(c=='-')sign=-1;}while(c<'0'||c>'9'); do{x=x*10+c-'0';c=getchar();}while(c>='0'&&c<='9'); x*=sign;}int dis[N],nxt[N],w[N],to[N],head[N],inq[N],cnt,n;inline void adde(int a,int b,int c){ w[++cnt]=c; to[cnt]=b; nxt[cnt]=head[a]; head[a]=cnt;}inline void init(){ read(n); rep(i,1,n){ int x;read(x); if(i==1){adde(i+1,i-1,-2*x-1);adde(i-1,i+1,2*x);} else if(i==n){adde(i,i-2,-2*x-1);adde(i-2,i,2*x);} else{adde(i+1,i-2,-3*x-2);adde(i-2,i+1,3*x);} adde(i-1,i,1); }}queue<int>q;void spfa(){ memset(dis,0,sizeof dis); q.push(0); inq[0]++;dis[0]=0; while(!q.empty()){ int k=q.front();q.pop(); inq[k]--; for(int i=head[k],v;i;i=nxt[i]){ if(dis[v=to[i]]>=dis[k]+w[i])continue; dis[v]=dis[k]+w[i]; if(!inq[v]){q.push(v);inq[v]++;} } }}int main(){ init(); spfa(); rep(i,1,n)printf("%d%c",dis[i]-dis[i-1],i==n?'\n':' '); return 0;}