HDU3790最短路径问题DIjkstra

题目很简单,直接用Dijkstra求最短路,但是又有点变化,就是要再求路径的同时求出费用。当然,也不难,直接结构体,把费用与路径同时做计算。就可以得出最短路径跟费用了。记住:要考虑当最短路相同时,费用要选择最小的那一个。

郁闷的是,题目还有可能会输入同一条边得不同路径长度。

 

Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
 

ps:

1、单向还是双向图,考虑清楚
2、注意那个maxInt这个值超不超,够不够
3、注意是否两点间有多条路径
4、分清变量是double型的还是int型的
5、注意主函数中初始化map[][]中的点边不要搞错(注意所有初始化,正确命名好变量)

 

仔细看好题目的input要求,a,b,d,p表示a和b之间有一条边。也就是说存在3,5,6,7,和3,5,13,34这种情况。还有,点的总数就n个,可是输入m却可以最多是100000,比n最多打了100倍,早该考虑到会有重边这种情况。有3,5,6,7,和3,5,13,34的可能,那么就应该有3,5,6,7,和3,5,6,34的存在啊。可是不考虑这里也可以ac.奇怪了.是HDU测试数据木有考虑到?

ac代码:

#include<iostream> 
#define N 1009 
#define Max 1000001
 
using namespace std; 
 
struct CP 

    int d; 
    int p; 
} map[N][N]; 
 
struct AN 

    int d1; 
    int p1; 
} dis[N]; 
 
int dijkstra(int s,int n,int e)//这里还是传统的dijkstra,就是加了结构体,还有计算最短路的价值 

    int visited[N],index=0
    int i,j; 
    memset(visited,0,sizeof(visited)); 
    visited[s]=1
    for(i=1; i<=n; i++) 
    { 
        dis[i].d1=map[s][i].d;//路程 
        dis[i].p1=map[s][i].p;//费用 
        ///    cout<<dis[i].p1<<"   "; 
    } 
    for(i=1; i<n; i++) 
    { 
        int min=Max; 
        for(j=1; j<=n; j++) 
        { 
            if(visited[j]==0&&min>dis[j].d1) 
            { 
                min=dis[j].d1; 
                index=j; 
            } 
        } 
        visited[index]=1
        for(j=1; j<=n; j++) 
        { 
            if(visited[j]==0&&min+map[index][j].d<dis[j].d1) 
            { 
                dis[j].d1=min+map[index][j].d; 
                dis[j].p1=dis[index].p1+map[index][j].p; 
            } 
            else if(visited[j]==0&&min+map[index][j].d==dis[j].d1)     //容易混淆,要仔细想 
            { 
                if(dis[j].p1>dis[index].p1+map[index][j].p) 
                    dis[j].p1=dis[index].p1+map[index][j].p; 
            } 
        } 
    } 
    /*    for(i=1;i<=n;i++) 
            cout<<dis[i].d1<<"   "; 
        cout<<endl; 
        for(i=1;i<=n;i++) 
            cout<<dis[i].p1<<"   "; 
        cout<<endl;*/ 
    printf("%d %d\n",dis[e].d1,dis[e].p1); 
    return 0

 
int main(void

    int n,m,i,j,a,b,d,p,s,e; 
    while(scanf("%d%d",&n,&m),n||m) 
    { 
        for(i=0; i<N; i++) 
        { 
            for(j=0; j<N; j++) 
            { 
                map[i][j].d=Max; 
                map[i][j].p=0;//初始费用为0或者Max都没关系,因为最后会被你输入覆盖。或者此路不存在,然后路劲为1000001 
            } 
            map[i][i].d=0
        } 
 
        for(i=1; i<=m; i++) 
        { 
            scanf("%d%d%d%d",&a,&b,&d,&p); 
            if(map[a][b].d>d)   //晕,还有一条边,然后有两种不同长度的情况。郁闷中~为此WA了10次,郁闷了3天 
            { 
                map[a][b].d=map[b][a].d=d; 
                map[a][b].p=map[b][a].p=p; 
            } 
            else if(map[a][b].d==d) 
            { 
                if(map[a][b].p>p) 
                { 
                    map[a][b].p=map[b][a].p=p; 
                } 
            } 
 
        } 
        scanf("%d%d",&s,&e); 
        dijkstra(s,n,e); 
    } 
    return 0

原文地址:https://www.cnblogs.com/cchun/p/2520111.html