标签:
求出家到其他点的最短路径,题目的条件变成了u->v不是回头路当且仅当d[u]>d[v]。然后根据这个条件建DAG图,跑dp统计方案数,dp[u] = sum(dp[v])。
#include<bits/stdc++.h> using namespace std; const int maxn = 1001, maxm = 2002; struct Edge { int v,w,nxt; }; #define PB push_back vector<Edge> edges; vector<int> G[maxn]; int head[maxn]; int d[maxn]; void addEdge(int u,int v,int w) { edges.PB({v,w,head[u]}); head[u] = edges.size()-1; } void init() { memset(head,-1,sizeof(head)); edges.clear(); } typedef pair<int,int> Node; #define fi first #define se second void dijkstra(int s = 1) { memset(d,0x3f,sizeof(d)); priority_queue<Node,vector<Node>,greater<Node> > q; q.push(Node(d[s] = 0,s)); while(q.size()){ Node x = q.top(); q.pop(); int u = x.se; if(x.fi != d[u]) continue; for(int i = head[u]; ~i ; i = edges[i].nxt){ Edge &e = edges[i]; if(d[e.v] > d[u]+e.w){ d[e.v] = d[u]+e.w; q.push(Node(d[e.v],e.v)); } } } } int dp[maxn]; int dfs(int u) { int &ans = dp[u]; if(~ans) return ans; if(u == 1) return ans = 1; ans = 0; for(int i = 0; i < (int)G[u].size(); i++){ ans += dfs(G[u][i]); } return ans; } void rebuild(int n) { for(int i = 0; i < n; i++) G[i].clear(); for(int u = 0; u < n; u++){ for(int i = head[u]; ~i; i = edges[i].nxt){ int v = edges[i].v; if(d[v] < d[u]) G[u].PB(v); } } } int main() { //freopen("in.txt","r",stdin); int n,m; while(scanf("%d%d",&n,&m),n){ init(); while(m--){ int u,v,w; scanf("%d%d%d",&u,&v,&w); u--;v--; addEdge(u,v,w); addEdge(v,u,w); } dijkstra(); rebuild(n); memset(dp,-1,sizeof(dp)); printf("%d\n",dfs(0)); } return 0; }
UVA10917 A walk trough the Forest
标签:
原文地址:http://www.cnblogs.com/jerryRey/p/4779264.html