zoukankan      html  css  js  c++  java
  • 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
    ", t.dp[0]);
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    深度通道编程模型
    缓冲区溢出实验实验楼
    团队作业(一)
    信安导论学习阶段性总结
    Python总结
    mysql下载及安装
    初识python
    MobileMenuScene来点动画效果
    移动菜单页面PlayerInput
    渲染和填充MobileMenuListItem
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6664957.html
Copyright © 2011-2022 走看看