Uva10917 Walk Through the Forest

题目链接:https://vjudge.net/problem/UVA-10917

题目意思:Jimmy下班回家要闯过一下森林,劳累一天后在森林中散步是非常惬意的事,所以他打算每天沿着一条不同的路径回家,欣赏不同的风景,但他也不太想太晚回家,因此他不打算走回头路。换句话来说,他只会沿着如下条件的道路(A,B)走:存在一条从B出发回家的路径,比所有从A出发回家的路径都要短。我们的任务是要找出一共有有多少条不同的回家路径,家的编号是2,公司的编号是1。

题目思路:最短路+dp,我们现在考虑如何dp,由于从B回家的路比所有从A回家的路都短,所以如果从2出发跑一遍最短路,如果我们重新建一个图了话,如果原图中存在边,且dist[A]>dist[B]的两个AB之间需要建一条边。现在我们dp,考虑子结构,从x点回家的所有路径是多少?应该是点x的边集中所有dist[y]>dist[x]的点y,回家路径的和。也就说当这些y的回家路径确定了以后x回家的路径的数量才确定。所以我们实际上是跑以2为起点的最短路,以2为起点开始的dfs。直接看代码吧!

代码:

 1 //Author: xiaowuga
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 #define inf 0x3f3f3f3f
 5 #define MAX INT_MAX
 6 #define mem(s,ch) memset(s,ch,sizeof(s))
 7 const long long N=2000; 
 8 const long long mod=1e9+7; 
 9 typedef long long LL;
10 typedef int II;
11 typedef unsigned long long ull;
12 #define nc cout<<"nc"<<endl
13 #define sp " "
14 II n,m;
15 vector<pair<II,II> >G[N];
16 II d[N];
17 II path[N],done[N];
18 void Dijkstra(II s,II t){
19     II vis[N];
20     mem(d,inf);mem(vis,0);
21     d[s]=0;
22     priority_queue<pair<II,II> >Q;
23     Q.push(make_pair(-d[s],s));//由于优先队列默认是大顶堆,我们直接放入一个负数就可以了。
24     while(!Q.empty()){
25         II now=Q.top().second;
26         Q.pop();
27         if(vis[now]) continue;
28         vis[now]=1;
29         for(II i=0;i<G[now].size();i++){
30             II v=G[now][i].first,w=G[now][i].second;
31             if(d[v]>d[now]+w){
32                 d[v]=d[now]+w;
33                 Q.push(make_pair(-d[v],v));
34             }
35         }
36     }
37 }
38 II dfs(II u){
39    if(path[u]!=-1) return path[u]; 
40    path[u]=0;
41    for(II i=0;i<G[u].size();i++){
42        II v=G[u][i].first;
43        if(d[u]<d[v]){
44           path[u]+=dfs(v); 
45        }
46    }
47    return path[u];
48 }
49 int main() {
50     ios::sync_with_stdio(false);cin.tie(0);
51     while(cin>>n&&n){
52         cin>>m;
53         for(II i=1;i<=n;i++) G[i].clear();
54         for(II i=0;i<m;i++){
55             II a,b,d;
56             cin>>a>>b>>d;
57             G[a].push_back(make_pair(b,d));
58             G[b].push_back(make_pair(a,d));
59         }
60         Dijkstra(2,1);
61         //for(II i=1;i<=n;i++) cout<<d[i]<<' '; cout<<endl;
62         mem(path,-1);path[1]=1;
63         II ans=dfs(2);    
64         cout<<ans<<endl;
65     }
66     return 0;
67 }
View Code

 

posted on 2017-10-06 14:10  xiaowuga  阅读(390)  评论(0编辑  收藏  举报

导航