Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2183 Accepted Submission(s): 787
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
2 4
题目大意:寻找一共有多少条符合题意的路。能够从点A走到点B的要求是:点A到终点的最短路 > 点B到终点的最短路。 也就是说:从终点出发,求每一个点的最短路,然后那些最短路的值记录起来,作为能否通过的判断条件。最后用记忆化搜索来搜索出一共多少条符合要求的路。普通的dfs是超时的,bfs是超内存的。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1142
代码:
#include <iostream> #include <stdio.h> #include <memory.h> #include <queue> #include <vector> using namespace std; const int INF = 99999999; const int N = 1005; vector<int> road[N]; //定义一个向量(第一次用-O(∩_∩)O-) int map[N][N], dist[N], s[N]; bool visit[N]; int n, t, sum; void init() { int i, j; sum = 0; memset(s, 0, sizeof(s)); for(i = 0; i <= n; i++) road[i].clear(); for(i = 0; i <= n; i++) for(j = 0; j <= n; j++) if(i == j) map[i][j] = 0; else map[i][j] = INF; } void input() { int a, b, d; while(t--) { scanf("%d %d %d", &a, &b, &d); if(d < map[a][b]) { map[a][b] = map[b][a] = d; //双向的 road[a].push_back(b); road[b].push_back(a); } } } void spfa() //比较喜欢用spfa { int i, now; memset(visit, false, sizeof(visit)); for(i = 1; i <= n; i++) dist[i] = INF; dist[2] = 0; queue<int> Q; Q.push(2); visit[2] = true; while(!Q.empty()) { now = Q.front(); Q.pop(); visit[now] = false; for(i = 1; i <= n; i++) { if(dist[i] > dist[now] + map[now][i]) { dist[i] = dist[now] + map[now][i]; if(visit[i] == false) { Q.push(i); visit[i] = true; } } } } } int dfs(int now) //记忆化搜索 { int i; if(now == 2) return 1; //找到终点,返回1(1条路) if(s[now]) return s[now]; //该点已经走过,返回:过该点有多少条路 for(i = 0; i < road[now].size(); i++) { if(dist[now] > dist[ road[now][i] ]) { s[now] += dfs(road[now][i]); } } return s[now]; //返回:该点一共可以有多少条路 } int main() { while(scanf("%d", &n), n) { scanf("%d", &t); init(); input(); spfa(); sum = dfs(1); //sum一共多少条路,sum = s[1] 也行 printf("%d\n", sum); } return 0; }