Links: https://ac.nowcoder.com/acm/contest/3004/J
Ideas:
Pretreatment with the first flyod dis [i] [j] represents the shortest distance from point i to j
After starting DP, dp [i] denote the i-th wizard may appear harvest the maximum combat effectiveness
Then dp [i] to obtain the transfer equation dp [i] = max (dp [i], dp [ij] + a [i] .val) represents Po may dream before i j number of occurrences of
Then this will be the time complexity is K 2 , but we can see that the distance between any two points on the map are less than 200, it can only be a maximum of 200 j, so it reduced complexity O (200 * K )
Note that the time difference is determined also dreams can occur two Po is greater than the distance between two points is equal to
#include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e5+10; const int inf=0x3f3f3f3f; int dis[205][205],n,m,u,v,k; ll ans=0,dp[maxn]; struct pok{ int t,pos,v; }a[maxn]; int cmp(pok a,pok b){return a.t<b.t;} void floyd() { 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]); } 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; } floyd(); scanf("%d",&k); for(int i=1;i<=k;i++) scanf("%d%d%d",&a[i].t,&a[i].pos,&a[i].v); sort(a+1,a+1+k,cmp); a[0].t=0,a[0].pos=1,a[0].v=0; for(int i=1;i<=k;i++){ dp[i]=-inf; for(int j=1;j<=200&&i>=j;j++){ if(a[i].t-a[i-j].t>=dis[a[i].pos][a[i-j].pos]) dp[i]=max(dp[i],dp[i-j]+a[i].v); } ans=max(dp[i],ans); } cout<<ans<<endl; return 0; }