• 工程规划(答案错误)


    【问题描述】

        造一幢大楼是一项艰巨的工程,它是由n个子任务构成的,给它们分别编号1,2,…,n(5≤n≤1000)。由于对一些任务的起始条件有着严格的限制,所以每个任务的起始时间T1,T2,…,Tn并不是很容易确定的(但这些起始时间都是非负整数,因为它们必须在整个工程开始后启动)。例如:挖掘完成后,紧接着就要打地基;但是混凝土浇筑完成后,却要等待一段时间再去掉模板。

        这种要求就可以用M(5≤m≤5000)个不等式表示,不等式形如Ti-Tj≤b代表i和j的起始时间必须满足的条件。每个不等式的右边都是一个常数b,这些常数可能不相同,但是它们都在区间(-100,100)内。

        你的任务就是写一个程序,给定像上面那样的不等式,找出一种可能的起始时间序列T1,T2,…,Tn,或者判断问题无解。对于有解的情况,要使最早进行的那个任务和整个工程的起始时间相同,也就是说,T1,T2,…,Tn中至少有一个为0。

    【输入】

        第一行是用空格隔开的两个正整数n和m,下面的m行每行有三个用空格隔开的整数i,j,b对应着不等式Ti-Tj≤b。

    【输出】

           如果有可行的方案,那么输出N行,每行都有一个非负整数且至少有一个为0,按顺序表示每个任务的起始时间。如果没有可行的方案,就输出信息“NO SOLUTION”。

    【样例1

           work.in                               work.out

           5 8                                     0

           1 2 0                                  2

           1 5 –1                                5

           2 5 1                                  4

           3 1 5                                  1

           4 1 4

           4 3 –1

           5 3 –1

           5 4 –3

    【样例2

           work.in                               work.out

           5 5                                     NO SOLUTION

           1 2 –3

           1 5 –1

           2 5 –1

           5 1 –5

           4 1 4

    【算法分析】

           本题是一类称为约束满足问题的典型问题,问题描述成n个子任务的起始时间Ti及它们之间在取值上的约束,求一种满足所有约束的取值方法。

           将工程的n个子任务1,2,…,n作为一有向图G的n个顶点,顶点Vi(i=1,…,n)的关键值为子任务i的起始时间Ti,我们并不需要关心顶点之间的弧及其弧长,而是要确定顶点的关键值Ti的取值,满足所有的约束条件。本题的约束条件由m个不等式Ti-Tj≤b给出,这样的有向图称为约束图。

        为了确定每一个Ti的值,先假设某一个子任务的起始时间为零,如设Tj=0,则其余子任务的起始时间Ti相对于T1可设置其起始时间为一区间[-maxt,maxt]。

        下面分析不等式Ti-Tj≤b。此不等式可变形为如下两种形式:

        (1)Ti≤Tj+b意味Ti的最大值为Tj+b;

        (2)Tj≥Ti-b意味Tj的最大值为Ti-b;

        因此,根据题中给出的m个不等式,逐步调整各个Ti的最小值和最大值。

        设high[i]为Ti当前的最大值,low[i]为Ti当前的最小值。

        high[j]为Tj当前的最大值,low[j]为Tj当前的最小值。

        若high[i]-high[j]>b,则high[i]=high[j]+b(根据Ti≤Tj+b),

        若low[i]-low[j]<b,则low[j]=low[i]-b(根据Ti≥Ti-b)。

        以上的调整终止视下列两种情况而定:

        (1)对所有的不等式Ti-Tj≤b,不再有high[i]或low[j]的调整;

        (2)若存在high[i]<low[i]或high[j]<low[j]则表示不存在T1,T2,…,Tn能满足所有m个不等式Ti-Tj≤b,即问题无解。

    /*
      <1>根据题意,假设一个开始任务,开始时间为0,其余的各项任务均
      维护一个时间范围,即low[i]—high[i]。 
      由 Ti-Tj<=b 得:① Ti<=Tj+b,即 high[i]=high[j]+b;
                     ② Tj>=Ti-b,即 low[j]=low[i]-b;
      <2>当high[i]-high[j]<=b 或者 low[i]-low[j]<=b 时,成立;
      反之,则用以上①②式更新。
      <3>当high[]<low[]时,没有可行方案,
      <4>当数据不再更新时,得出可行方案(满足数据非负,且至少有一个0)。 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define M 1010
    #define N 5010
    #define INF 10000
    using namespace std;
    int high[M],low[M];
    struct node
    {
        int x,y,v;
    };node a[N];
    int main()
    {
        int n,m,x,y,v;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&v);
            a[i].x=x;
            a[i].y=y;
            a[i].v=v;
        }
        for(int i=2;i<=n;i++)
        {
            high[i]=INF;
            low[i]=-INF;
        }
        int flag=1,ff=0;
        while(flag)
        {
            flag=0;
            for(int i=1;i<=m;i++)
            {
                int x=a[i].x,y=a[i].y,b=a[i].v;
                if(high[x]-high[y]>b)
                {
                    high[x]=high[y]+b;
                    flag=1;
                }
                if(low[x]-low[y]>b)
                {
                    low[y]=low[x]-b;
                    flag=1;
                }
                if(high[x]<low[x]||high[y]<low[y])
                {
                    ff=1;
                    flag=0;
                }
            }
        }
        if(ff)printf("NO SOLUTION");
        else
        {
            int minn=INF;
            for(int i=1;i<=n;i++)
              minn=min(high[i],minn);
            for(int i=1;i<=n;i++)
              printf("%d
    ",high[i]-minn);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【[AH2017/HNOI2017]礼物】
    【[ZJOI2014]力】
    FFT抄袭笔记
    【[SCOI2015]小凸玩矩阵】
    【[SDOI2017]新生舞会】
    bzoj 3277: 串
    【[ZJOI2015]诸神眷顾的幻想乡】
    【[TJOI2017]DNA】
    【[TJOI2018]碱基序列】
    【[TJOI2018]异或】
  • 原文地址:https://www.cnblogs.com/harden/p/5596812.html
Copyright © 2020-2023  润新知