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;
}

 

posted on 2016-07-24 12:31  Yxter  阅读(620)  评论(0编辑  收藏  举报

导航