差分约束——再卖菜

再卖菜

问题描述
  在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜。
  第一天,每个商店都自己定了一个价格。店主们希望自己的菜价和其他商店的一致,第二天,每一家商店都会根据他自己和相邻商店的价格调整自己的价格。具体的,每家商店都会将第二天的菜价设置为自己和相邻商店第一天菜价的平均值(用去尾法取整)。
  注意,编号为1的商店只有一个相邻的商店2,编号为n的商店只有一个相邻的商店n-1,其他编号为i的商店有两个相邻的商店i-1和i+1。
  给定第一天各个商店的菜价,请计算第二天每个商店的菜价。
输入格式
  输入的第一行包含一个整数n,表示商店的数量。
  第二行包含n个整数,依次表示每个商店第一天的菜价。
输出格式
  输出一行,包含n个正整数,依次表示每个商店第二天的菜价。
样例输入
8
4 1 3 1 6 5 17 9
样例输出
2 2 1 3 4 9 10 13
数据规模和约定
  对于所有评测用例,2 ≤ n ≤ 1000,第一天每个商店的菜价为不超过10000的正整数。

题解:

在这里插入图片描述
字典序最小就是提醒我们求最长路。然后把方程式都写成大于等于的样子。最后确定一个绝对大小并检查是否能从起点到所有的点。最后跑一下图就可以了。

#include <bits/stdc++.h>
using namespace std;
const int N=1000;
int ne[N],head[N],w[N],cnt,e[N];
int a[N],dis[N],vis[N],con[N],n;
void add(int a,int b,int c)
{
    w[cnt]=c,e[cnt]=b,ne[cnt]=head[a],head[a]=cnt++;
}
void spfa()
{
    memset(dis,-0x3f3f3f3f,sizeof dis);
    queue<int> q;
    q.push(0);
    vis[0]=1;
    dis[0]=0;
    while (!q.empty()){
        int u=q.front(); q.pop();
        vis[u]=0;
        for(int i=head[u];~i;i=ne[i]){
            int j=e[i];
            con[j]=con[u]+1;
            if(con[j]>=n) break;
            if(dis[j]<=dis[u]+w[i]){
                dis[j]=w[i]+dis[u];
                if(!vis[j]) {
                    q.push(j);
                    vis[j]=1;
                }
            }
        }
    }
}
int main()
{
    memset(head,-1,sizeof head);
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    add(0,2,2*a[1]);
    add(2,0,-(2*a[1]+1));
    for(int i=2;i<n;i++){
        add(i-2,i+1,3*a[i]);
        add(i+1,i-2,-(3*a[i]+2));
    }
    add(n-2,n,2*a[n]);
    add(n,n-2,-(2*a[n]+1));
    for(int i=1;i<=n;i++) add(i-1,i,1);
    spfa();
    for(int i=1;i<=n;i++) cout<<dis[i]-dis[i-1]<<' ';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值