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
*/

浙公网安备 33010602011771号