1. 程式人生 > >A Walk Through the Forest

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;
}