POJ3169 差分约束系统(+SPFA)

大意:
n头牛编号为1到n,按照编号的顺序排成一列,每两头牛的之间的距离 >= 0。这些牛的距离存在着一些约束关系:1.有ml组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 <= w。2.有md组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 >= w。问如果这n头无法排成队伍,则输出-1,如果牛[1]和牛[n]的距离可以无限远,则输出-2,否则则输出牛[1]和牛[n]之间的最大距离。

我们假设(u)<(v)。
对u,v做ml处理时,题目有dis[v]-dis[u]<=w;
即dis[u]+w>=dis[v],所以这里要从u到v建一条长度为w的边。

对u,v做md处理时,题目有dis[v]-dis[u]>=w;
即dis[v]+(-w)>=dis[u],所以这里要从v到u建一条长度为-w的边。

然后求最短路即可。

特殊情况:
负环存在时取最小值会导致一个点必须要在自己前面,但那是不可能的事(输出-1)。
当dis[n]没有改变时说明1和n没有联系,即可以无穷大(输出-2)。

我的代码比较凌乱,不是很方便看懂。
(不是很理解我即便很浪费空间也不至于多花别人十几倍啊)

/*
    memory:4088k
    time:32ms
*/
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1010
int n,ml,md,w[N][N];
int dis[N],cnt[N],que[N];
bool in[N];

inline void uni(int x) {
    int a,b,dis;
    scanf("%d%d%d",&a,&b,&dis);
    if((a>b)^(x==-1)) a^=b^=a^=b;
    w[a][b]=dis*x;
}

int spfa() {
    int hd=1,tl=1;
    que[hd]=1;
    dis[1]=0;
    while(hd<=tl) {
        int x=que[hd++%N];
        in[x]=0;
        for(int i=1; i<=n; i++) {
            int len=dis[x]+w[x][i];
            if(w[x][i]&&len<dis[i]) {
                dis[i]=len;
                if(!in[i]) {
                    in[i]=1;
                    que[++tl%N]=i;
                    if(++cnt[i]>=n) return -1;
                }
            }
        }
    }
    if(dis[n]==522133279) return -2;
    return dis[n];
}

int main() {
    memset(dis,31,sizeof(dis));//522133279
    scanf("%d%d%d",&n,&ml,&md);
    while(ml--) uni(1);
    while(md--) uni(-1);
    printf("%d",spfa());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值