HDU1142 (Dijkstra+记忆化搜索)
2015-10-23 15:33
288 查看
A Walk Through the Forest
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6935 Accepted Submission(s): 2548
The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take. Input Input contains several test cases followed by a line containing 0. Jimmy has numbered each intersection or joining of paths starting with 1. His office is numbered 1, and his house is numbered 2. The first line of each test case gives the number of intersections N, 1 < N ≤ 1000, and the number of paths M. The following M lines each contain a pair of intersections a b and an integer distance 1 ≤ d ≤ 1000000 indicating a path of length d between intersection a and a different intersection b. Jimmy may walk a path any direction he chooses. There is at most one path between any pair of intersections. Output For each test case, output a single integer indicating the number of different routes through the forest. You may assume that this number does not exceed 2147483647 Sample Input 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 Sample Output 2 4 Source University of Waterloo Local Contest 2005.09.24 题意是求从起点1到终点2的满足条件的路径条数,条件是该条路径上的所有边AB都要满足A到终点的最短路大于B到终点的最短路。 思路就是Dijkstra+记忆化搜索
/* ID: LinKArftc PROG: 1142.cpp LANG: C++ */ #include <map> #include <set> #include <cmath> #include <stack> #include <queue> #include <vector> #include <cstdio> #include <string> #include <utility> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define eps 1e-8 #define randin srand((unsigned int)time(NULL)) #define input freopen("input.txt","r",stdin) #define debug(s) cout << "s = " << s << endl; #define outstars cout << "*************" << endl; const double PI = acos(-1.0); const double e = exp(1.0); const int inf = 0x3f3f3f3f; const int INF = 0x7fffffff; typedef long long ll; const int maxn = 1010; int n, m; int mp[maxn][maxn]; int dis[maxn]; bool vis[maxn]; void dij(int s) { for (int i = 1; i <= n; i ++) dis[i] = mp[s][i]; memset(vis, 0, sizeof(vis)); vis[s] = true; dis[s] = 0; for (int i = 2; i <= n; i ++) { int mi = inf; int ii = s;//要赋值,因为下一行的for循环可能并不改变ii的值,所以可能会RE for (int j = 1; j <= n; j ++) { if (!vis[j] && dis[j] < mi) { mi = dis[j]; ii = j; } } vis[ii] = true; for (int j = 1; j <= n; j ++) { if (!vis[j] && dis[j] > dis[ii] + mp[ii][j]) { dis[j] = dis[ii] + mp[ii][j]; } } } } int cnt[maxn]; int dfs(int cur) { if (cnt[cur]) return cnt[cur]; if (cur == 2) return 1; int ret = 0; for (int i = 1; i <= n; i ++) { if (mp[cur][i] == inf || dis[i] >= dis[cur]) continue; ret += dfs(i); } cnt[cur] = ret; return ret; } int main() { //input; int u, v, c; while (~scanf("%d", &n) && n) { scanf("%d", &m); memset(mp, 0x3f, sizeof(mp)); for (int i = 1; i <= m; i ++) { scanf("%d %d %d", &u, &v, &c); mp[u][v] = c; mp[v][u] = c; } dij(2); //for (int i = 1; i <= n; i ++) printf("dis[%d] = %d\n", i, dis[i]); memset(cnt, 0, sizeof(cnt)); printf("%d\n", dfs(1)); } return 0; }
相关文章推荐
- Java语言基础(移位运算符)
- 原生的强大DOM选择器querySelector
- 用sql查询当天,一周,一个月的数据
- Android 通过网页打开自己的APP(scheme)
- 如何实现MindMapper中的幻灯片功能的合理运用
- SearchView 学习_0
- 利用NSOperation进行异步图片下载——设置UITabView数据,图片下载,占位图。解决异步下载和Cell重用造成的图片设置混乱。和多次重复下载的问题
- java中的代理模式 用接口
- 动态的计算带有行间距的字段的长高
- SVN服务器搭建和使用(二)
- VS2010 生成Xml格式的注释文档
- StringBuilder清空方式
- ios7 苹果原生二维码扫描(和微信类似)
- 数据结构的字节对齐
- LSTM模型理论总结(产生、发展和性能等)
- Ancient Cipher 字符串加密 重排
- POJ 2262 Goldbach's Conjecture
- 基于Oracle的EntityFramework的WEBAPI2的实现(三)—— 建立APIController及设置返回类型JSON、XML等
- [OpenStack] [Liberty] Neutron单网卡桥接模式访问外网
- MariaDB 10.1 可每秒处理一百万次查询