zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Oracle SQL语句大全—查看表空间
    Class to disable copy and assign constructor
    在moss上自己总结了点小经验。。高手可以飘过 转贴
    在MOSS中直接嵌入ASP.NET Page zt
    Project Web Access 2007自定义FORM验证登录实现 zt
    SharePoint Portal Server 2003 中的单一登录 zt
    vs2008 开发 MOSS 顺序工作流
    VS2008开发MOSS工作流几个需要注意的地方
    向MOSS页面中添加服务器端代码的另外一种方式 zt
    状态机工作流的 SpecialPermissions
  • 原文地址:https://www.cnblogs.com/cchun/p/2520111.html
Copyright © 2011-2022 走看看