POJ 2449 Remmarguts' Date
2014-03-06 16:40
477 查看
题目大意:
好男人决不能错过和女生的约会。
从前有一个UDF(联合三角洲自由王国)王国,一天王国的邻居国家的公主Uyuw被派往UDF完成一项外交使命,而在这之前Uyuw已经通知过UDF的王子Remmarguts她将会到UDF首都的大厅中与王子商讨商业事宜,但是商讨能开展的条件就是王子必须通过k短路径到达大厅(公主并不想见王子,故意为其设置障碍)。出于对公主的倾心以及对国家商贸发展的重视王子决定前往。
UDF首都共有N个驿站(1 ≤ N ≤ 1,000)和M条泥泞小路(都是单向的,1 ≤ M ≤ 100,000),S为王子的出发地点,T是目标地点(即大厅),为了走k短路径同一个驿站可能会经过两次或者两次以上,包括S和T。
现有多个测例(测例数无上限),每个测例中都会给出N和M,驿站按1-N编号,每条路都会给出起点、终点和路上所花的时间t(1 ≤ t ≤ 100),最后给出起点S、终点T和第k短路径的k(1 ≤ k ≤ 1,000),对于每个测例都需要打印k短路径的长度(即总时间),如果k短路径不存在则打印-1即可。
题目链接
注释代码:
无注释代码:
单词解释:
date:n, 约会
appointment:n, 约定,预约
mandarin:n, 普通话,国语,官话
softly:adv, 温柔的
prince:n, 王子
delta:n, 三角洲
princess:n, 公主
diplomatic:adj, 外交的
mission:n, 使命,任务
erenow:adv, 在此之前
inform:vt, 通知
hall:n, 大厅
commercial:adj, 商业的
via:prep, 通过,经由
enamored:adj, 迷恋的,倾心的
prime minister:n, 首相
muddy:adj, 泥泞的
sideway:n, 人行道,小巷
directed:adj, 定向的
disparate:adj, 不同的,相异的
station:n, 车站,驻地
quote:n, 引用,引号
好男人决不能错过和女生的约会。
从前有一个UDF(联合三角洲自由王国)王国,一天王国的邻居国家的公主Uyuw被派往UDF完成一项外交使命,而在这之前Uyuw已经通知过UDF的王子Remmarguts她将会到UDF首都的大厅中与王子商讨商业事宜,但是商讨能开展的条件就是王子必须通过k短路径到达大厅(公主并不想见王子,故意为其设置障碍)。出于对公主的倾心以及对国家商贸发展的重视王子决定前往。
UDF首都共有N个驿站(1 ≤ N ≤ 1,000)和M条泥泞小路(都是单向的,1 ≤ M ≤ 100,000),S为王子的出发地点,T是目标地点(即大厅),为了走k短路径同一个驿站可能会经过两次或者两次以上,包括S和T。
现有多个测例(测例数无上限),每个测例中都会给出N和M,驿站按1-N编号,每条路都会给出起点、终点和路上所花的时间t(1 ≤ t ≤ 100),最后给出起点S、终点T和第k短路径的k(1 ≤ k ≤ 1,000),对于每个测例都需要打印k短路径的长度(即总时间),如果k短路径不存在则打印-1即可。
题目链接
注释代码:
/* * Problem ID : POJ 2449 Remmarguts' Date * Author : Lirx.t.Una * Language : G++ * Run Time : 657 ms * Run Memory : 8808 KB */ #pragma G++ optimize("O2") #include <iostream> #include <cstring> #include <cstdio> #include <queue> #define NIL 0 //infinity //这里指k短路径的最大时间 //INF ≥ MAXSIDEWAYN × MAXT(单条路径的最大时间是100) #define INF 1000000000 //maximum number of stations //站的最大数量 #define MAXSTATIONN 1001 //maximum number of sideways //有向路径的最大数量 #define MAXSIDEWAYN 100001 using namespace std; struct Arc { int u; int v; int t;//time,时间权值 Arc(void) {} Arc( int xu, int xv, int xt ) : u(xu), v(xv), t(xt) {} }; Arc arc[MAXSIDEWAYN]; int e; int head[MAXSTATIONN]; int rhead[MAXSTATIONN];//reverse,逆图 int next[MAXSIDEWAYN]; int rnext[MAXSIDEWAYN]; int stk[MAXSTATIONN]; bool in[MAXSTATIONN]; int top; int dp[MAXSTATIONN];//dp[i],i点到目标点的最短时间 struct Node { int ith; int tot;//total time,从起始到该点所经过的总时间 int f;//f为估价函数,等于tot加上该店到目标点的单源最短路径 Node(void) {} Node( int xith, int pst, int dt ) : ith(xith), tot( pst + dt ), f( tot + dp[xith] ) {} bool operator<(const Node &oth) const { return f > oth.f; } }; void addarc( int u, int v, int t ) { arc[e] = Arc( u, v, t ); next[e] = head[u]; head[u] = e; //初始化逆图 rnext[e] = rhead[v]; rhead[v] = e++; } void init( int n, int m ) { int u, v; int t; int i; memset( head + 1, NIL, n * sizeof(int)); memset( rhead + 1, NIL, n * sizeof(int)); memset( in + 1, false, n * sizeof(bool)); for ( i = 1; i <= n; i++ ) dp[i] = INF; e = 1; while ( m-- ) { scanf("%d%d%d", &u, &v, &t); addarc( u, v, t ); } } bool relax( int u, int v, int dt ) {//SPFA弹性判断 int ttmp; ttmp = dp[u] + dt; if ( ttmp < dp[v] ) { dp[v] = ttmp; return true; } return false; } void spfa(int end) {//求各点到目标点的最短时间 int u, v; int i; dp[end] = 0; top = 1; stk[1] = end; in[end] = true; while ( top ) { u = stk[top--]; in[u] = false; for ( i = rhead[u]; i; i = rnext[i] ) { v = arc[i].u; if ( relax( u, v, arc[i].t ) && !in[v] ) { stk[++top] = v; in[v] = true; } } } } int astar( int bgn, int end, int k ) {//A*启发式搜索 //第k次搜索到目标结点表示搜索成功 //begin,end,k,起始结点,终止结点,和第k短路径 priority_queue<Node> heap; Node node;//临时结点 int pst;//past time,从bgn到父结点所经历的时间 int u;//临时结点的标号 int i;//计数变量 if ( bgn == end )//自己到自己不计,因此需要减去 //等价就是将k加1 k++; heap.push( Node( bgn, 0, 0 ) ); while ( !heap.empty() ) { node = heap.top(); u = node.ith; pst = node.tot; if ( u == end && !(--k) )//第k次搜索到终点时便得到答案 //直接将k短路径的长度返回即可 return pst; heap.pop(); for ( i = head[u]; i; i = next[i] ) heap.push( Node( arc[i].v, pst, arc[i].t ) ); } return -1;//有可能除了最短路径之外,从其它点经过时会走到死路 //比如 1 // 2 3 4 // 5 6 7 // 8 //5和7都是死路(起始是1,终点是8) } int main() { int n, m; int bgn, end; int k; while ( ~scanf("%d%d", &n, &m) ) { init( n, m ); scanf("%d%d%d", &bgn, &end, &k); spfa(end); if ( INF == dp[bgn] ) {//连最短路径都是无穷就意味着 //bgn到end不可达 puts("-1"); continue; } printf("%d\n", astar( bgn, end, k )); } return 0; }
无注释代码:
#pragma G++ optimize("O2") #include <iostream> #include <cstring> #include <cstdio> #include <queue> #define NIL 0 #define INF 1000000000 #define MAXSTATIONN 1001 #define MAXSIDEWAYN 100001 using namespace std; struct Arc { int u; int v; int t; Arc(void) {} Arc( int xu, int xv, int xt ) : u(xu), v(xv), t(xt) {} }; Arc arc[MAXSIDEWAYN]; int e; int head[MAXSTATIONN]; int rhead[MAXSTATIONN]; int next[MAXSIDEWAYN]; int rnext[MAXSIDEWAYN]; int stk[MAXSTATIONN]; bool in[MAXSTATIONN]; int top; int dp[MAXSTATIONN]; struct Node { int ith; int tot; int f; Node(void) {} Node( int xith, int pst, int dt ) : ith(xith), tot( pst + dt ), f( tot + dp[xith] ) {} bool operator<(const Node &oth) const { return f > oth.f; } }; void addarc( int u, int v, int t ) { arc[e] = Arc( u, v, t ); next[e] = head[u]; head[u] = e; rnext[e] = rhead[v]; rhead[v] = e++; } void init( int n, int m ) { int u, v; int t; int i; memset( head + 1, NIL, n * sizeof(int)); memset( rhead + 1, NIL, n * sizeof(int)); memset( in + 1, false, n * sizeof(bool)); for ( i = 1; i <= n; i++ ) dp[i] = INF; e = 1; while ( m-- ) { scanf("%d%d%d", &u, &v, &t); addarc( u, v, t ); } } bool relax( int u, int v, int dt ) { int ttmp; ttmp = dp[u] + dt; if ( ttmp < dp[v] ) { dp[v] = ttmp; return true; } return false; } void spfa(int end) { int u, v; int i; dp[end] = 0; top = 1; stk[1] = end; in[end] = true; while ( top ) { u = stk[top--]; in[u] = false; for ( i = rhead[u]; i; i = rnext[i] ) { v = arc[i].u; if ( relax( u, v, arc[i].t ) && !in[v] ) { stk[++top] = v; in[v] = true; } } } } int astar( int bgn, int end, int k ) { priority_queue<Node> heap; Node node; int pst; int u; int i; if ( bgn == end ) k++; heap.push( Node( bgn, 0, 0 ) ); while ( !heap.empty() ) { node = heap.top(); u = node.ith; pst = node.tot; if ( u == end && !(--k) ) return pst; heap.pop(); for ( i = head[u]; i; i = next[i] ) heap.push( Node( arc[i].v, pst, arc[i].t ) ); } return -1; } int main() { int n, m; int bgn, end; int k; while ( ~scanf("%d%d", &n, &m) ) { init( n, m ); scanf("%d%d%d", &bgn, &end, &k); spfa(end); if ( INF == dp[bgn] ) { puts("-1"); continue; } printf("%d\n", astar( bgn, end, k )); } return 0; }
单词解释:
date:n, 约会
appointment:n, 约定,预约
mandarin:n, 普通话,国语,官话
softly:adv, 温柔的
prince:n, 王子
delta:n, 三角洲
princess:n, 公主
diplomatic:adj, 外交的
mission:n, 使命,任务
erenow:adv, 在此之前
inform:vt, 通知
hall:n, 大厅
commercial:adj, 商业的
via:prep, 通过,经由
enamored:adj, 迷恋的,倾心的
prime minister:n, 首相
muddy:adj, 泥泞的
sideway:n, 人行道,小巷
directed:adj, 定向的
disparate:adj, 不同的,相异的
station:n, 车站,驻地
quote:n, 引用,引号
相关文章推荐
- jQuery计算文本宽度和input标签根据输入字符动态自适应宽度的实现
- 在线编辑word文档代码
- mapreduce counter
- java 排序与二分法查找代码
- STL中各个容器的内存的释放
- LoadRunner参数化详解
- 解析oracle的rownum
- 关于正则表达式的个人笔记
- android SQLite使用SQLiteOpenHelper类对数据库进行操作
- iOS RunLoop 初识
- spi流程
- 给Win32 GUI程序增加控制台窗口的方法
- android利用数字证书对程序签名
- run configurations改端口
- 项目简述
- 谈谈WEB开发跟非WEB开发各自不同的关注点
- Hibernate介绍
- android JNI学习六
- iOS-应用间通信之自定义URL Schemes
- 如何才能不纠结