本来就是水题一道。

题意:一个人要从点1去到点2,中间还有很多点和很多条边。问你如果他每次走的边(a,b)都满足:a点到目标点的最短距离<b点到目标点的最短距离,那么他从点1出发到点2总共有多少条路径。

思路:先用Dijkstra求最短路,然后创一个图,对于满足条件的边(a,b)就加一条有向边,由于是严格按照小于加的边,图中绝对没有环,是个DAG。接下来dp就行了。

dp[i]表示i点出发有多少条路径,dp[i]=sum(dp[j])。

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

UVa 10917 Dijkstra的更多相关文章

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

    layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: tr ...

  2. UVA - 10917 - Walk Through the Forest(最短路+记忆化搜索)

    Problem    UVA - 10917 - Walk Through the Forest Time Limit: 3000 mSec Problem Description Jimmy exp ...

  3. uva 10806 Dijkstra, Dijkstra. (最小费最大流)

    uva 10806 Dijkstra, Dijkstra. 题目大意:你和你的伙伴想要越狱.你的伙伴先去探路,等你的伙伴到火车站后,他会打电话给你(电话是藏在蛋糕里带进来的),然后你就能够跑去火车站了 ...

  4. UVA 10917 Walk Through the Forest(dijkstra+DAG上的dp)

    用新模板阿姨了一天,换成原来的一遍就ac了= = 题意很重要..最关键的一句话是说:若走A->B这条边,必然是d[B]<d[A],d[]数组保存的是各点到终点的最短路. 所以先做dij,由 ...

  5. UVA 10917 Walk Through the Forest SPFA

    uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem= ...

  6. Uva 10917

    题目链接:http://vjudge.net/contest/143062#problem/A 题意:一个人要从点1去到点2,中间还有很多点和很多条边.问你如果他每次走的边(a,b)都满足:a点到目标 ...

  7. UVa 658 (Dijkstra) It's not a Bug, it's a Feature!

    题意: 有n个BUG和m个补丁,每个补丁用一个串表示打补丁前的状态要满足的要求,第二个串表示打完后对补丁的影响,还有打补丁所需要的时间. 求修复所有BUG的最短时间. 分析: 可以用n个二进制位表示这 ...

  8. UVa 10806 Dijkstra,Dijkstra(最小费用最大流)

    裸的费用流.往返就相当于从起点走两条路到终点. 按题意建图,将距离设为费用,流量设为1.然后增加2个点,一个连向节点1,流量=2,费用=0;结点n连一条同样的弧,然后求解最小费用最大流.当且仅当最大流 ...

  9. uva 11367 (Dijkstra+DP)

    题意:一辆汽车在一张无向图中开告诉你每个城市加油的费用.每次给q个查询(起点,终点,油箱容量)问你最小花费是多少. 思路:一道Dijkstra状态的题目.在这种最短路问题中一维的dis数组记录的信息往 ...

随机推荐

  1. 【Leetcode】Longest Palindromic Substring

    问题:https://leetcode.com/problems/longest-palindromic-substring/ 给定一个字符串 S,求出 S 的最长回文子串 思路: 1. 回文:一个字 ...

  2. JVM内存区域异常分析

    在Java虚拟机规范描述中,除程序计数器外,其他几个运行时区域都有可能发生OutOfMemoryError异常.接下来将对各区域分别进行分析介绍,内容包括触发各区域OutOfMemoryError异常 ...

  3. 《将博客搬至CSDN》

    http://www.cnblogs.com/duenyang  两个博客一起用,大家也可以去我CSDN博看查看.

  4. stl循环删除

    struct st_data { st_data(int i) : id(i) {} int id; }; 对于STL标准序列容器vector/deque/list(以vector为例) 当我们需清空 ...

  5. iOS WKWebView的javascript alert 不弹的解决方案

    - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiate ...

  6. java synchronized详解

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...

  7. try{}、catch(){}、throw语句

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  8. Swift 必备开发库10个

    1.CryptoSwift swift加密库, 支持md5,sha1,sha224,sha256... github地址: https://github.com/krzyzanowskim/Crypt ...

  9. WordPress基础:订阅源rss的使用

    设置->阅读,可设置rss显示效果 RSS源为:http://wordpress目录/feed 把这个地址放入你的rss阅读器进行订阅即可,最简单的就是使用QQ邮箱里面的阅读空间进行订阅.

  10. cloudera learning2:HDFS

    存入HDFS的文件会按块(block)划分,默认每块128MB.默认1个block还有2个备份.备份增加了数据的可靠性和提高计算效率(数据本地化). HDFS部署可选择不支持HA,也可选择支持HA. ...