题目链接: ccf
题眼
每项科目最多只依赖一项别的科目,且满足依赖科目的编号小于自己
解题思路
最早开始时间(从前向后遍历)
如果无依赖科目,则为1 。
有依赖科目则为early[i] = early[pre[i]] + time[pre[i]]
最晚开始时间(从后向前遍历)
注意每个科目后继科目可能有多个,我们需要求所有后继求出来最早开始的那个时间
即late[buf] = min(n - day, late[buf])
AC代码
#include <stdio.h>
#include <list>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
int n, m;
const int N = 105;
bool vis[N];
const int MAX = 1000;
int early[N], late[N], pre[N], time[N];
void callate()
{
memset(vis, false, sizeof vis);
for (int i = m; i >= 1; i--)
{
if (vis[i])
continue;
vis[i] = true;
late[i] = n - time[i];
int buf = pre[i];
int day = time[i];
while (buf != 0)
{
vis[buf] = true;
day += time[buf];
late[buf] = min(n - day, late[buf]);
buf = pre[buf];
}
}
return;
}
void calearly()
{
memset(vis, false, sizeof vis);
for (int i = 1; i <= m; i++)
{
if (pre[i] == 0)
{
early[i] = 1;
}
else
{
early[i] = early[pre[i]] + time[pre[i]];
}
}
return;
}
int main()
{
scanf("%d%d", &n, &m);
n++;
memset(early, 0, sizeof early);
memset(late, 0, sizeof late);
for (int i = 1; i <= m; i++)
{
scanf("%d", &pre[i]);
}
for (int i = 1; i <= m; i++)
{
scanf("%d", &time[i]);
}
for (int i = 1; i <= m; i++)
{
late[i] = MAX;
}
calearly();
callate();
for (int i = 1; i <= m; i++)
{
printf("%d ", early[i]);
}
printf("\n");
bool flag = true;
for (int i = 1; i <= m; i++)
{
if (late[i] <= 0)
flag = false;
}
if (flag)
{
for (int i = 1; i <= m; i++)
{
printf("%d ", late[i]);
}
}
return 0;
}