zoukankan      html  css  js  c++  java
  • POJ2662A Walk Through the Forest;UVA10917 Walk Through the Forest(最短路径)

    题意:jimmy下班需要穿过一个森林。劳累一天后在森林中漫步是见非常惬意的事,所以他打算每天沿着不同的路径回家,欣赏不同的风景。但他也不想太晚回家,因此他不打算走回头路。换句话说,他只沿(A,B)走,存在一条从B出发回家的路径比所有从A出发回家的路径都短。你的任务是计算一共有多少条不同的回家路径

    分析:用dijkstra计算家到各个点的最短路径,则当d[i]>d[j],则有一条i-->j的路可走,因此形成了一个新图,且是DAG图。故可用动态规划计算方案。(使用记忆化搜索)

    // File Name: 2662.cpp
    // Author: zlbing
    // Created Time: 2013/2/6 18:48:14
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define MAXN 1050
    const int INF=1e9;
    struct Edge{
        int from,to,dist;
    };
    struct HeapNode{
        int d,u;
        bool operator <(const HeapNode &rhs)const{
            return d>rhs.d;
        }
    };
    struct Dijkstra{
        int n,m;//点和边数
        vector<Edge>edges;//边列表
        vector<int>G[MAXN];//每个节点出发的边编号(从0开始编号)
        bool done[MAXN];//是否永久标记
        int d[MAXN];//s到各个点的距离
        int p[MAXN];//最短路中的上一条边
    
        void init(int n)
        {
            this->n=n;
            for(int i=0;i<n;i++)G[i].clear();//清空邻接表
            edges.clear();//清空边表
        }
        void AddEdge(int from,int to,int dist)
        {
        //如果是无向图,每条无向边需调用2次AddEdge
            edges.push_back((Edge){from,to,dist});
            m=edges.size();
            G[from].push_back(m-1);
        }
        void dijkstra(int s)
        {//求s到所有点的距离
            priority_queue<HeapNode> Q;
            for(int i=0;i<n;i++)d[i]=INF;
            d[s]=0;
            memset(done,0,sizeof(done));
            Q.push((HeapNode){0,s});
            while(!Q.empty())
            {
                HeapNode x=Q.top();Q.pop();
                int u=x.u;
                if(done[u])continue;
                done[u]=true;
                for(int i=0;i<G[u].size();i++)
                {
                    Edge& e=edges[G[u][i]];
                    if(d[e.to]>d[u]+e.dist)
                    {
                        d[e.to]=d[u]+e.dist;
                        p[e.to]=G[u][i];
                        Q.push((HeapNode){d[e.to],e.to});
                    }
                }
            }
        }
    };
    Dijkstra solver;
    int M,N;
    int d[MAXN];
    int g[MAXN][MAXN];
    int dfs(int u)
    {
        if(d[u]!=-1)return d[u];
        d[u]=0;
        for(int i=0;i<N;i++)
        {
            if(g[i][u])
            d[u]+=dfs(i);
        }
        return d[u];
    }
    int main(){
        while(~scanf("%d",&N))
        {
            if(N==0)break;
            solver.init(N);
            scanf("%d",&M);
            int a,b,c;
            for(int i=0;i<M;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                a--,b--;
                solver.AddEdge(a,b,c);
                solver.AddEdge(b,a,c);
            }
            solver.dijkstra(1);
            memset(d,-1,sizeof(d));
            memset(g,0,sizeof(g));
            d[0]=1;
            for(int i=0;i<solver.edges.size();i++)
            {
                Edge& e=solver.edges[i];
                int u=e.from,v=e.to;
                if(solver.d[u]>solver.d[v])
                {
                    g[u][v]=1;
                }
            }
            int ans=dfs(1);
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    Hello,cnblogs!
    本地搭建IIS服务器
    thinkPHP相关
    网页中经常用到的<hr / >标签的样式
    JS三元表达式
    ZUI开发人员选项
    XWindow、Server、Client和QT、GTK之间的关系
    深度桌面操作系统架构设计
    关于linux图形界面的基本知识
    linux各发行版之间的区别
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2908213.html
Copyright © 2011-2022 走看看