标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7733 Accepted Submission(s): 2851
5 6 1 3 2 1 4 2 3 4 3 1 5 12 4 2 34 5 2 24 7 8 1 3 1 1 4 1 3 7 1 7 4 1 7 5 1 6 7 1 5 2 1 6 2 1 0
题目意思是说一个人要从上班的地方回到家里,途中会经过一些地方,按下面规则问他回家会有几种路线:
题目已经定义好1为上班地方2为家,每个地点之间的距离都已经知道,哪么如果从A到B的一条路,可以走的条件
是B到2(家)的路程必须小于从A到2(家)的路程,其实就是A到家的最短路径必须大于B到家的最短路径。
默认一定可以走到家,也就是一定会有一种路线。最后是让你计算有几种路线。可以用迪杰斯特拉算法找一下所有点到终点的最短路,然后DFS搜一下就行了。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #define mod 1000000007 #define inf 0x3f3f3f3f #define pi acos(-1.0) using namespace std; typedef long long ll; const int N=1005; int n;//十字路口数 int w[1001][1001]; int dist[1001],dp[1001]; int s[1001]; void dijkstra(int v)//迪杰斯特拉算法 { int i,j,mins,index; for(i=1; i<=n; i++) { dist[i] = w[i][v]; s[i] = 0; } dist[v] = 0; s[v] = 1; for(i=1; i<n; i++) { mins = 2000000; for(j=1; j<=n; j++) { if(s[j]==0 && dist[j]<mins) { mins = dist[j]; index = j; } } if(mins == 2000000)//注意 若没有 会在中间溢出 break; s[index] = 1; for(j=1; j<=n; j++) { if(s[j]==0 && dist[j]>dist[index]+w[j][index]) dist[j] = dist[index]+w[j][index]; } } } int dfs(int v)//记忆法深搜 { if(dp[v] != -1) return dp[v]; if(v == 2) return 1; int i,temp,sum=0; for(i=1; i<=n; i++) { if(w[v][i]!=2000000 && dist[v] > dist[i])//有路相通而且要去的i点到终点站的距离要比v到终点站的距离小 { temp = dfs(i); sum += temp; } } dp[v] = sum; return sum; } int main() { while(cin>>n && n) { int i,j,d,m; cin>>m; for(i=1; i<=n; i++) { dp[i] = -1; for(j=1; j<=n; j++) w[i][j] = 2000000; } while(m--) { scanf("%d%d%d",&i,&j,&d); w[i][j] = w[j][i] = d;//无向图 } //求出各点到终点站的最短距离 dijkstra(2);//2为终点站 dfs(1);//从1出发 cout<<dp[1]<<endl; } return 0; }
HDU1142 A Walk Through the Forest(dijkstra)
标签:
原文地址:http://www.cnblogs.com/jianrenfang/p/5723429.html