1 条题解
-
0
这题关键就是每项任务都会有先决条件, 要完成该项任务a必须先完成他的先决条件。所以对于每个先决条件, 我们构建一条有向边到任务本身, 然后因为要求一个最小值, 按照最长路的方式松弛(dis[v] >= dis[u] + d, u是v的先决条件, d是v的完成时间,我们以边的终点完成时间作为边的权), 遇到没有出度的边记录答案。找出树上权值和最大的路;dp[i]记录到该点最大花费初始dp均为-1,然后让没有前置工作的dp[i]=cost【i】遍历点,如果dp[i]还没有求出来就记忆化搜索
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #define fora(i,a,b) for(i=a;i<b;i++) #define fors(i,a,b) for(i=a;i>b;i--) #define fora2(i,a,b) for(i=a;i<=b;i++) #define fors2(i,a,b) for(i=a;i>=b;i--) #define PI acos(-1.0) #define eps 1e-6 #define INF 0x3f3f3f3f typedef long long LL; typedef long long LD; using namespace std; const int maxn=10000+11; const int mod=10056; int n; int cost[maxn]; int tre[maxn][111]; int cou[maxn]; int dp[maxn]; void init() { memset(cou,0,sizeof(cou)); memset(dp,-1,sizeof(dp)); } void read() { init(); for(int i=1;i<=n;i++) { scanf("%d%d",&cost[i],&cou[i]); if(cou[i]==0)dp[i]=cost[i]; for(int j=1;j<=cou[i];j++) { scanf("%d",&tre[i][j]); } } } void DFS(int t) { for(int i=1;i<=cou[t];i++) { if(dp[tre[t][i]]==-1)DFS(tre[t][i]); } for(int i=1;i<=cou[t];i++) { dp[t]=max(dp[t],dp[tre[t][i]]); } dp[t]+=cost[t]; } int main() { while(~scanf("%d",&n)) { read(); int ans=0; for(int i=1;i<=n;i++) { if(dp[i]==-1)DFS(i); ans=max(ans,dp[i]); } printf("%d\n",ans); } return 0; }
- 1
信息
- ID
- 950
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者