本题算法:最短路树

这是个啥玩意呢,就是对于一个图,构造一棵树,使从源点开始的单源最短路径与原图一模一样。怎么做呢,跑一边Dijkstra,然后对于一个点u,枚举它的边,设当前的边为cur_edge,如果dis[u]+cue_edge的长度=dis[cur_edge的终点],那么显然这条边应该珂以是最短路树上的一条边,然后打一个标记表示cur_edge的终点不能再被加边了,题目要求字典序最小,显然u从1到n枚举珂以解决问题。

建好树以后跑一边DFS,我们知道当前节点u上连边的贡献是\((dis[u] - t) \times\)以\(u\)为根的子树的牛的个数,找到贡献最大的点更新答案即可。

代码:

#include <cstdio>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#define ll long long using namespace std; ll read(){
ll x = 0; int zf = 1; char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
} struct Edge{
int from, to, next; ll dis;
} edges[1000001]; int head[300001], edge_num = 0; ll dis[300001]; inline void addEdge(int u, int v, ll w){
edges[++edge_num] = (Edge){u, v, head[u], w};
head[u] = edge_num;
} set< pair<ll, int> > que;
int n, t, s = 1; void dijkstra(){
for (int i = 1; i <= n; ++i)
dis[i] = (1ll << 62);
dis[s] = 0; que.insert(make_pair(0, s));
pair<ll, int> uu; int u, v;
while (!que.empty()){
uu = *que.begin(); que.erase(uu);
u = uu.second;
for (int c_e = head[u]; c_e; c_e = edges[c_e].next){
v = edges[c_e].to;
if (dis[u] + edges[c_e].dis < dis[v]){
que.erase(make_pair(dis[v], v));
dis[v] = dis[u] + edges[c_e].dis;
que.insert(make_pair(dis[v], v));
}
}
}
} vector<int> vec[100001];
ll ans = 0;
int a[100001];
int vis[100001]; int DFS(int u){
int v, cnt = 0; vis[u] = 1;
for (int i = 0; i < vec[u].size(); ++i){
v = vec[u][i];
if (!vis[v])
cnt += DFS(v);
}
cnt += a[u];
ans = max(ans, (dis[u] - t) * cnt);
return cnt;
} int v2[100001]; signed main(){
int m; n = read(), m = read(), t = read();
for (int i = 1; i <= n; ++i) a[i] = read();
int u, v; ll w;
for (int i = 1; i <= m; ++i){
u = read(), v = read(), w = read();
addEdge(u, v, w), addEdge(v, u, w);
}
dijkstra();
for(int i = 1; i <= n; ++i)
for(int c_e = head[i]; c_e; c_e = edges[c_e].next)
if(dis[edges[c_e].to] == dis[i] + edges[c_e].dis && !v2[edges[c_e].to]){
v2[edges[c_e].to] = 1;
vec[i].push_back(edges[c_e].to), vec[edges[c_e].to].push_back(i);
}
DFS(1);
printf("%lld", ans);
return 0;
}

[USACO19JAN]Shortcut题解的更多相关文章

  1. USACO19JAN Gold题解

    噩梦的回忆.. 上周日在机房打的模拟赛,结果十分惨烈,就最后一题yy出了正解结果玄学的只拿了80 考试结果:0+0+80=80 订正时对着T3打了2hours结果还是90 订正结果:100+100+9 ...

  2. Luogu P5201 [USACO19JAN]Shortcut 最短路树???

    最短路树...开眼界了...之前想也没想过.... 先跑出来1到每个点最短路,然后建树时要标记点的入度,否则会多连边...然后深搜时更新新答案就是 #include<cstdio> #in ...

  3. LuoguP5201 [USACO19JAN]Shortcut(最短路树)

    字典序?建树时从小枚举,用\(Dijkstra\)的血泪建好树,\(size\)大小决定贡献 #include <iostream> #include <cstdio> #in ...

  4. USACO比赛题泛刷

    随时可能弃坑. 因为不知道最近要刷啥所以就决定刷下usaco. 优先级排在学习新算法和打比赛之后. 仅有一句话题解.难一点的可能有代码. 优先级是Gold>Silver.Platinum刷不动. ...

  5. 20190922 「HZOJ NOIP2019 Round #7」20190922模拟

    综述 这次是USACO2019JAN Gold的题目. \(\mathrm{Cow Poetry}\) 题解 因为每句诗的长度一定是\(k\),所以自然而然想到背包. 设\(opt[i][j]\)代表 ...

  6. 树状数组 || 线段树 || Luogu P5200 [USACO19JAN]Sleepy Cow Sorting

    题面:P5200 [USACO19JAN]Sleepy Cow Sorting 题解: 最小操作次数(记为k)即为将序列倒着找第一个P[i]>P[i+1]的下标,然后将序列分成三部分:前缀部分( ...

  7. P5204 [USACO19JAN]Train Tracking 2

    P5204 [USACO19JAN]Train Tracking 2 毒毒题,对着嘤文题解看了贼久 首先考虑此题的一个弱化版本:如果输入的所有\(c_i\)相等怎么做 现在假设有\(len\)个数,取 ...

  8. LG5201 「USACO2019JAN」Shortcut 最短路树

    \(\mathrm{Shortcut}\) 问题描述 LG5201 题解 最短路树. 显然奶牛的路径就是从\(1\)走到各个草地,于是从\(1\)跑最短路,构建最短路树. 为了保证字典序,从\(1\) ...

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

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

随机推荐

  1. cocos2dx基础篇(18) 数据存储CCUserDefault

    在cocos2dx中提供了一个数据存储类CCUserDefault,可以作为一个轻量级的数据库来使用.它支持五种数据bool.int.float.double.string的存储. [3.x]     ...

  2. 【组策略】1.组策略介绍group policy

    组策略介绍group policy 高效学习法,念念不忘,必有回响. 分享一个高效学习思维,潜意识思考.就是在您没有大量时间的情况下,学习十分钟. 然后离开去完成别的事情的时候,大脑潜意识中还会继续思 ...

  3. 创建一个项目并在GitHub上发出拉取请求

    1.第一步:创建存储库 创建新存储库: New repository 命名存储库 写一个简短的描述 选择使用自述文件初始化此存储库 2.第二步:创建一个分支 创建一个新分支 转到新的存储库hello- ...

  4. k线图的分形

    蜡烛图上的分形指标,作为一种特殊的K线组合形态,通过对价格的一系列的高低点的描述,辅助识别出市场潜在的突破和反转点,预判后期走势. 顶分形:相邻的五根K线,若中间那根K线最高价为这五根K线的最高价,则 ...

  5. Docker最详细入门教程

    Docker原理.详细入门教程 https://blog.csdn.net/deng624796905/article/details/86493330 阮一峰Docker入门讲解 http://ww ...

  6. 搜索专题: HDU2102 A计划

    这不知道是公主被抓走了第几次了,反正我们的骑士救就对了(别说了,我都救我都救...);这次的迷宫有些特别,双层,带电梯(?),而且这个电梯还有生命危险,可能会撞死(一层是电梯,一层是墙),或者永远困在 ...

  7. 51nod 1963 树上Nim

    这题还真就是树上玩 Nim... 相关知识点就是阶梯博弈,具体可以康这里 →_→ PS:手动搜索阶梯博弈 然后这题就转化为了多路径的阶梯博弈,这样的话咱定义根节点深度为 0,然后把所有奇数深度点的权值 ...

  8. 剑指offer-重构二叉树-树-python

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  9. 使用SQL语法来查询Elasticsearch:Elasticsearch-SQL插件

    简介 Elasticsearch-SQL是Elasticsearch的一个插件,它可以让我们通过类似SQL的方式对Elasticsearch中的数据进行查询.项目地址是:https://github. ...

  10. Hive导入导出数据的方法

    Hive导入数据的方式 官网文档: LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (p ...