题目:
Input
Output
输出n行。第i行输出两个整数,分别表示第i份作业最早完成的时刻以及最晚完成的时刻,两个整数之间以一个空格间隔。
Sample Input
4 4
3 4 5 6
1 2
1 3
2 4
3 4
Sample Output
3 3
7 12
8 12
18 18
思路:
不得不说,挺水的。
用深搜。
怎样才能做到最快呢?先把目标作业前的作业做完,即使最短。(即f1的树)
怎样才能做到最慢呢?先做其他能做的作业(sum-不能做的作业)(即f2树)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int a[2222],n,m,f1[2222][2222],f2[2222][2222];
bool b[2222];
int dfs1(int x)
{
int fuck=a[x];
for(int p=1; p<=f1[x][0]; p++)
if (!b[f1[x][p]]) {b[f1[x][p]]=1;fuck+=dfs1(f1[x][p]);}
return fuck;
}
int dfs2(int x)
{
int fuck=a[x];
for(int p=1; p<=f2[x][0]; p++)
if (!b[f2[x][p]]) {b[f2[x][p]]=1;fuck+=dfs2(f2[x][p]);}
return fuck;
}
int main()
{
scanf("%d%d",&n,&m);
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
int sum=0;
for(int i=1; i<=n; i++) {scanf("%d",&a[i]); sum+=a[i];}
for(int i=1; i<=m; i++)
{
int x,y=0;
scanf("%d%d",&x,&y);
f1[y][++f1[y][0]]=x;
f2[x][++f2[x][0]]=y;
}
for(int i=1; i<=n; i++)
{
memset(b,0,sizeof(b));
printf("%d ",dfs1(i));
memset(b,0,sizeof(b));
printf("%d\n",sum-dfs2(i)+a[i]);
}
return 0;
}