CSP202212_2

CSP202212_2

题目

训练计划

思路

第一遍刚读完题没仔细看,以为前趋关系没有任何限制,想到用拓扑排序,在AOE网上求时间,感觉考察方向好明显。

结果一看样例,样例出奇的水,竟然都是一条链,再看了一遍题,原来每个点前趋最多有一个,不仅如此,前趋编号一定小于自身。那什么都不用,直接模拟就行了。

最早开始时间直接正序遍历,没前趋的直接第一天开始,否则在前趋结束后开始。对于最晚时间直接逆序遍历,自身若不是任何点的前趋,直接以恰好完成为标准开始,同时记得更新自己的前趋,必须让前趋的结束时间满足足够自身的结束,取最小值即可。记得一开始要初始化为INF。

Code

#include<bits/stdc++.h>
const int INF = 0x3f3f3f3f;
using namespace std;

int n, m;
int t[1010];
int pre[1010];
int ely[1010], lat[1010];

bool flag;

int main()
{
    cin >> n >> m;
    for(int i = 1;i <= m;i++)
    {
        cin >> pre[i];
    }
    for(int i = 1;i <= m;i++)
    {
        cin >> t[i];
    }

    for(int i = 1;i <= m;i++)
    {
        if(! pre[i]) ely[i] = 1;
        else ely[i] = ely[pre[i]] + t[pre[i]];
        if(ely[i] + t[i] - 1 > n) flag = true;
    }
    for(int i = 1;i <= m;i++)
    {
        cout << ely[i] << " ";
        lat[i] = INF;
    }
    if(flag) return 0;
    else cout << endl;

    for(int i = m;i >= 1;i--)
    {
        if(lat[i] == INF) lat[i] = n - t[i] + 1;
        if(pre[i])
        {
            lat[pre[i]] = min(lat[i] - t[pre[i]], lat[pre[i]]);
        }
    }
    for(int i = 1;i <= m;i++)
    {
        cout << lat[i] << " ";
    }
    return 0;
}
/*
10 5
0 0 0 0 0
1 2 3 2 10

1 1 1 1 1
10 9 8 9 1
*/
/*
10 7
0 1 0 3 2 3 0
2 1 6 3 10 4 3

1 3 1 7 4 7 1
*/
posted @ 2023-03-13 22:01  Kevin_Chance  阅读(43)  评论(0)    收藏  举报