• 先讲一个为了少打一些代码而滥用继承终于接受慘痛教训的故事。
#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. 【翻译自mos文章】11.2.0.4及更高版本号的asm实例中MEMORY_TARGET 和 MEMORY_MAX_TARGET的默认值和最小值

    [翻译自mos文章]11.2.0.4及更高版本号的asm实例中MEMORY_TARGET 和 MEMORY_MAX_TARGET的默认值和最小值 来源于: Default and Minimum ME ...

  2. Spark SQL with Hive

    前一篇文章是Spark SQL的入门篇Spark SQL初探,介绍了一些基础知识和API,可是离我们的日常使用还似乎差了一步之遥. 终结Shark的利用有2个: 1.和Spark程序的集成有诸多限制 ...

  3. 0x17 二叉堆

    优先队列太好用了手写啥呀 poj1456 经过贪心专题的洗礼以后这题根本就不叫题啊...按时间大到小排每次取最大就好 #include<cstdio> #include<iostre ...

  4. java 中的静态(static)代码块

    类字面常量 final 静态域不会触发类的初始化操作 非 final static 静态域(以及构造器其实是一种隐式的静态方法) Class.forName():会自动的初始化: 使用 .class来 ...

  5. 【HDU 5015】233 Matrix

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5015 [算法] 矩阵乘法 [代码] #include<bits/stdc++.h> u ...

  6. 第七章 用户输入和while 循环

    7.1 创建多行字符串的方式: 01 prompt="if you tell me who you are, we can personalize the message you see.& ...

  7. Hessian Spirng实例

    Spring实例 之前,我们做了很简单的纯Hessian的调用,虽然到此已经能够满足远程调用的需求了,但是我听说spring也能够访问hessian的远程服务,研究了一番,废话不多说,直接上示例. 业 ...

  8. POJ 3233 矩阵快速幂&二分

    题意: 给你一个n*n的矩阵 让你求S: 思路: 只知道矩阵快速幂 然后nlogn递推是会TLE的. 所以呢 要把那个n换成log 那这个怎么搞呢 二分! 当k为偶数时: 当k为奇数时: 就按照这么搞 ...

  9. BZOJ 2427 /HAOI 2010 软件安装 tarjan缩点+树形DP

    终于是道中文题了.... 当时考试的时候就考的这道题.... 果断GG. 思路: 因为有可能存在依赖环,所以呢 先要tarjan一遍 来缩点. 随后就进行一遍树形DP就好了.. x表示当前的节点.j表 ...

  10. ffmpeg x264编译与使用介绍

    问题1:我用的是最新版本的ffmpeg和x264,刚刚编译出来,编译没有问题,但是在linux 环境使用ffmpeg的库时发现报错error C3861: 'UINT64_C': identifier ...