zoukankan      html  css  js  c++  java
  • 30.

    Dijkstra+dfs。主要是先用dijkstra搞出每个点的最短路径,以及记录下那些同样可以构成最短路径的前驱点在pre里。vector在这种情况下是非常好用的。然后就是从目的点往回深搜,我用的是一个栈记录路径,尤其要注意栈pop时要处理一些事,缺一不可。

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #define Infinity 99999999
    
    using namespace std;
    
    bool visit[501];
    int edge[501][501],cost[501][501],dist[501],path[501],totalmoney=Infinity,stack[501],sp=-1,money=0;
    vector<int>pre[501];
    int N,M,S,D;
    
    void dfs(int u)
    {
        stack[++sp]=u;
        if(u==S)
        {
            if(money<totalmoney)
            {
                memcpy(path,stack,501);
                totalmoney=money;
            }
            return ;
        }
        for(vector<int>::iterator p=pre[u].begin();p!=pre[u].end();p++)
        {
            money+=cost[u][*p];
            dfs(*p);
            //退栈时要注意三件小事
            stack[sp]=-1;
            sp--;
            money-=cost[u][*p];
        }
        return ;
    }
    
    int main()
    {
        cin>>N>>M>>S>>D;
        fill(visit,visit+501,false);
        fill(edge[0],edge[0]+501*501,Infinity);
        fill(dist,dist+501,Infinity);
        fill(path,path+501,-1);
        fill(stack,stack+501,-1);
        for(int i=0;i<M;i++)
        {
            int city1,city2;
            cin>>city1>>city2;
            cin>>edge[city1][city2];
            edge[city2][city1]=edge[city1][city2];
            cin>>cost[city1][city2];
            cost[city2][city1]=cost[city1][city2];
        }
    
        //Dijkstra algorithm
        dist[S]=0;
        while(true)
        {
            int min=Infinity,u=-1;
            for(int j=0;j<N;j++)
            {
                if(visit[j]== false&&dist[j]<min)
                {
                    min=dist[j];
                    u=j;
                }
            }
            if(u==-1)break;
            visit[u]=true;
            for(int v=0;v<N;v++)
            {
                if(edge[u][v]<Infinity)
                {
                    if(visit[v]==false&&dist[u]+edge[u][v]<dist[v])
                    {
                        dist[v]=dist[u]+edge[u][v];
                        pre[v].clear();
                        pre[v].push_back(u);
                    }
                    else if(dist[u]+edge[u][v]==dist[v])
                    {
                        pre[v].push_back(u);
                    }
                }
            }
        }
    
        dfs(D);
    
        for(int i=500;i>=0;i--)
        {
            if(path[i]!=-1)
            {
                cout<<path[i]<<' ';
            }
        }
        cout<<dist[D]<<' '<<totalmoney;
    }
  • 相关阅读:
    quora 中有关angular与emberjs的精彩辩论
    迷你MVVM框架 avalonjs 0.94发布
    重写自己,减少判断 ---- 引发的思考
    JSON数据的优化
    记录全局错误
    Bat相关的项目应用
    C#中如何实现json转化时只处理部分属性
    JSON数据的处理中的特殊字符
    C# .net中json字符串和对象之间的转化方法
    VS调试 ---- 监视窗口、即时窗口、输出窗口
  • 原文地址:https://www.cnblogs.com/KRCheung/p/6589471.html
Copyright © 2011-2022 走看看