如HDU的4502,把题目抽象成一张图,把区间的头-1,这样就可以连接起来了。
View Code
#include <cstdio> #include <cstring> const int Max = 109; #define max(a,b) a>b?a:b int mat[Max][Max]; int dis[Max]; bool vis[Max]; int n ,m; void dij(int s) { memset(vis,0,sizeof(vis)); for(int i = 1; i <= n; i++) { dis[i] = mat[s][i]; } vis[s] = 1; while(1) { int Mmin = 0, p = -1; for(int i = 1; i <= n; i++) { if(!vis[i] && dis[i] > Mmin) { Mmin = dis[i]; p = i; } } if(p == -1) break; vis[p] = 1; for(int i = 1; i <= n; i++) { if(dis[i] < dis[p] + mat[p][i]) { dis[i] = dis[p] + mat[p][i]; } } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(mat,-0x7f,sizeof(mat)); for(int i = 0; i <=n ; i++) { for(int j = i+1; j <=n ;j++) { mat[i][j] = 0; } } for(int i = 0; i < m; i++) { int a ,b ,c; scanf("%d%d%d",&a,&b,&c); if(b > n) continue; mat[a-1][b] = max(mat[a-1][b],c); } for(int k = 0; k <= n; k++) { for(int i = k + 1; i <= n; i++) { for(int j = k - 1 ; j >= 0; j--) { mat[j][i] = max(mat[k][i],mat[j][i]); } } } dij(0); int ans = 0; for(int i = 1; i <= n; i++) { if(dis[i] > ans) ans = dis[i]; } printf("%d\n",ans); } return 0; }
PS:最长路没有子结构,子段最长不一定总的最长。如此图