题意:jimmy下班需要穿过一个森林。劳累一天后在森林中漫步是见非常惬意的事,所以他打算每天沿着不同的路径回家,欣赏不同的风景。但他也不想太晚回家,因此他不打算走回头路。换句话说,他只沿(A,B)走,存在一条从B出发回家的路径比所有从A出发回家的路径都短。你的任务是计算一共有多少条不同的回家路径
分析:用dijkstra计算家到各个点的最短路径,则当d[i]>d[j],则有一条i-->j的路可走,因此形成了一个新图,且是DAG图。故可用动态规划计算方案。(使用记忆化搜索)
// File Name: 2662.cpp // Author: zlbing // Created Time: 2013/2/6 18:48:14 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define MAXN 1050 const int INF=1e9; struct Edge{ int from,to,dist; }; struct HeapNode{ int d,u; bool operator <(const HeapNode &rhs)const{ return d>rhs.d; } }; struct Dijkstra{ int n,m;//点和边数 vector<Edge>edges;//边列表 vector<int>G[MAXN];//每个节点出发的边编号(从0开始编号) bool done[MAXN];//是否永久标记 int d[MAXN];//s到各个点的距离 int p[MAXN];//最短路中的上一条边 void init(int n) { this->n=n; for(int i=0;i<n;i++)G[i].clear();//清空邻接表 edges.clear();//清空边表 } void AddEdge(int from,int to,int dist) { //如果是无向图,每条无向边需调用2次AddEdge edges.push_back((Edge){from,to,dist}); m=edges.size(); G[from].push_back(m-1); } void dijkstra(int s) {//求s到所有点的距离 priority_queue<HeapNode> Q; for(int i=0;i<n;i++)d[i]=INF; d[s]=0; memset(done,0,sizeof(done)); Q.push((HeapNode){0,s}); while(!Q.empty()) { HeapNode x=Q.top();Q.pop(); int u=x.u; if(done[u])continue; done[u]=true; for(int i=0;i<G[u].size();i++) { Edge& e=edges[G[u][i]]; if(d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; Q.push((HeapNode){d[e.to],e.to}); } } } } }; Dijkstra solver; int M,N; int d[MAXN]; int g[MAXN][MAXN]; int dfs(int u) { if(d[u]!=-1)return d[u]; d[u]=0; for(int i=0;i<N;i++) { if(g[i][u]) d[u]+=dfs(i); } return d[u]; } int main(){ while(~scanf("%d",&N)) { if(N==0)break; solver.init(N); scanf("%d",&M); int a,b,c; for(int i=0;i<M;i++) { scanf("%d%d%d",&a,&b,&c); a--,b--; solver.AddEdge(a,b,c); solver.AddEdge(b,a,c); } solver.dijkstra(1); memset(d,-1,sizeof(d)); memset(g,0,sizeof(g)); d[0]=1; for(int i=0;i<solver.edges.size();i++) { Edge& e=solver.edges[i]; int u=e.from,v=e.to; if(solver.d[u]>solver.d[v]) { g[u][v]=1; } } int ans=dfs(1); printf("%d\n",ans); } return 0; }