1142A Walk Through the Forest

题目大意:

公司和家之间隔着一片森林,回家的路有多条,但是每两个岔路口之间只有一条直通的路,如果从公司出发,走a->b这条路的前提是a到家的距离要比b到家的距离远。现在问你最多有多少种走法!

解题思路:

       没认真分析完题目就开始写代码的都是瞎搞,分析完题目后不认真写代码的都是扯淡,出现bug后只会找关键点错误的更是傻逼,为了赋值的时候多写了个==找了大半天,oh!no!. 

      本题其实就是先利用dijkstra,spfa,bellman中的任意一种先计算出各个点到家的最短路,然后dfs出所有满足条件的可能即可!

#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
#define N 1005
#define inf 0x3fffffff
using namespace std;
struct node{
  int v;
  int dis;
};
int dis[N],dp[N];
vector<node>G[N];
bool in_s[N];
struct cmp
{
    bool operator()(int a,int b)
    {
        return dis[a]>dis[b];
    }
};
void spfa(int st,int n){
     int ui,vi,i,cur,di;
     for(i=0;i<=n;i++){
              dis[i]=inf;
              in_s[i]=false;
     }
     priority_queue<int,vector<int>,cmp> s;
     s.push(st);
     in_s[st]=true;
     dis[st]=0;
     while(!s.empty()){
            cur=s.top();
            s.pop();
            in_s[cur]=false;//这个等号找了半天,啥也不说了!
            for(i=0;i<G[cur].size();i++){
                 vi=G[cur][i].v;
                 di=G[cur][i].dis;
                    if(dis[vi]>dis[cur]+di){
                        dis[vi]=dis[cur]+di;
                        if(!in_s[vi]){
                            in_s[vi]=true;
                            s.push(vi);
                        }
                    }
              }
       }
}
int dfs(int vi){
    if(vi==2)
        return 1;
    if(dp[vi]>0)
        return dp[vi];
    for(int i=0;i<G[vi].size();i++){
        int to=G[vi][i].v;
        if(dis[vi]>dis[to]){
            dp[vi]+=dfs(to);
        }
    }
    return dp[vi];
}
int main()
{
   int n,m,a,b,d,i,j;
   node temp;
   while(scanf("%d",&n)&&n){
      scanf("%d",&m);
      for(i=0;i<=n;i++)
              G[i].clear();
      for(i=1;i<=m;i++)
      {
        scanf("%d%d%d",&a,&b,&d);
        temp.dis=d;
        temp.v=a;
        G[b].push_back(temp);
        temp.v=b;
        G[a].push_back(temp);
     }
     spfa(2,n);
     memset(dp,0,sizeof(dp));
     printf("%d\n",dfs(1));

}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值