Dijkstra求最长路就是个坑!

如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:最长路没有子结构,子段最长不一定总的最长。如此图

posted @ 2013-03-21 17:42  gray035  阅读(851)  评论(0编辑  收藏  举报