【解题报告】HDU -1142 A Walk Through the Forest
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1142
题目大意:Jimmy要从办公室走路回家,办公室在森林的一侧,家在另一侧,他每天要采取不一样的路线回家。由于他要尽快回家,他在选择路线的时候总是要越来越靠近他家。计算符合条件的路线一共有几种。
解题思路:题目要求“路线要越来越靠近家”,也就是说每次选择下一个结点的时候距离家的距离比当前的结点近。首先该结点离家的距离就是该节点到家的最短路径的长度。所以我们先求出所有节点到家的最短路径。(Dijkstra算法)
然后从办公室出发,选择路径的时候要选择相邻且距离更近的点作为下一个点,利用DFS遍历。当前结点的路径条数等于下一个所有可能的结点的路径的总和。而终点的路径为1。
附上代码:
#include<stdio.h> #define MaxVertexNum 1000 /*顶点数*/ #define MaxWeight 1147483647 typedef int weight; weight w[MaxVertexNum][MaxVertexNum]={0};/*边的关系*/ int d[MaxVertexNum]; int dfs[MaxVertexNum]; /*两点的最短路径*/ void ShortestPath(int vertexnum,int m) /*从m节点出发,p数组保存路径,d数组保存长度*/ { int v,min,i,j; int bo[MaxVertexNum]; for(v=0;v<vertexnum;v++) { bo[v]=0; d[v]=w[m][v]; } d[m]=0; bo[m]=1; for(i=1;i<vertexnum;i++) { min=MaxWeight; for(j=0;j<vertexnum;j++) /*v最近*/ if(!bo[j]&&d[j]<min) {v=j;min=d[j];} bo[v]=1; for(j=0;j<vertexnum;j++) { if(!bo[j]&&min+w[v][j]<d[j]) { d[j]=min+w[v][j]; } } } } /*根据边的关系输入*/ void input_AdjacencyMatrix(int n) { int i,j; while(n--) { scanf("%d%d",&i,&j); scanf("%d",&w[i-1][j-1]); /*输入权值*/ w[j-1][i-1]=w[i-1][j-1]; } } int DFS(int n,int vertexnum)/*表示n节点到1节点的路径数*/ { int i,s; if(n==1) return 1;/*结束条件*/ if(dfs[n]!=-1) return dfs[n];/*如果已经计算过则直接调用*/ s=0; for(i=0;i<vertexnum;i++) { if(w[n][i]!=MaxWeight&&d[n]>d[i])/*相邻且距离更近*/ { s+=DFS(i,vertexnum);/*路径数的和*/ } } dfs[n]=s;/*保存当前遍历结果*/ return s; } int main() { int i,j,vertexnum,n; /*freopen("yx.txt","r",stdin);*/ while(1) { scanf("%d",&vertexnum); if(vertexnum==0) return 0; scanf("%d",&n); for(i=0;i<vertexnum;i++) for(j=0;j<vertexnum;j++) w[i][j]=MaxWeight;/*无穷大*//*初始化*/ input_AdjacencyMatrix(n); ShortestPath(vertexnum,1); for(i=0;i<vertexnum;i++) dfs[i]=-1; printf("%d\n",DFS(0,vertexnum)); } return 0; }