Description

题库链接

给出一张 \(n\) 个点 \(m\) 条边有向图,询问最多有多少条不同的路径从 \(1\) 到 \(n\) 并且路径长度和 \(\leq E\) 。

\(2\leq n\leq 5000,1\leq m\leq 200000,1\leq E\leq 10^7\)

Solution

由于要求最多多少条,我们有贪心的思想,选取尽可能短的路径不会差。

那么题目就变成了求这张图 \(1\rightarrow n\) 的最短的 \(ans\) 条路径,并且路径的长度和 \(\leq E\) 。

就变成了裸的 \(k\) 短路问题。

由 \(f(x)=g(x)+h(x)\) ,由于让路径尽可能短,那么估价函数 \(h(x)\) 就取点 \(x\) 到 \(n\) 的最短路就好了。

b站上这道题代码写的丑的 \(stl\) 会 \(MLE\) ,像我这种菜鸡肯定过不了,只能手写可并堆了...

Code

//It is made by Awson on 2018.3.1
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 5000, M = 200000, INF = ~0u>>1;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); } int n, m, vis[N+5]; double dist[N+5], e;
struct node {
double f, g; int u;
bool operator < (const node &b) const {return f > b.f; }
};
struct mergeable_tree {
int ch[1300005][2], dist[1300005], pos, root, cnt; node k[1300005];
queue<int>mem;
int newnode(node x) {
int o; if (!mem.empty()) o = mem.front(), mem.pop(); else o = ++pos;
ch[o][0] = ch[o][1] = dist[o] = 0; k[o] = x; return o;
}
int merge(int a, int b) {
if (!a || !b) return a+b;
if (k[a] < k[b]) Swap(a, b);
ch[a][1] = merge(ch[a][1], b);
if (dist[ch[a][0]] < dist[ch[a][1]]) Swap(ch[a][0], ch[a][1]);
dist[a] = dist[ch[a][1]]+1; return a;
}
node top() {return k[root]; }
void push(node x) {root = merge(root, newnode(x)); ++cnt; }
void pop() {mem.push(root); root = merge(ch[root][0], ch[root][1]); --cnt; }
bool empty() {return !cnt; }
}Q;
struct Graph {
struct tt {int to, next; double cost; }edge[M+5];
int path[N+5], top;
void add(int u, int v, double c) {edge[++top].to = v, edge[top].next = path[u], edge[top].cost = c, path[u] = top; }
void SPFA() {
for (int i = 1; i < n; i++) dist[i] = INF;
queue<int>Q; vis[n] = 1; Q.push(n);
while (!Q.empty()) {
int u = Q.front(); Q.pop(); vis[u] = 0;
for (int i = path[u]; i; i = edge[i].next)
if (dist[edge[i].to] > dist[u]+edge[i].cost) {
dist[edge[i].to] = dist[u]+edge[i].cost;
if (!vis[edge[i].to]) Q.push(edge[i].to), vis[edge[i].to] = 1;
}
}
}
int Astar() {
int ans = 0;
node t, tt; t.f = dist[1], t.g = 0, t.u = 1;
Q.push(t);
while (!Q.empty()) {
t = Q.top(); Q.pop();
if (t.u == n) {if (e >= t.f) {ans++, e -= t.f; continue; } else break; }
for (int i = path[t.u]; i; i = edge[i].next) {
tt.g = t.g+edge[i].cost, tt.u = edge[i].to, tt.f = tt.g+dist[edge[i].to];
Q.push(tt);
}
}
return ans;
}
}g1, g2; void work() {
read(n), read(m); scanf("%lf", &e); int u, v; double c;
for (int i = 1; i <= m; i++) {
read(u), read(v), scanf("%lf", &c), g1.add(u, v, c), g2.add(v, u, c);
}
g2.SPFA(); writeln(g1.Astar());
}
int main() {
work(); return 0;
}

[SDOI 2010]魔法猪学院的更多相关文章

  1. 解题:SDOI 2010 魔法猪学院

    题面 题外话:神**可持久化左偏树,你谷的人都太神了,学不来 我把这个当做A*模板题的说,先讲一讲个人对A*的理解:如果说普通的BFS是Bellman_Ford,那A*就是一个Dijkstra.以寻找 ...

  2. BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...

  3. Bzoj 1975: [Sdoi2010]魔法猪学院 dijkstra,堆,A*,K短路

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1357  Solved: 446[Submit][Statu ...

  4. bzoj 1975: [Sdoi2010]魔法猪学院 [k短路]

    1975: [Sdoi2010]魔法猪学院 裸题... 被double坑死了 #include <iostream> #include <cstdio> #include &l ...

  5. BZOJ_1975_[Sdoi2010]魔法猪学院_A*

    BZOJ_1975_[Sdoi2010]魔法猪学院_A* Description iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPi ...

  6. K短路 (A*算法) [Usaco2008 Mar]牛跑步&[Sdoi2010]魔法猪学院

    A*属于搜索的一种,启发式搜索,即:每次搜索时加一个估价函数 这个算法可以用来解决K短路问题,常用的估价函数是:已经走过的距离+期望上最短的距离 通常和Dijkstra一起解决K短路 BZOJ1598 ...

  7. bzoj 1975 [Sdoi2010]魔法猪学院

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1758  Solved: 557[Submit][Statu ...

  8. P2483 [SDOI2010]魔法猪学院

    P2483 [SDOI2010]魔法猪学院 摘要 --> 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世 ...

  9. 【BZOJ1975】【SDOI2010】魔法猪学院 [A*搜索]

    魔法猪学院 Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description iPig在假期来到了传说中的魔法猪 ...

随机推荐

  1. Visual Studio 2017 Key 激活码

    Visual Studio 2017(VS2017) 企业版 Enterprise 注册码:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Visual Studio 2017(VS201 ...

  2. 新事物学习---Chrome上使用PWA

    PWA是什么 PWA(Progressive Web Apps)是 Google 最近在提的一种 Web App 形态 (或者如 Wikipedia 所称的"软件开发方法").PW ...

  3. 分区表SQL调优/优化(Tuning)时容易“被欺骗”的场景之一

    近几天没有用户找到,除了看看书,就是上网浏览点东西,好不惬意.可惜好景不长,正在享受悠闲惬意的日子时,一个用户的工作人员QQ找到我,说他们在统计一些数据,但一个SQL特别慢,或者说就从来没出过数据,我 ...

  4. 冲刺NO.12

    Alpha冲刺第十二天 站立式会议 项目进展 项目核心功能,如学生基本信息管理模块,学生信用信息模块,奖惩事务管理模块等等都已完成,测试工作大体结束. 问题困难 项目结束后对项目的阶段性总结缺乏一定的 ...

  5. 201621123050 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:接口.has-a.comparable 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. ...

  6. C程序第二次作业

    2-1删除字符串中数字字符 1.设计思路 (1)主要描述题目算法 第一步:遍历指针s所指的s数组. 第二步:如果 * (s+i)在0至9之间的话,则跳过此 * (s+i). 第三步:如果* (s+i) ...

  7. Mysql数据库的触发程序

    /** **创建表 */ CREATE TABLE test1(a1 INT); CREATE TABLE test2(a2 INT); CREATE TABLE test3(a3 INT NOT N ...

  8. auto_prepend_file与auto_append_file使用方法

    auto_prepend_file与auto_append_file使用方法 如果需要将文件require到所有页面的顶部与底部. 第一种方法:在所有页面的顶部与底部都加入require语句. 例如: ...

  9. JAVA_SE基础——59.权限访问修饰符

    了解了包的概念,就可以系统的介绍Java中的访问控制级别.在Java中,针对类.成员方法和属性提供了四种访问级别,分别是private.default.protected和public. 权限访问修饰 ...

  10. thinkphp中的常见静态常亮

    thinkphp __PUBLIC__的定义 __ROOT__等常量的定义 1 2 3 4 5 6 7 8 9 '__TMPL__'      =>  APP_TMPL_PATH,  // 项目 ...