题意:看样子很多人都把这题目看错了,以为是求最短路的条数。真正的意思是:假设 A和B 是相连的,当前在 A 处,

如果 A 到终点的最短距离大于 B 到终点的最短距离,则可以从 A 通往 B 处,问满足这种的条件的从办公室到家的路径条数。

分析:1、以终点 2 为起点 Dijkstra跑一边最短路,找到所有点到2的最短距离;
       2、直接DFS记忆化搜索。
注意:记忆化搜索时的return值,否则此很容易TLE
解法1:O(n^2)
#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 0x7fffffff
int n,m,u,v,w;
using namespace std;
int g[][],dis[];
int vis[],path[];
void Dijkstra(int u)
{
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)
dis[i]=g[u][i];
dis[u]=;
vis[u]=;
for(int i=;i<=n;i++){
int k,min=inf;
for(int j=;j<=n;j++){
if(!vis[j]&&min>dis[j]){
min=dis[j];
k=j;
}
}
vis[k]=;
for(int j=;j<=n;j++){
if(!vis[j]&&g[k][j]!=inf){//g[k][j]!=inf不能少
if(dis[j]>dis[k]+g[k][j])
dis[j]=dis[k]+g[k][j];
}
}
}
} int dfs(int u)
{
if(path[u]!=-) return path[u];
if(u==) return ;//记忆化搜索,如果该点已经访问过了,就返回从该点到终点的路径数
int num=;
for(int v=;v<=n;v++){
if(g[u][v]!=inf&&dis[v]<dis[u])
num+=dfs(v);
}
path[u]=num;//不能直接return num,否则会TLE
return path[u];
} int main()
{
while(scanf("%d",&n),n){
scanf("%d",&m);
memset(path,-,sizeof(path));
for(int i=;i<=n;i++){
for(int j=;j<=n;j++)
g[i][j]=(i==j?:inf);
}
for(int i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
if(g[u][v]>w)//处理重边
g[u][v]=g[v][u]=w;
}
Dijkstra();
cout<<dfs()<<endl;
}
return ;
}

解法2:刚开始dfs中TLE,修改后就一直WA...至今缘由不明,还是太菜了

#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#define inf 0x7fffffff
using namespace std;
struct Node
{
int u,d;
Node(long long uu,long long dd){
u=uu,d=dd;
}
friend bool operator < (Node a,Node b){
return a.d>b.d;
}
};
struct Edge
{
int v,w;
Edge(long long vv,long long ww){
v=vv,w=ww;
}
};
bool vis[];
long long path[];
vector<Edge> g[];//为Edge类型
priority_queue<Node>que;//为Node类型
long long dis[];
void Dijkstra()
{
dis[]=;
que.push(Node(,));
while(!que.empty()){
Node p=que.top();
que.pop();
long long u=p.u;
if(!vis[u]){
vis[u]=;//vis[u]=1位置不能放错
for(int i=;i<g[u].size();i++){
long long v=g[u][i].v;
long long c=g[u][i].w;
if(!vis[v]){//这里不能写vis[v]=1;
if(dis[v]>dis[u]+c){
dis[v]=dis[u]+c;
que.push(Node(v,dis[v]));
}
}
}
}
}
}
int dfs(int u)
{
if(path[u]!=-) return path[u];
if(u==) return ;//找到终点,返回1条路
long long num=;//注意num的位置
for(int i=;i<g[u].size();i++){
int v=g[u][i].v;
if(dis[v]<dis[u])
num+=dfs(v);
}
path[u]=num;
return path[u];//返回从u到终点的所有路径数
}
int main()
{
long long n,m,u,v,w;
while(scanf("%lld",&n),n){
scanf("%lld",&m);
memset(g,,sizeof(g));//切记清零
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++) dis[i]=inf;
for(int i=;i<=m;i++){
scanf("%lld%lld%lld",&u,&v,&w);
g[u].push_back(Edge(v,w));
g[v].push_back(Edge(u,w));
}
Dijkstra();
memset(path,-,sizeof(path));//初始化
printf("%lld\n",dfs());
}
}

HDU 1142 A Walk Through the Forest(Dijkstra+记忆化搜索)的更多相关文章

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

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

  2. 题解报告:hdu 1142 A Walk Through the Forest

    题目链接:acm.hdu.edu.cn/showproblem.php?pid=1142 Problem Description Jimmy experiences a lot of stress a ...

  3. HDU1142 (Dijkstra+记忆化搜索)

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

  4. HDU 1142 A Walk Through the Forest (记忆化搜索 最短路)

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

  5. HDU 1142 A Walk Through the Forest(最短路+记忆化搜索)

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

  6. HDU 4444 Walk (离散化建图+BFS+记忆化搜索) 绝对经典

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4444 题意:给你一些n个矩形,给你一个起点,一个终点,要你求从起点到终点最少需要转多少个弯 题解:因为 ...

  7. luogu3953 [NOIp2017]逛公园 (tarjan+dijkstra+记忆化搜索)

    先跑一边dijkstra算出从1到i的最短距离dis[i] 然后建反向边 从n开始记忆化搜索,(p,k)表示1到p的距离=dis[p]+k的方案数 答案就是$\sum\limits_{i=0}^{k} ...

  8. HDU 1142 A Walk Through the Forest (求最短路条数)

    A Walk Through the Forest 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1142 Description Jimmy exp ...

  9. hdu 1142 A Walk Through the Forest (最短路径)

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

随机推荐

  1. mac 安装软件提示权限不足的解决的方法

    假设直接输入命令提示没权限的时候 1.sudo 安装命令 2.sudo su -  这时候切换到root用户下了 ,能够随心所欲了

  2. json 转 T

    T test = JsonConvert.DeserializeObject<T>(json);(json.net)

  3. when case group by 的用法集合

    1.用那个以前大家都熟悉的例子,要求是依旧下面的表格求每个大洲的人口总和 国家(countrcoungry) 人口(population) 中国 600 美国 100 加拿大 100 英国 200 法 ...

  4. std__vector介绍

    vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...

  5. 各种层次NET人应该知道些什么?

    A.任何一个使用.NET的人 1.描述线程与进程的区别? 2.什么是Windows服务,它的生命周期与标准的EXE程序有什么不同 ? 3.Windows上的单个进程所能访问的最大内存量是多少?它与系统 ...

  6. 【BZOJ1005/1211】[HNOI2008]明明的烦恼/[HNOI2004]树的计数 Prufer序列+高精度

    [BZOJ1005][HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可 ...

  7. java的Enumeration转list

    java的Enumeration转list Enumeration<String> attrs = getAttrNames();// while(attrs.hasMoreElement ...

  8. tortoiseSVN如何回滚(切换至)某个历史版本?

    tortoiseSVN如何回滚(切换至)某个历史版本? 1.右键需要回滚的项目,tortoiseSVN - >show log 2.右键需要回滚的历史版本,选择revert to this re ...

  9. MyBatis笔记——EhCache二级缓存

    介绍 ehcache是一个分布式缓存框架. 我们系统为了提高系统并发,性能.一般对系统进行分布式部署(集群部署方式)  不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发.所以要使用分布式缓 ...

  10. js功能实现的特效--距离新年还有多少天

    代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...