zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Mysql注入绕过姿势
    轻松入侵我学校网站
    华科机考:矩阵转置
    浙大patB习题的一点总结
    链表的一些基本操作
    关于C中函数传参的一点理解
    Java与JavaScript中判断两字符串是否相等的区别
    Jsp中out.println()与System.out.println()的区别
    eclipse背景主题
    Kruskal算法的简单实现
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7631490.html
Copyright © 2011-2022 走看看