zoukankan      html  css  js  c++  java
  • HDU 1142 A Walk Through the Forest

    A Walk Through the Forest

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
    Total Submission(s) : 8   Accepted Submission(s) : 5

    Font: Times New Roman | Verdana | Georgia

    Font Size: ← →

    Problem Description

    Jimmy experiences a lot of stress at work these days, especially since his accident made working difficult. To relax after a hard day, he likes to walk home. To make things even nicer, his office is on one side of a forest, and his house is on the other. A nice walk through the forest, seeing the birds and chipmunks is quite enjoyable. 
    The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take. 

    Input

    Output

    For each test case, output a single integer indicating the number of different routes through the forest. You may assume that this number does not exceed 2147483647

    Sample Input

    5 6
    1 3 2
    1 4 2
    3 4 3
    1 5 12
    4 2 34
    5 2 24
    7 8
    1 3 1
    1 4 1
    3 7 1
    7 4 1
    7 5 1
    6 7 1
    5 2 1
    6 2 1
    0
    

    Sample Output

    2
    4

    思路:同 hdu 1428 校园漫步
    先求出bfs,每点到终点的距离(为后面能不能走作判断基础),再统计,路线数量
    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    const int inf=0x7fffffff;
    const int maxn=1005;
    int n,m,i,j;
    long long  f[maxn],dis[maxn];
    int st[maxn];
    
    struct node
    {
        int num,d;
        node(int a,int b){num=a; d=b;}
    };
    vector<node> s[maxn];
    
    bool cmp(int  a,int  b)
    {
        return dis[a]>dis[b];
    }
    
    void bfs()
    {
        queue<int> Q;
        Q.push(2);
       // memset(vis,0,sizeof(vis));
        dis[2]=0;
        while(!Q.empty())
        {
            int u=Q.front();
            Q.pop();
            for(int i=0;i<s[u].size();i++)
            {
                if(dis[u]+s[u][i].d>=dis[s[u][i].num]) continue;
                dis[s[u][i].num]=dis[u]+s[u][i].d;
                Q.push(s[u][i].num);
                //不能用vis[]数组判断是否访问过。
                //原因:如果被访问过,不一定在队列中,就不能更新其他点。
            }
        }
        return;
    }
    int main()
    {
        while(scanf("%d",&n))
        {
            if (n==0) break;
            scanf("%d",&m);
            for(i=1;i<=n;i++)
            {
                s[i].clear();
                dis[i]=inf;
            }
            for(i=1;i<=m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                s[x].push_back(node(y,z));
                s[y].push_back(node(x,z));
            }
            bfs();
            for(i=1;i<=n;i++) st[i]=i;
            sort(st+1,st+n+1,cmp);
            memset(f,0,sizeof(f));
            f[1]=1;
            for(i=1;i<=n;i++)
            {
                for(j=0;j<s[st[i]].size();j++)
                 if (dis[ s[st[i]][j].num ]>dis[st[i]])
                     f[st[i]]+=f[s[st[i]][j].num];
            }
            printf("%lld\n",f[2]);
        }
        return 0;
    }

     spfa算法+记忆化搜索

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int inf=1000000010;
    int n,m;
    int dis[1005],dp[1005];
    bool vis[1005];
    struct node
    {
        int num,d;
        node(int a,int b){num=a; d=b;}
    };
    vector<node> s[1005];
    
    int  dfs(int k)
    {
        if (dp[k]>0) return dp[k];
        if (k==2) return 1;
        //dp[k]=0;
        for(int i=0;i<s[k].size();i++)
           if (dis[k]>dis[s[k][i].num])
             dp[k]+=dfs(s[k][i].num);
        return dp[k];
    }
    
    void spfa()
    {
        queue<int> Q;
        Q.push(2);
        vis[2]=1;
        dis[2]=0;
        while(!Q.empty())
        {
            int u=Q.front();
            Q.pop();
            vis[u]=0;
            for(int i=0;i<s[u].size();i++)
            {
                if(dis[s[u][i].num]<=dis[u]+s[u][i].d) continue;
                dis[s[u][i].num]=dis[u]+s[u][i].d;
                if (!vis[s[u][i].num])
                {
                    vis[s[u][i].num]=1;
                    Q.push(s[u][i].num);
                }
            }
        }
        return;
    }
    int main()
    {
        while(scanf("%d",&n) && n)
        {
            scanf("%d",&m);
            for(int i=1;i<=n;i++) s[i].clear();
            for(int i=1;i<=m;i++)
            {
                int x,y,d;
                scanf("%d%d%d",&x,&y,&d);
                s[x].push_back(node(y,d));
                s[y].push_back(node(x,d));
            }
    
           for(int i=1;i<=n;i++) dis[i]=inf;
           spfa();
           memset(dp,0,sizeof(dp));
           printf("%d\n",dfs(1));
        }
        return 0;
    }
  • 相关阅读:
    复利计算
    实验四 主存空间的分配和回收
    0526 Sprint1个人总结 & 《构建之法》第八、九、十章
    实验三 进程调度模拟程序
    0427 scrum & 读后感
    0415 评论
    0414 结对2.0
    汉堡包
    0406 结对编程总结
    读《构建之法》第四章有感
  • 原文地址:https://www.cnblogs.com/stepping/p/5700570.html
Copyright © 2011-2022 走看看