A Walk Through the Forest

http://acm.hdu.edu.cn/showproblem.php?pid=1142

题解:

看样子很多人都把这题目看错了,以为是求最短路的条数。真正的意思是:假设 A 和 B 是相连的,当前在 A 处,如果 A 到终点的距离大于 B 到终点的距离,

则可以从 A 通往 B 处,问满足这种的条件的路径条数。

分析:

1、以终点 2 为起点 dijkstra;

 2、直接DFS记忆化搜索。

/*
*@Author:   STZG
*@Language: C++
*/
//#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
//#include<map>
#include<set>
//#define DEBUG
#define RI register int
using namespace std;
typedef long long ll;
typedef __int128 lll;
const int N=1010;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,q;
int map[N][N];
bool vis[N];
int dist[N];
int p[N];
void init(){
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            map[i][j]=(i==j?0:INF);
    memset(p,0,sizeof(p));
    memset(vis,false,sizeof(vis));
    memset(dist,0,sizeof(dist));
}
void Dijkstra(){
    for(int i=1;i<=n;i++){
        dist[i]=map[2][i];
    }
    dist[2]=0;
    vis[2]=1;
    for(int i=1;i<n;i++){
        int minl=INF,k=0;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&dist[j]<minl){
                minl=dist[j];
                k=j;
            }
        }
        if(k==0)
            break;
        vis[k]=1;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&dist[j]>map[k][j]+minl){
                dist[j]=map[k][j]+minl;
            }
        }
    }
}
int DFS(int s){
    if(p[s])return p[s];
    if(s==2)return 1;
    int sum=0;
    for(RI i=1;i<=n;i++){
        if(map[s][i]<INF&&dist[s]>dist[i]){
            if(p[i])
                sum+=p[i];
            else
                sum+=DFS(i);
        }
    }
    p[s]+=sum;
    return p[s];
}
int main()
{
#ifdef DEBUG
	freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
#endif
    while(~scanf("%d",&n)&&n){
        scanf("%d",&m);
        init();
        int a,b,d;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&d);
            map[a][b]=map[b][a]=d;
        }
        Dijkstra();
        cout<<DFS(1)<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}

 

全部评论

相关推荐

03-26 13:04
已编辑
电子科技大学 算法工程师
xiaowl:你这个简历“条目上”都比较有深度性,但是实际上面试官又没法很好的评估你是怎么达到很多看上去很厉害的结果的。要避免一些看上去很厉害的包装,比如高效的内存复用策略的表达,如果仅是简单的一些内存共享机制,而且面试上也没有深挖的空间,就不要这样表达。比如,工程化模式本质上可能就是定义了一些abstract class,那也就没特别多值得讲的内容。建议简历上应该侧重那些你花了大量时间和精力解决、研究的问题,不要过分追求“丰富”,而是关注在技术深入度、问题解决能力的表现上。
没有实习经历,还有机会进...
点赞 评论 收藏
分享
UtopianYou...:这个简历排版真的不太行哦,去找免费的或者花点小钱,把排版弄整齐一点吧,看着舒服。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务