• 先讲一个为了少打一些代码而滥用继承终于接受慘痛教训的故事。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int oo = 1000000000, nil = 0;
int N, M, S, T, K, times[1005];
int u[200010], v[200010], w[200010], nxt[200010], pnt[1005], e;
int d[1005];
bool vis[1005], other[1005];
class node
{
public:
int n, dis;
node(int n = 0, int dis = 0) :n(n), dis(dis) {}
protected:
virtual bool operator < (const node& b) const
{
return dis > b.dis;
}
};
struct astar : public node
{
astar(int xn = 0, int xdis = 0)
{
n = xn; dis = xdis;
}
bool operator < (const astar& b) const
{
return dis + d[n] > b.dis + d[b.n];
}
};
void addedge(int a, int b, int c, bool d)
{
u[++e] = a; v[e] = b; w[e] = c;
nxt[e] = pnt[a]; pnt[a] = e; other[e] = d;
}
void init()
{
int a, b, c;
scanf("%d%d", &N, &M);
for(int i = 1; i <= M; ++i)
{
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, c, false);
addedge(b, a, c, true);
}
scanf("%d%d%d", &S, &T, &K);
if(S == T)
{
++K;
}
}
void getSSSP(int s)
{
memset(d, 0x3f, sizeof(d));
memset(vis, 0, sizeof(vis));
priority_queue <node> Q;
d[s] = 0;
Q.push(node(s, 0));
while(!Q.empty())
{
node t = Q.top();
Q.pop();
vis[t.n] = true;
for(int j = pnt[t.n]; j != nil; j = nxt[j])
{
if((!vis[v[j]]) && (d[v[j]] > t.dis + w[j]) && (other[j]))
{
d[v[j]] = t.dis + w[j];
Q.push(node(v[j], d[v[j]]));
}
}
}
}
void work()
{
getSSSP(T);
memset(times, 0, sizeof(times));
priority_queue <astar> Q;
Q.push(astar(S, 0));
while(!Q.empty())
{
astar t = Q.top();
Q.pop();
++times[t.n];
if((t.n == T) && (times[t.n] == K))
{
printf("%d\n", t.dis);
return;
}
for(int j = pnt[t.n]; j != nil; j = nxt[j])
{
if(!other[j])
{
Q.push(astar(v[j], t.dis + w[j]));
}
}
}
puts("-1");
}
int main()
{
init();
work();
return 0;
}

然后由于node里的小于号被protected了。stl的priority_queue无法调用之而编译失败。

假设去掉protected。node里的小于号覆盖不掉,又会使astar中的小于号没用导致WA。TUT……

  • 题目来源

id=2449">http://poj.org/problem?id=2449

  • 题目大意

    求一张有向图从S到T的第K短路(边权均为正)。

  • 题解

    首先在反向图中最短路出每一个点到终点的距离,然后利用A*的思想,从起点開始可反复地搜索,估价函数为{当前走过的距离+该点到终点的最短路长度}。当终点T被第K次从堆(优先队列)中取出时,输出答案。

  • 注意细节

    S == T时要把K加上1;

    某结点出队次数超过K时,能够不再考虑。

  • Code

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int oo = 1000000000, nil = 0;
int N, M, S, T, K, times[1005];
int u[200010], v[200010], w[200010], nxt[200010], pnt[1005], e;
int d[1005];
bool vis[1005], other[200010];
struct node
{
int n, dis;
node(int n = 0, int dis = 0) :n(n), dis(dis) {}
bool operator < (const node& b) const
{
return dis > b.dis;
}
};
struct astar
{
int n, dis;
astar(int n = 0, int dis = 0) :n(n), dis(dis) {}
bool operator < (const astar& b) const
{
return dis + d[n] > b.dis + d[b.n];
}
};
void addedge(int a, int b, int c, bool d)
{
u[++e] = a; v[e] = b; w[e] = c;
nxt[e] = pnt[a]; pnt[a] = e; other[e] = d;
}
void init()
{
int a, b, c;
scanf("%d%d", &N, &M);
for(int i = 1; i <= M; ++i)
{
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, c, false);
addedge(b, a, c, true);
}
scanf("%d%d%d", &S, &T, &K);
if(S == T)
{
++K;
}
}
void getSSSP()
{
memset(d, 0x3f, sizeof(d));
memset(vis, 0, sizeof(vis));
priority_queue <node> Q;
d[T] = 0;
Q.push(node(T, 0));
while(!Q.empty())
{
node t = Q.top();
Q.pop();
vis[t.n] = true;
for(int j = pnt[t.n]; j != nil; j = nxt[j])
{
if((!vis[v[j]]) && (d[v[j]] > t.dis + w[j]) && (other[j]))
{
d[v[j]] = t.dis + w[j];
Q.push(node(v[j], d[v[j]]));
}
}
}
}
void work()
{
getSSSP();
memset(times, 0, sizeof(times));
priority_queue <astar> Q;
Q.push(astar(S, 0));
while(!Q.empty())
{
astar t = Q.top();
Q.pop();
++times[t.n];
if((t.n == T) && (times[t.n] == K))
{
printf("%d\n", t.dis);
return;
}
if(times[t.n] > K)
{
continue;
}
for(int j = pnt[t.n]; j != nil; j = nxt[j])
{
if(!other[j])
{
Q.push(astar(v[j], t.dis + w[j]));
}
}
}
puts("-1");
}
int main()
{
init();
work();
return 0;
}
  • 再讲一个悲伤的故事:这段代码我一開始把other数组开成了点数,然后RE了4次,另一次忘了删去while(1)……所以一定要养成提前定义常量和认真静态查错的好习惯。

POJ2449题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. UVA - 1642 Magical GCD 数学

                                  Magical GCD The Magical GCD of a nonempty sequence of positive integer ...

  2. UESTC--1263--The Desire of Asuna(贪心)

    The Desire of Asuna Time Limit: 1000MS   Memory Limit: 65535KB   64bit IO Format: %lld & %llu Su ...

  3. SQL的优化技巧

    一.一些常见的SQL实践 (1)负向条件查询不能使用索引 select * from order where status!=0 and stauts!=1 not in/not exists都不是好 ...

  4. 【BZOJ 2152】 聪聪可可

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2152 [算法] 点分治 [代码] #include<bits/stdc++.h ...

  5. Java-MyBatis:MyBatis 3 动态 SQL

    ylbtech-Java-MyBatis:MyBatis 3 动态 SQL 1.返回顶部 1. 动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架 ...

  6. 杂项-DB:数据库

    ylbtech-杂项-DB:数据库   数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增.截取.更新.删除等操作. 所谓“数据库”是以一定方式储存在一起.能与 ...

  7. 如何用写js弹出层 ----2017-03-29

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. category与协议的不同

    1,category是针对类进行扩展,而且该类必须有里面的所有成员 协议不同可以选择性实现 2,category是针对一个具体的类实现,其他类没有 协议允许任何类使用,只要实现以后只能通过重写修改 3 ...

  9. 在js在添版本号

    为了增加用户访问网站体验,快速打开网页,许多网站都对不常更新的js,css文件在浏览器端设置了缓存.但如果在服务器端做了更新,浏览器使用的仍是缓存在本地的js文件,除非强制清缓存(ctrl+F5).为 ...

  10. jquery分页点击后页面置顶

    前台: <a href="#" ><span id='top'></span></a> js中: 放在分页事件后,数据加载完成后 j ...