A Walk Through the Forest

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 3   Accepted Submission(s) : 1
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
Input contains several test cases followed by a line
containing 0. Jimmy has numbered each intersection or joining of paths starting
with 1. His office is numbered 1, and his house is numbered 2. The first line of
each test case gives the number of intersections N, 1 < N ≤ 1000, and the
number of paths M. The following M lines each contain a pair of intersections a
b and an integer distance 1 ≤ d ≤ 1000000 indicating a path of length d between
intersection a and a different intersection b. Jimmy may walk a path any
direction he chooses. There is at most one path between any pair of
intersections.
 
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
 
Source
University of Waterloo Local Contest 2005.09.24
 
题意:Jimmy工作压力大,为了放松,他喜欢走路回家。而为了不太晚到家,他又得朝着家的方向走,也就是说必须离家越来越近。给定一个无向图,求有多少条路径回家。
 
分析:先用迪杰特斯拉算法求出各结点离源点(家)的最短距离,然后dfs求出路径总数。
 
时间超限代码(dfs需优化)
 #include <cstdio>
#include <queue>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std; const int maxn=;
vector<int> g[maxn];
struct node
{
int num,dis;
};
int n,m;
int cost[maxn][maxn],d[maxn];
int ans; bool operator<(const node& n1,const node& n2)
{
return n1.dis<n2.dis;
} void dij()
{
fill(d+,d+n+,INF);
d[]=;
priority_queue<node> que;
que.push(node{,});
while(!que.empty())
{
int x=que.top().num;
que.pop();
for(int i=;i<g[x].size();i++)
{
int u=x;
int v=g[x][i];
if(d[v]>d[u]+cost[u][v])
{
d[v]=d[u]+cost[u][v];
que.push(node{v,d[v]});
}
}
}
} void dfs(int x)
{
if(x==)
{
ans++;
return ;
}
for(int i=;i<g[x].size();i++)
{
int fx=g[x][i];
if(d[fx]<d[x])
dfs(fx);
}
} int main()
{
while(scanf("%d",&n),n)
{
scanf("%d",&m);
ans=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
cost[i][j]=(i==j)?:INF;
}
for(int i=;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a].push_back(b);
g[b].push_back(a);
cost[a][b]=cost[b][a]=c;
}
dij();
d[]=;
dfs();
printf("%d\n",ans);
for(int i=;i<=n;i++)
g[i].clear();
ans=;
}
return ;
}

优化分析:存在对某些结点进行了多次dfs,导致时间耗费过多。考虑采用记忆化搜索。我们用sum[i]表示从i出发有多少条到家的路径,对于已知sum[i]的结点i就不需要再次dfs,这样dfs的次数就只有n-1次(n为结点数)。

优化后代码:用时514ms

 #include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std; const int maxn=;
vector<int> g[maxn];//图的邻接表表示
struct node
{
int num,dis;
};
int n,m;
int cost[maxn][maxn],d[maxn];
int sum[maxn]; bool operator<(const node& n1,const node& n2)//重载运算符
{
return n1.dis<n2.dis;
} void dij()
{
fill(d+,d+n+,INF);//下标从1开始
d[]=;
priority_queue<node> que;
que.push(node{,});
while(!que.empty())
{
int x=que.top().num;
que.pop();
for(int i=;i<g[x].size();i++)
{
int u=x;
int v=g[x][i];
if(d[v]>d[u]+cost[u][v])
{
d[v]=d[u]+cost[u][v];
que.push(node{v,d[v]});
}
}
}
} void dfs(int x)
{
for(int i=;i<g[x].size();i++)
{
int fx=g[x][i];
if(d[fx]<d[x])
{
if(sum[fx]>)
{
sum[x]+=sum[fx];
}
else
{ dfs(fx);
sum[x]+=sum[fx];
}
}
}
// return ;
} int main()
{
while(scanf("%d",&n),n)
{
scanf("%d",&m);
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
cost[i][j]=(i==j)?:INF;
}
for(int i=;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a].push_back(b);
g[b].push_back(a);
cost[a][b]=cost[b][a]=c;
}
dij();
sum[]=;
dfs();
printf("%d\n",sum[]);
for(int i=;i<=n;i++)
g[i].clear();
}
return ;
}

此题bug过的地方

(1)fill(d+1,d+1+n,INF),一开始没注意下标是从1开始,写成了fill(d,d+n,INF)。dij函数bug。

(2)每组用例输出后没有清空图,导致下一组用例的图多了许多不属于自己的边和顶点。

hdu_A Walk Through the Forest ——迪杰特斯拉+dfs的更多相关文章

  1. PAT 1087 All Roads Lead to Rome[图论][迪杰斯特拉+dfs]

    1087 All Roads Lead to Rome (30)(30 分) Indeed there are many different tourist routes from our city ...

  2. HDU 1142 A Walk Through the Forest(最短路+dfs搜索)

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  3. HDU 1142 A Walk Through the Forest(dijkstra+记忆化DFS)

    题意: 给你一个图,找最短路.但是有个非一般的的条件:如果a,b之间有路,且你选择要走这条路,那么必须保证a到终点的所有路都小于b到终点的一条路.问满足这样的路径条数 有多少,噶呜~~题意是搜了解题报 ...

  4. 1018 Public Bike Management (30分) (迪杰斯特拉+dfs)

    思路就是dijkstra找出最短路,dfs比较每一个最短路. dijkstra可以找出每个点的前一个点, 所以dfs搜索比较的时候怎么处理携带和带走的数量就是关键,考虑到这个携带和带走和路径顺序有关, ...

  5. HDU1142 A Walk Through the Forest(dijkstra)

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  6. hdu 1142(迪杰斯特拉+记忆化搜索)

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  7. POJ 2502 Subway(迪杰斯特拉)

    Subway Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6692   Accepted: 2177 Descriptio ...

  8. C#迪杰斯特拉算法

    C#迪杰斯特拉算法 网上有许多版本的,自己还是写一个理解点 Dijkstra.cs public class Dijkstra { private List<Node> _nodes; p ...

  9. C++迪杰斯特拉算法求最短路径

    一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...

随机推荐

  1. Log4j配置文件内容详解

    .Log4j的优点 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送地:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控 ...

  2. Java 判断回文字符串有多少和其中的最大字符串

    一.简介代码功能 该代码的功能可以实现对任意的一段字符串进行判断是否有回文,回文有哪些,和其中的最大回文. 二.代码部分 1.全局变量 static String hws = "" ...

  3. JAVA----类的继承1(extends)

    要学习类的继承,首先应当理解继承的含义: 来自新华词典的释义: ①依法承受(死者的遗产等):-权ㄧ-人. ②泛指把前人的作风.文化.知识等接受过来:-优良传统ㄧ-文化遗产. ③后人继续做前人遗留下来的 ...

  4. NodeJs系列二:你好,世界

    安装nodejs 什么是nodejs中的模块 hello,world

  5. 任务十二:学习CSS 3的新特性

    任务目的 学习了解 CSS 3 都有哪些新特性,并选取其中一些进行实战小练习 任务描述 实现 示例图(点击查看) 中的几个例子 实现单双行列不同颜色,且前三行特殊表示的表格 实现正常状态和focus状 ...

  6. [编织消息框架][传输协议]stcp简单开发

    测试代码 public class ServerSTCP { static int SERVER_PORT = 3456; static int US_STREAM = 0; static int F ...

  7. Java计算两个程序运行时间

    一.获取系统当前时间 long startTime = System.currentTimeMillis(); //获取开始时间 doSomething(); //测试的代码段 long endTim ...

  8. DirectFB 之 字体显示

    通过本文,可以简单地了解directfb字体内部运行机制. 简介 SetFont函数,是每次写字体前必须调用的一个函数,否则directfb程序将会报错.这个函数是将某种字体与某个surface相关联 ...

  9. mui开发app之webview是什么

    WebView(网络视图)能加载显示网页,可以将其视为一个浏览器,webview被封装在html5+,plus对象中,底层由java,OC实现. 先来谈谈我对webview的理解: 使用mui开发的a ...

  10. Elasticsearch5中安装Elasticsearch-head插件

    介绍 elasticsearch-head是一个用于管理Elasticsearch的web前端插件,搞过ES的同学应该都了解.该插件在es5中可以以独立服务的形式进行安装使用.本文将介绍如何操作. 相 ...