再卖菜
csp2018.9第4题
用差分约束求差的最小值,然后有一些转化,比如前缀和
换成>=,跑最长路
a1*2≤x1+x2≤a1*2+1
d[2]-d[0]>=a1*2
d[0]-d[2]>=-a1*2-1
a2*3<=x1+x2+x3<=a2*3+2
.
.
.
an-1*2<=xn-1+xn<=an*2+1
x1>=1
x2>=1
x3>=1
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<set> #include<map> #include<stack> #include<cstring> #define inf 2147483647 #define ls rt<<1 #define rs rt<<1|1 #define lson ls,nl,mid,l,r #define rson rs,mid+1,nr,l,r #define N 100010 #define For(i,a,b) for(int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() using namespace std; int n ,a[310],d[310],x; queue<int>q; bool vis[1000010]; struct node{ int v; int n; node *next; }*e[100010]; void in(int &x){ int y=1; char c=g();x=0; while(c<'0'||c>'9'){ if(c=='-')y=-1; c=g(); } while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=g(); } x*=y; } void o(int x){ if(x<0){ p('-'); x=-x; } if(x>9)o(x/10); p(x%10+'0'); } void push(int x,int y,int v){ node *p; p=new node(); p->n=y; p->v=v; if(e[x]==NULL) e[x]=p; else{ p->next=e[x]->next; e[x]->next=p; } } void spfa(){ For(i,1,n)d[i]=-6876868; q.push(0); while(q.size()>0){ x=q.front(); vis[x]=true; for(node *i=e[x];i!=NULL;i=i->next) if(d[i->n]<d[x]+i->v){ d[i->n]=d[x]+i->v; if(!vis[i->n]){ q.push(i->n); vis[i->n]=true; } } vis[x]=false; q.pop(); } } int main(){ in(n); For(i,1,n)in(a[i]); push(0,2,a[1]*2); push(2,0,-a[1]*2-1); push(n-2,n,a[n]*2); push(n,n-2,-a[n]*2-1); For(i,2,n-1){ push(i+1,i-2,-a[i]*3-2); push(i-2,i+1,a[i]*3); } For(i,1,n) push(i-1,i,1); spfa(); For(i,1,n){ o(d[i]-d[i-1]);p(' '); } return 0; }