StkOvflow

STACK OVERFLOW!

一言(ヒトコト)

即得易见平凡,由上自证显然,留作习题答案略,读者自证不难。
反之亦然同理,推论自然成立,略去过程Q.E.D,由上可知证毕。
——lca

AcWing1170. 排队布局[USACO05]

解题思路

这题也是一个比较裸的差分约束:多了的那个输出2的其实就是在差分约束系统中1号点和n号点没有约束关系,也就是1n号不连通。由于这里要求最大距离,所以我们在系统中应该跑最短路

从题目中我们可以看出这样几条约束关系
xi+1xixixi+1+0 :因为后面的牛的位置一定不能比前面的靠前。

ML条的关系中 xbxaLxbxa+L:距离不大于L

MD条的关系中 xbxaDxaxbDxaxbD:距离不小于D

然后又没有一个源点可以遍历所有边,所以我们还是建立超级源点0让它和所有点连边权0的边。
整理关系得到
{xixi+1+0,xbxa+L,xaxbD,xix0+0.

代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010, M = 21010, INF = 0x3f3f3f3f;
int h[N], e[M], w[M], ne[M], idx;
int dist[N], cnt[N], q[N], st[N];
int hh, tt(1), md, ml, n, ring;

void add(int a, int b, int c) 
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}

void spfa(int S) 
{
    memset(dist, 0x3f, sizeof dist);
    memset(st, 0, sizeof st);
    memset(cnt, 0, sizeof cnt);
    
    q[tt ++ ] = S, st[S] = 1, dist[S] = 0;
    
    while (hh != tt) 
    {
        int t = q[hh ++ ];
        if (hh == N) hh = 0;
        st[t] = 0;
        
        for (int i = h[t]; ~i; i = ne[i]) 
        {
            int j = e[i];
            if (dist[j] > dist[t] + w[i]) 
            {
                dist[j] = dist[t] + w[i];
                cnt[j] = cnt[t] + 1;
                if (cnt[j] >= n) return void (ring = true);
                if (!st[j]) 
                {
                    st[j] = true ;
                    q[tt ++ ] = j;
                    if (tt == N) tt = 0;
                }
            }
        }
    }
    
    return void (ring = false);
}

int main() 
{
    scanf("%d%d%d", &n, &ml, &md);
    
    memset(h, -1, sizeof h);
    while (ml -- ) 
    {
        int a, b, l;
        scanf("%d%d%d", &a, &b, &l);
        if (a > b) swap(a, b);
        add(a, b, l);
    }
    
    while (md -- )
    {
        int a, b, d;
        scanf("%d%d%d", &a, &b, &d);
        if (a > b) swap(a, b);
        add(b, a, -d);
    }
    
    for (int i = 1; i < n; i ++ ) 
        add(i + 1, i, 0), add(0, i, 0);
    add(0, n, 0);
    
    spfa(0);
    if (ring) puts("-1");
    else {
        spfa(1);
        printf("%d\n", dist[n] == INF ? -2 : dist[n]);
    }
    
    return 0;
}
posted @   StkOvflow  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示