链接:https://ac.nowcoder.com/acm/contest/3004/J
来源:牛客网
牛牛所在的W市是一个不太大的城市,城市有n个路口以及m条公路,这些双向连通的公路长度均为1,保证你可以从一个城市直接或者间接移动到所有的城市。牛牛在玩宝可梦Go,众所周知呢,这个游戏需要到城市的各个地方去抓宝可梦,假设现在牛牛知道了接下来将会刷出k只宝可梦,他还知道每只宝可梦的刷新时刻、地点以及该宝可梦的战斗力,如果在宝可梦刷新时,牛牛恰好在那个路口,他就一定能够抓住那只宝可梦。
看题解前:不会,溜了
看题解后:floyd,排序,01背包......................
#include<bits/stdc++.h> using namespace std; const int MAXN=100005; const int MAXP=505; const long long INF=1LL<<60; long long premax,dp[MAXN],ans,dis[MAXP][MAXP]; int n,m,N,u,v; struct node { int p,t; long long val; }a[MAXN]; int main() { scanf("%d %d",&n,&m); for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { dis[i][j]=i==j?0:INF; } } for(int i=1;i<=m;++i) { scanf("%d %d",&u,&v); dis[u][v]=dis[v][u]=1; } for(int k=1;k<=n;++k) { for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } } } scanf("%d",&N); for(int i=1;i<=N;++i) { scanf("%d %d %lld",&a[i].t,&a[i].p,&a[i].val); } sort(a+1,a+1+N,[](const node &A,const node &B){return A.t<B.t;}); a[0].p=1; for(int i=1;i<=N;++i) { if(i>200) { premax=max(premax,dp[i-200]); dp[i]=a[i].val+premax; } else { dp[i]=-INF; } for(int j=1;j<=200&&i-j>=0;++j) { if(a[i].t-a[i-j].t>=dis[a[i].p][a[i-j].p]) { dp[i]=max(dp[i],dp[i-j]+a[i].val); } } ans=max(ans,dp[i]); } printf("%lld\n",ans); return 0; }