0w1

UVA 10917 Walk Through the Forest ( Dijkstra + DP )

UVa Online Judge
用 Dijkstra 求一次從家裡到各個點的單源最短路徑,則所求是公司到家的路徑數,可走的有向邊只存在於滿足 DIjkstra 求出的 dis[ v ] < dis[ u ] 時的 u -> v,很明顯是個 DAG,用 DP 隨便處理就行了。

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int MAXN = 1e3 + 3;
const int INF = 1e9;

int n, m;
vector<pii> G[MAXN];

int vis[MAXN];
void dijkstra(int s, int *d){
    priority_queue<pii, vector<pii>, greater<pii> > pq;
    pq.push( pii( 0, s ) );
    fill( d, d + MAXN, INF );
    d[s] = 0;
    fill( vis, vis + MAXN, 0 );
    while( !pq.empty() ){
        int u = pq.top().second; pq.pop();
        if( vis[ u ] ) continue;
        vis[ u ] = 1;
        for(pii z: G[ u ]){
            int c = z.first, v = z.second;
            if( d[ v ] > d[ u ] + c ){
                d[ v ] = d[ u ] + c;
                pq.push( pii( d[ v ], v ) );
            }
        }
    }
}

int dis[MAXN];
int way[MAXN];
int dp(int u){
    int &ans = way[u];
    if( ans != -1 ) return ans;
    if( u == 2 ) return ans = 1;
    ans = 0;
    for(int i = 0; i < G[u].size(); ++i){
        int v = G[u][i].second;
        if( dis[ v ] < dis[ u ] )
            ans += dp( v ); // transferable
    }
    return ans;
}

void solve(){
    dijkstra( 2, dis );
    memset( way, -1, sizeof(way) );
    printf("%d\n", dp( 1 ));
}

void init(){
    for(int i = 1; i <= n; ++i)
        G[i].clear();
}

int main(){
    while( scanf("%d%d", &n, &m) == 2 ){
        init();
        for(int i = 0; i < m; ++i){
            int a, b, c; scanf("%d%d%d", &a, &b, &c);
            G[ a ].push_back( pii( c, b ) );
            G[ b ].push_back( pii( c, a ) );
        }
        solve();
    }
    return 0;
}