zoukankan      html  css  js  c++  java
  • Bzoj1731 排队布局

    当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些。FJ 有 N 头奶牛,编号从 1 到 N,沿一条直线站着等候喂食。奶牛排在队伍中的顺序和它们的编号是相同的。因为奶牛相当苗条,所以可能有两头或者更多奶牛站在同一位置上。即使说,如果我们想象奶牛是站在一条数轴上的话,允许有两头或更多奶牛拥有相同的横坐标。一些奶牛相互间存有好感,它们希望两者之间的距离不超过一个给定的数 L。另一方面,一些奶牛相互间非常反感,它们希望两者间的距离不小于一个给定的数 D。
    给出 ML条关于两头奶牛间有好感的描述,再给出 MD条关于两头奶牛间存有反感的描述。你的工作是:如果不存在满足要求的方案,输出 −1;如果 1 号奶牛和 N号奶牛间的距离可以任意大,输出 −2;否则,计算出在满足所有要求的情况下,1 号奶牛和 N 号奶牛间可能的最大距离。


    很显然,我们对于两个要在一起的情况,相当于想这两个点之间添加一条长度相应的边,使得在没有更短路的时候可以走这条

    然后对于分开的则是添加一条负权边

    典型的差分约束

    特别的,相邻的两个牛之间之间添加一条距离为0的边

    下面给出代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cmath>
    using namespace std;
    inline int rd(){
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    inline void write(int x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
        return ;
    }
    int n,m1,m2;
    int head[100006],nxt[100006],to[100006];
    int v[100006];
    int total=0;
    void add(int x,int y,int z){
        total++;
        to[total]=y;
        v[total]=z;
        nxt[total]=head[x];
        head[x]=total;
        return ;
    }
    int q[100006];
    int l=0,r=0;
    int book[100006];
    int dis[100006];
    int cnt[100006];
    int f=0;
    void spfa(){
        memset(dis,127,sizeof(dis));
        dis[1]=0;
        book[1]=1;
        q[++r]=1;
        while(l<r){
            int x=q[++l];
            book[x]=0;
            for(int e=head[x];e;e=nxt[e]){
                if(dis[to[e]]>dis[x]+v[e]){
                    dis[to[e]]=dis[x]+v[e];
                    cnt[x]++;
                    if(cnt[x]==n){
                        f=1;
                        return ;
                    }
                    if(!book[to[e]]){
                        book[to[e]]=1;
                        q[++r]=to[e];
                    }
                }
            }
        }
        return ;
    }
    int main(){
        n=rd(),m1=rd(),m2=rd();
        for(int i=1;i<=m1;i++){
            int x=rd(),y=rd(),z=rd();
            add(x,y,z);
        }
        for(int i=1;i<=m2;i++){
            int x=rd(),y=rd(),z=rd();
            add(y,x,-z);
        }
        for(int i=2;i<=n;i++) add(i,i-1,0);
        spfa();
        if(f) printf("-1");
        else if(dis[n]==2139062143) printf("-2");
        else write(dis[n]);
        return 0;
    }
  • 相关阅读:
    Git Stash用法
    动态设置ImageView的宽高以及位置
    【算法笔记】B1047 编程团体赛
    【算法笔记】B1043 输出PATest
    【算法笔记】B1042 字符统计
    【算法笔记】B1039 到底买不买
    【算法笔记】B1038 统计同成绩学生
    【算法笔记】B1033 旧键盘打字
    【算法笔记】B1029 旧键盘
    【算法笔记】B1048 数字加密
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9861393.html
Copyright © 2011-2022 走看看