zoukankan      html  css  js  c++  java
  • hdu 1142 最短路+记忆化

    最短路+记忆化搜索
    HDU 1142 A Walk Through the Forest
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1142

    > 题意:找出不同的路径条数,假如jimmy要从A走到B的话满足jimmy从B到家的距离比从A到家的距离短
    > 这样我们可以通过最短路算法,找出从家(看成源点)到各个点的最短路径长度,记做D[v]。 然后就可以从起点(office)
    > dfs,首先从某点i到某点j走得通,然后满足D[j]<D[j],则可以往下搜索,直到终点(house),普通的dfs是会超时的,N都是1000了,不加剪枝啥的,dfs生成树那么大,肯定会TLE的。
    > 所以这里要用记忆话搜索,减少重复计算某个一个状态的值。 对于最短路和记忆化,本人也是刚刚学习的,最短路模仿的数据结构书上的
    > dijkstra,记忆化也是借鉴别人的思路。不过我想说说子结构的重复计算 比如 0
    > 1 2
    > 3 4 5 6

    > 7 8 9

    >  10   dfs(0) 是 从0到10的所以路径条数(假设走法随意,只要深度+1即可) dfs(4)是从4到10的路径条数,1可以到4,2也可以到4.
    > 那么dfs(1)后肯定已经计算过dfs(4)了,dfs(2)就没必要再计算,直接用这个结果就行了 所以可以用个数组保存即可
    > 再啰嗦一句,题库分这题在并查集里面,有哪位大神能教我并查集怎么做?

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    typedef struct
    {
        int arcs[1010][1010];
        int vexnum,arcnum;
        int vexs[1010];
    } AMGraph;
    AMGraph G;
    int D[1010],path[1010],S[1010],dp[1010];///这里忽略掉path吧,没用到
    const int maxint = 1000000000;
    int n,m;
    void createG(AMGraph &G)
    {
        int x,y,distance;
        for(int i = 1 ; i <=n; i++)
            for(int j =1; j<=n; j++)
                G.arcs[i][j] = maxint; ///建图,不连通的用一个能够满足题意的无穷大值表示
        for(int i = 0; i<m; i++)
        {
            scanf("%d%d%d",&x,&y,&distance);
            G.arcs[x][y] = G.arcs[y][x] = distance;
        }
    }
    void shortestflyod(AMGraph &G,int v0)///书上代码,不懂得还是看书吧
    {
        int v,w;
        for( v = 1; v<=n; v++)
        {
            S[v] = 0;
            D[v] = G.arcs[v0][v];
            if(D[v]<maxint) path[v] = v0;
            else path[v] = -1;
        }
        S[v0] = 1;
        D[v0] = 0;
        for(int i =2 ; i<=n; i++)
        {
            int minn = maxint;
            for( w = 1; w<=n; w++)
                if(!S[w]&&D[w]<minn)
                {
                    v = w;
                    minn = D[w];
                }
            S[v] = 1;
            for(w = 1; w<=n; w++)
                if(!S[w]&&D[v]+G.arcs[v][w]<D[w])
                {
                    D[w] = D[v] + G.arcs[v][w];
                    path[w] = v;
                }
        }
    }
    int  dfs(int v)
    {
        if(v==2)///到终点,找到一条路径
        {
            return 1;
        }
        if(dp[v]) return dp[v];///计算过,直接返回
        for(int i = 1; i<=n; i++)
            if(G.arcs[v][i]!=maxint&&D[i]<D[v])//连通且满足条件
                dp[v] += dfs(i);//dp[v] 等于下面一个分支的路径数之和
        return dp[v];
    }
    int main()
    {
        while(scanf("%d",&n)&&n)
        {
            scanf("%d",&m);
            createG(G);
            shortestflyod(G,2);
            memset(dp,0,sizeof(dp));
            int ans = 0;
            ans = dfs(1);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    onlyoffice 宋体显示问题排查
    【记录】shell脚本简写
    java 读取jar包内文件方法
    clickhouse升级
    grafana安装升级部署
    grafana新增插件
    ogg复制进程集成模式与经典模式之间切换
    ogg主库目录迁移
    goldengate从库目录迁移
    goldengate如何判断数据是否完成同步
  • 原文地址:https://www.cnblogs.com/jiachinzhao/p/4547873.html
Copyright © 2011-2022 走看看