• 排队布局


    【题目描述】:

    当排队等候喂食时,奶牛喜欢和它们的朋友靠近些。FJ 有N头奶牛,编号从1到N,沿一条直线站着等候喂食。奶牛排在队伍中的顺序和它们的编号是相同的。因为奶牛相当苗条,所以可能有两头或者更多奶牛站在同一位置上。如果我们想象奶牛是站在一条数轴上的话,允许有两头或更多奶牛拥有相同的横坐标。一些奶牛相互间存有好感,它们希望两者之间的距离不超过一个给定的数L。另一方面,一些奶牛相互间非常反感,它们希望两者间的距离不小于一个给定的数D。给出ML条关于两头奶牛间有好感的描述,再给出MD条关于两头奶牛间存有反感的描述。

    你的工作是:如果不存在满足要求的方案,输出-1;如果1号奶牛和N号奶牛间的距离可以任意大,输出-2;否则,计算出在满足所有要求的情况下,1号奶牛和N号奶牛间可能的最大距离。

    【输入描述】:

    第一行读人三个整数N,ML,MD。

    接下去ML行每行有三个正整数A,B,D(1<=A<B<=N),表示奶牛A和奶牛B至多相隔D的距离。

    接下去MD行每行有三个正整数A,B,D(1<=A<B<=N),表示奶牛A和奶牛B至少相隔D的距离。

    【输出描述】:

    如果不存在满足要求的方案,输出-1;如果1号奶牛和N号奶牛间的距离可以任意大,输出-2;否则,计算出在满足所有要求的情况下,1号奶牛和N号奶牛间可能的最大距离。

    【样例输入】:

    4 2 1
    1 3 10
    2 4 20
    2 3 3

    【样例输出】:

    27

    【样例说明】:

    四只牛分别在0,7,10,27。

    【时间限制、数据范围及描述】:

    时间:1s 空间:64M

    对于 30%的数据:2<=N<=50;1<=ML+MD<=300;

    对于 50%的数据:2<=N<=200;1<=ML+MD<=1000;

    对于100%的数据:2<=N<=1000;1<=ML+MD<=10,000;1<=L,D<=1,000,000

    分析:

    本题属于差分约束的模板题,只需要知道大概的思路即可,洛谷上应该恶意评分,不算很难吧。但是要从0开始判断是否无解。

    CODE:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int M=100005;
    const int inf=1<<20;
    int n,ml,md;
    int next[M],head[M],to[M],adj[M];
    int dis[M],ti[M];
    bool f[M];
    queue <int> q;
    inline int get(){
        int f=1;
        char c=getchar();
        int res=0;
        while (c<'0'||c>'9') {
            if (c=='-') f=-1;
            c=getchar();
        }
        while (c>='0'&&c<='9'){
            res=(res<<3)+(res<<1)+c-'0';
            c=getchar();
        }
        return res*f;
    }
    int tot;
    void add(int u,int v,int w){
        next[++tot]=head[u];
        head[u]=tot;
        adj[tot]=w;
        to[tot]=v;
        return ;
    }
    void spfa(int s){
        memset(ti,0,sizeof(ti));
        memset(f,false,sizeof(f));
        for (int i=1;i<=n;i++) dis[i]=inf;
        q.push(s);
        dis[s]=0;
        f[s]=true;
        int u;
        while (!q.empty()){
            u=q.front();
            q.pop();
            f[u]=false;
            for (int j=head[u];j;j=next[j]){
                if (dis[to[j]]>dis[u]+adj[j]){
                    dis[to[j]]=dis[u]+adj[j];
                    if (!f[to[j]]){
                        q.push(to[j]);
                        f[to[j]]=true;
                        ti[to[j]]++;
                    }
                    if (ti[to[j]]>n) {cout<<"-1"<<endl;exit(0);}
                }
            }
        }
        return ;
    }
    int main(){
        freopen("pd.in","r",stdin);
        freopen("pd.out","w",stdout);
        n=get(),ml=get(),md=get();
        for(int i=1;i<=n;i++) add(0,i,0);
        int a,b,d;
        for(int i=1;i<=ml;i++){
            a=get(),b=get(),d=get();
            add(a,b,d);
        }
        for(int i=1;i<=md;i++){
            a=get(),b=get(),d=get();
            add(b,a,-d);
        }
        spfa(0);
        spfa(1);
        if (dis[n]==inf) cout<<"-2"<<endl;
        else cout<<dis[n]<<endl;
        return 0;
    }
  • 相关阅读:
    segmentation fault(core dumped)
    (LIS LCS 例题)Max Sum Advanced Fruits Super Jumping! Jumping! Jumping!
    几种数学公式(环排列 母函数 唯一分解定理 卡特兰数 默慈金数 贝尔数 那罗延数)
    map set 详解
    算法录 之 二分和三分
    LIS 最长上升子序列 LCS 最长公共子序列 模板
    JAVA 大数据 例题
    Java 实现大数算法
    7 21 第一次团队赛——————写给队友
    离散化+unique()+二分查找
  • 原文地址:https://www.cnblogs.com/kanchuang/p/11121419.html
Copyright © 2020-2023  润新知