博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[SDOI 2010]魔法猪学院
阅读量:5098 次
发布时间:2019-06-13

本文共 3437 字,大约阅读时间需要 11 分钟。

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 
#define LL long long#define dob complex
#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
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
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;}

转载于:https://www.cnblogs.com/NaVi-Awson/p/8486667.html

你可能感兴趣的文章
洛谷 P2089 烤鸡【DFS递归/10重枚举】
查看>>
我眼中的技术地图
查看>>
lc 145. Binary Tree Postorder Traversal
查看>>
在centos上开关tomcat
查看>>
黑马程序员——2 注释
查看>>
android dialog使用自定义布局 设置窗体大小位置
查看>>
ionic2+ 基础
查看>>
查询消除重复行
查看>>
[leetcode]Minimum Path Sum
查看>>
内存管理 浅析 内存管理/内存优化技巧
查看>>
Json格式的字符串转换为正常显示的日期格式
查看>>
Mobiscroll脚本破解,去除Trial和注册时间限制【转】
查看>>
BootStrap---2.表格和按钮
查看>>
Ajax之404,200等查询
查看>>
Aizu - 1378 Secret of Chocolate Poles (DP)
查看>>
csv HTTP简单表服务器
查看>>
IO流写出到本地 D盘demoIO.txt 文本中
查看>>
Screening technology proved cost effective deal
查看>>
mysql8.0.13下载与安装图文教程
查看>>
Thrift Expected protocol id ffffff82 but got 0
查看>>