HDu-1142-A Walk Through the Forest
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1142
程序分析:
题目意思是说一个人要从上班的地方回到家里,途中会经过一些地方,按下面规则问他回家会有几种路线:
题目已经定义好1为上班地方2为家,每个地点之间的距离都已经知道,哪么如果从A到B的一条路,可以走的条件
是B到2(家)的路程必须小于从A到2(家)的路程,其实就是A到家的最短路径必须大于B到家的最短路径。
默认一定可以走到家,也就是一定会有一种路线。最后是让你计算有几种路线。
解决方法:
因为有一个固定的起点,哪么就可以用dijkstra算法计算出每一个地点到家的最短路径,然后用DFS回溯求出
路线的数目。可以进行下一次递归调用的是A点必须跟B点有直接通路,回溯时数目加一;递归停止条件是B=2(家)。
从1(公司)开始走(调用)DFS(1);一些路径的存储就是无向图那样吧。也许会有重边(也就是两个地方有多条直接通路),有判断了就不用管它有没有了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 4 const int Max = 1005; 5 const int INF = 1<<30; 6 bool used[Max]; 7 int dis[Max]; 8 int map[Max][Max]; 9 int n, m; 10 int ans[Max]; 11 12 void Make_set() 13 { 14 for(int i=0; i<=n; i++) 15 { 16 dis[i] = INF; 17 for(int j=0; j<=n; j++) 18 { 19 map[i][j] = map[j][i] = INF; 20 if(i == j) 21 map[i][j] = 0; 22 } 23 } 24 memset(used, false, sizeof(used)); 25 memset(ans, 0, sizeof(ans)); 26 } 27 28 void dijkstra(int a) 29 { 30 31 dis[a] = 0; 32 int minNode; 33 //used[a] = true; 34 for(int cnt=1; cnt<=n; cnt++) 35 { 36 minNode = 0; 37 int min = INF; 38 for(int i=1; i<=n ;i++) 39 { 40 if(!used[i] && dis[i]<min) 41 { 42 min = dis[i]; 43 minNode = i; 44 } 45 } 46 //if(minNode == -1) 47 //break; 48 used[minNode] = true; 49 for(int j=1; j<=n ;j++) 50 { 51 if(!used[j] && dis[j]>dis[minNode]+map[j][minNode]) 52 { 53 dis[j] = dis[minNode]+map[j][minNode]; 54 } 55 } 56 } 57 } 58 59 int DFS(int k) 60 { 61 if(ans[k]) 62 return ans[k]; 63 if(k == 2) 64 return 1; 65 for(int i=1; i<=n; i++) 66 { 67 if(map[i][k]!=INF && dis[k]>dis[i]) 68 ans[k]+=DFS(i); 69 } 70 return ans[k]; 71 } 72 73 int main() 74 { 75 int a, b, c; 76 while(cin>>n && n && cin>>m) 77 { 78 Make_set(); 79 for(int i=0; i<m; i++) 80 { 81 cin>>a>>b>>c; 82 if(map[a][b]>c) 83 { 84 map[a][b] = map[b][a] = c; 85 } 86 } 87 dijkstra(2); 88 cout<<DFS(1)<<endl; 89 } 90 return 0; 91 }