UVa 10917 林中漫步

https://vjudge.net/problem/UVA-10917

题意:

给出一个图,求出从1走到2共有多少种走法。前提是他只沿着满足如下条件的道路(A,B)走:存在一条从B出发回家的路径,比所有从A出发回家的路径都短。

思路:

首先用Dijkstra算法求出每个点到家的最短路径,那么题目的要求也就变成了d[B]<d[A],这样,我们创建了一个新的图,当且仅当d[B]<d[A]时加入有向边A->B,这样就是一个DAG,直接用动态规划计数。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7
  8 const int maxn = 1000 + 5;
  9 const int INF = 0x3f3f3f3f;
 10
 11 int n, m;
 12
 13 struct Edge
 14 {
 15     int from, to, dist;
 16     Edge(int u, int v, int d) :from(u), to(v), dist(d){}
 17 };
 18
 19 struct HeapNode
 20 {
 21     int d, u;
 22     HeapNode(int x, int y) :d(x), u(y){}
 23     bool operator < (const HeapNode& rhs) const
 24     {
 25         return d>rhs.d;
 26     }
 27 };
 28
 29 struct Dijkstra
 30 {
 31     int n, m;
 32     vector<Edge> edges;
 33     vector<int> G[maxn];
 34     bool done[maxn];
 35     int d[maxn];
 36     int p[maxn];
 37     int dp[maxn];
 38
 39     void init(int n)
 40     {
 41         this->n = n;
 42         for (int i = 0; i < n; i++)
 43             G[i].clear();
 44         edges.clear();
 45     }
 46
 47     void AddEdge(int from, int to, int dist)
 48     {
 49         edges.push_back(Edge(from, to, dist));
 50         int m = edges.size();
 51         G[from].push_back(m - 1);
 52     }
 53
 54     void dijkstra(int s)
 55     {
 56         priority_queue<HeapNode> Q;
 57         for (int i = 0; i < n; i++)  d[i] = INF;
 58         memset(done, 0, sizeof(done));
 59         d[s] = 0;
 60         Q.push(HeapNode(0, s));
 61         while (!Q.empty())
 62         {
 63             HeapNode x = Q.top();
 64             Q.pop();
 65             int u = x.u;
 66             if (done[u])  continue;
 67             done[u] = true;
 68             for (int i = 0; i < G[u].size(); i++)
 69             {
 70                 Edge& e = edges[G[u][i]];
 71                 if (d[e.to]>d[u] + e.dist)
 72                 {
 73                     d[e.to] = d[u] + e.dist;
 74                     p[e.to] = e.from;
 75                     Q.push(HeapNode(d[e.to], e.to));
 76                 }
 77             }
 78         }
 79     }
 80
 81     int DP(int s)
 82     {
 83         if (s == 1)  return 1;
 84         if (dp[s] != -1)  return dp[s];
 85         dp[s] = 0;
 86         for (int i = 0; i < G[s].size(); i++)
 87         {
 88             Edge e = edges[G[s][i]];
 89             if (d[e.to] < d[s])  dp[s] += DP(e.to);
 90         }
 91         return dp[s];
 92     }
 93 }t;
 94
 95 int main()
 96 {
 97     //freopen("D:\\input.txt", "r", stdin);
 98     int u, v, d;
 99     while (~scanf("%d", &n) && n)
100     {
101         scanf("%d", &m);
102         t.init(n);
103         for (int i = 0; i < m; i++)
104         {
105             scanf("%d%d%d", &u, &v, &d);
106             t.AddEdge(u - 1, v - 1, d);
107             t.AddEdge(v - 1, u - 1, d);
108         }
109         t.dijkstra(1);
110         memset(t.dp, -1, sizeof(t.dp));
111         t.DP(0);
112         printf("%d\n", t.dp[0]);
113     }
114     return 0;
115 }
时间: 2024-08-28 22:07:35

UVa 10917 林中漫步的相关文章

UVA - 10917 Walk Through the Forest (最短路+DP)

题意:Jimmy打算每天沿着一条不同的路走,而且,他只能沿着满足如下条件的道路(A,B):存在一条从B出发回家的路径,比所有从A出发回家的路径都短,你的任务是计算有多少条不同的路径 从后往前找最短路, 对于每一步要更新之后走的位置值: #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> using namespace s

uva 10917

Problem C: A Walk Through the Forest 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

uva 10917 Walk Through the Forest(最短路)

uva 10917 Walk Through the Forest gbn最近打算穿过一个森林,但是他比较傲娇,于是他决定只走一些特殊的道路,他打算只沿着满足如下条件的(A,B)道路走:存在一条从B出发回家的路,比所有从A出发回家的路径都短.你的任务是计算一共有多少条不同的回家路径.其中起点的编号为1,终点的编号为2. Input 多组数据输入,每组数据第一行输入n,m(1<=n<=1000)表示点的数目和边的数目,点的编号为1~n,接下来m行每行输入3个数a,b,c表示有一条双向道路连接a,

UVA 10917 - Walk Through the Forest(dijstra)

UVA 10917 - Walk Through the Forest 题目链接 题意:公司编号为1,家编号为2,每次回家都不走回头路,回头路定义为:满足条件的道路(A,B),满足存在一条从B出发比所有从A出发的回家的路径都短,问有几种走法 思路:先从家求dijstra,这样满足条件的道路就是d[A] > d[B],这个图是一个dag,在上面进行dp就可以找出种数了 代码: #include <cstdio> #include <cstring> #include <v

训练指南 UVA - 10917(最短路Dijkstra + 基础DP)

layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - 基础DP - Dijkstra - 图论 - 训练指南 Walk Through the Forest UVA - 10917 题意 Jimmy打算每天沿着一条不同的路走,而且,他只能沿着满足如下条件的道路(A,B):存在一条从B出发回家的路径,比

UVA 10917 Walk Through the Forest(Dijkstra+DAG动态规划)

题意:gbn最近打算穿过一个森林,但是他比较傲娇,于是他决定只走一些特殊的道路,他打算只沿着满足如下条件的(A,B)道路走:存在一条从B出发回家的路,比所有从A出发回家的路径都短.你的任务是计算一共有多少条不同的回家路径.其中起点的编号为1,终点的编号为2. 思路:首先从终点Dijkstra一次,求出每个点u回家的最短路长度,那么相当于创建了一个新图,当d[B]<d[A]时有一条A指向B的有向边,则题目的目标就是求出起点到终点的路径条数.因为这个图是DAG,可以用动态规划求解. #include

UVa 10917 A Walk Through the Forest

A Walk Through the Forest Time Limit:1000MS  Memory Limit:65536K Total Submit:48 Accepted:15 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 t

UVa 10596 清晨漫步

题意:有很多路,问能否每条路只走一遍.恰好回到起点? 思路:无向图的欧拉回路的应用.但是是神坑的一道题~ 注意:考虑下面的数据 Input: 3 2 0 1 1 0 2 2 1 0 1 0 4 4 0 1 1 0 2 3 3 2 5 6 0 1 1 0 2 3 2 3 0 2 2 0 4 6 1 2 2 1 2 3 2 3 3 1 1 3 2 0 Output: Possible Possible Not Possible Possible Possible Not Possible 也就是说,

G - Walk Through the Forest (UVA - 10917)

- 题目大意 一个人,他只会沿着如下条件的道路(A,B)走:存在一条从B出发回家的路径,比所有从A出发回家的路径都要短.我们的任务是要找出一共有有多少条不同的回家路径. - 解题思路 先用dijkstra预处理出终点到每个点的最短路,然后将满足行走条件的A.B(除行走条件外,还要满足一个前提,即A.B之间要有边)用一条有向边连起来(A->B),然后利用记忆化搜索来解决这个问题. - 代码 #include<cstdio> #include<cstring> #include&