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 }