原题地址

题目描述

Gremlins have infested the farm. These nasty, ugly fairy-like

creatures thwart the cows as each one walks from the barn (conveniently located at pasture_1) to the other fields, with cow_i traveling to from pasture_1 to pasture_i. Each gremlin is personalized and knows the quickest path that cow_i normally takes to pasture_i. Gremlin_i waits for cow_i in the middle of the final cowpath of the quickest route to pasture_i, hoping to harass cow_i.

Each of the cows, of course, wishes not to be harassed and thus chooses an at least slightly different route from pasture_1 (the barn) to pasture_i.

Compute the best time to traverse each of these new not-quite-quickest routes that enable each cow_i that avoid gremlin_i who is located on the final cowpath of the quickest route from pasture_1 to

pasture_i.

As usual, the M (2 <= M <= 200,000) cowpaths conveniently numbered 1..M are bidirectional and enable travel to all N (3 <= N <= 100,000) pastures conveniently numbered 1..N. Cowpath i connects pastures a_i (1 <= a_i <= N) and b_i (1 <= b_i <= N) and requires t_i (1 <= t_i <= 1,000) time to traverse. No two cowpaths connect the same two pastures, and no path connects a pasture to itself (a_i != b_i). Best of all, the shortest path regularly taken by cow_i from pasture_1 to pasture_i is unique in all the test data supplied to your program.

By way of example, consider these pastures, cowpaths, and [times]:

1--[2]--2-------+
| | |
[2] [1] [3]
| | |
+-------3--[4]--4
TRAVEL     BEST ROUTE   BEST TIME   LAST PATH
p_1 to p_2 1->2 2 1->2
p_1 to p_3 1->3 2 1->3
p_1 to p_4 1->2->4 5 2->4

When gremlins are present:

TRAVEL     BEST ROUTE   BEST TIME    AVOID
p_1 to p_2 1->3->2 3 1->2
p_1 to p_3 1->2->3 3 1->3
p_1 to p_4 1->3->4 6 2->4

For 20% of the test data, N <= 200.

For 50% of the test data, N <= 3000.

TIME LIMIT: 3 Seconds

MEMORY LIMIT: 64 MB

Gremlins最近在农场上泛滥,它们经常会阻止牛们从农庄(牛棚_1)走到别的牛棚(牛_i的目的 地是牛棚_i).每一个gremlin只认识牛_i并且知道牛_i一般走到牛棚_i的最短路经.所以它 们在牛_i到牛棚_i之前的最后一条牛路上等牛_i. 当然,牛不愿意遇到Gremlins,所以准备找 一条稍微不同的路经从牛棚_1走到牛棚_i.所以,请你为每一头牛_i找出避免gremlin_i的最 短路经的长度.

和以往一样, 农场上的M (2 <= M <= 200,000)条双向牛路编号为1..M并且能让所有牛到 达它们的目的地, N(3 <= N <= 100,000)个编号为1..N的牛棚.牛路i连接牛棚a_i (1 <= a_i <= N)和b_i (1 <= b_i <= N)并且需要时间t_i (1 <=t_i <= 1,000)通过. 没有两条牛路连接同样的牛棚,所有牛路满足a_i!=b_i.在所有数据中,牛_i使用的牛棚_1到牛 棚_i的最短路经是唯一的.

输入格式

* Line 1: Two space-separated integers: N and M

* Lines 2..M+1: Three space-separated integers: a_i, b_i, and t_i

输出格式

* Lines 1..N-1: Line i contains the smallest time required to travel from pasture_1 to pasture_i+1 while avoiding the final cowpath of the shortest path from pasture_1 to pasture_i+1. If no such path exists from pasture_1 to pasture_i+1, output -1 alone on the line.

输入输出样例

输入 #1复制

4 5
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
输出 #1复制

3
3
6

打题的艰辛历程

  • 这题,只要是个想我一样这么弱的人第一反应就是次短路,把断的边给连上跑一次次短路就行了,然后隔壁大佬给了一组数据,他有可能次短路也要走这条边,然后这个思路就死了。
  • 过了一会又瞎YY出来了一个算法,找出终点的父节点,然后从这个父节点开始跑最短路再加上根节点到父节点的距离就可以了,就这个算法一开始还没看出来是错的,还瞎搞了一个什么算法,还一本正经的试了样例,发现错了,然后才发现他可以从父节点之前就绕道走。。。。
  • 最后去看了题解,又瞎搞了什么最短路树,调了一上午,发现有一个字母打错了。。。。
  • 最后终于过了
  • 总结这题就是折磨人的。。。

思路:

  • 这题就是一个最短路树,最短路树,就是一棵树,根节点到每个节点的长度就是原图上起点到这个点的最短路(就是1到每个节点的最短路径路过的边所构成的集合)
  • 我们要找一个点对(x,y)x,y之间有连边,但不在最短路树上,y在节点i的子树中,而x则不在,x同样也不是i,y的祖先,dis是最短路径,w是路径长度。
  • 所以我们要找的节点路径就是dis(x)+dis(y)-dis(i)+w(x,y);这个东西比较抽象,可以动手画图看一下。
  • 由于dis(i)是一定的,所以我们就要维护dis(x)+dis(y)+w(x,y)的最小值,因为太懒,就直接排个序算了,慢也慢不到哪去,STL里的sort好像有什么搞不懂的优化,反正排序用他就可以了。
  • 这样我们就选出了不在树上的边,排下序。更新好答案。
  • 在一个点被更新之后,那这个点的答案就一定最优,所以对上面那一堆式子,第一次更新就一定会是他的最优解。
  • 然后就可以用冰茶姬去维护每一个只搞了一次。
  • 然后又可以发现每一次更新都更新了x->lca(x,y)和y->lca(x,y)的所有点。因为如果更新到了LCA(x,y),那x,y就在同一棵子树里了,而我们可以更新的前提就是X,Y不在一棵子树中,题目说了x-y不会是i的父边,所以就一个一个像LCA那样去跳,一边跳一遍更新,知道LCA,然后改一下冰茶姬,最后完美结束。

最后放一下代码,千万别用SPFA,会T掉很多。。。

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = ;
const int maxm = ; inline int read()
{
int res = ;
bool flag = ;
char c = getchar();
while (c < '' or c > '')
{
if (c == '-') flag = ;
c = getchar();
}
while (c >= '' and c <= '')
{
res = res * + c - '';
c = getchar();
}
return flag ? -res : res;
} int n, m;
int a [maxm], b[maxm], c[maxm];
int what[maxm];
int ins[maxm];
bool iiis[maxm];
int father[maxn];
int fa[maxn];
int ans[maxn]; int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
} struct edge
{
int next;
int to;
int val;
}way[maxm]; int head[maxn], tot;
inline void add (int x , int y , int z , int GG)
{
way[++tot].next = head[x];
way[tot].to = y;
way[tot].val = z;
what[tot] = GG;
head[x] = tot;
}
inline void add (int x , int y)
{
way[++tot].next = head[x];
way[tot].to=y;
head[x]=tot;
}
struct date
{
int x;
int y;
int w;
}usaco[maxm]; bool cmp(date a, date b)
{
return a.w < b.w;
} int dfs(int x)
{
for(int i=head[x];i;i=way[i].next)
{
int to=way[i].to;
if(to==father[x])
{
continue;
}
father[to]=x;
dfs(to);
}
} struct dij{int x, w;}; bool operator <(const dij &a,const dij &b)
{
return a.w > b.w;
} int dis[maxn];
bool vis[maxn]; int dijkstra(int qa)
{
memset(dis,0x3f,sizeof(dis));
priority_queue < dij > q;
dis[qa]=;
q.push((dij){qa,});
while(!q.empty())
{
dij t=q.top();
q.pop();
int x=t.x;
if(vis[x])
{
continue;
}
vis[x]=;
for(int i=head[x];i;i=way[i].next)
{
int to=way[i].to;
if(!vis[to]&&dis[to]>dis[x]+way[i].val)
{
ins[to]=what[i];
dis[to]=dis[x]+way[i].val;
q.push((dij){to,dis[to]});
}
}
}
}
int main()
{
//freopen("testdata.in","r",stdin);
n=read();
m=read();
for(int i=;i<=m;i++)
{
a[i]=read();
b[i]=read();
c[i]=read();
add(a[i],b[i],c[i],i);
add(b[i],a[i],c[i],i);
}
dijkstra();
tot=;
memset(head,,sizeof(head));
for(int i=;i<=n;i++)
{
int x=ins[i];
add(a[x],b[x]);
add(b[x],a[x]);
iiis[x]=;
}
dfs();
int sum=;
for(int i=;i<=m;i++)
{
if(iiis[i])
{
continue;
}
usaco[++sum]=(date){a[i],b[i],dis[a[i]]+dis[b[i]]+c[i]};
}
sort(usaco+,usaco++sum,cmp);
for(int i=;i<=n;i++)
{
fa[i]=i;
ans[i]=-;
}
for(int i=;i<=sum;i++)
{
int x=usaco[i].x;
int y=usaco[i].y;
x=find(x);
y=find(y);
while(x!=y)
{
if(dis[x]<dis[y])
{
swap(x,y);
}
ans[x]=usaco[i].w-dis[x];
fa[x]=father[x];
x=find(x);
}
}
for(int i=;i<=n;i++)
{
printf("%d\n",ans[i]);
// cout<<ans[i]<<endl;
}
return ;
}

「BZOJ1576」[Usaco2009 Jan] 安全路经Travel------------------------P2934 [USACO09JAN]安全出行Safe Travel的更多相关文章

  1. luogu P2934 [USACO09JAN]安全出行Safe Travel

    题目链接 luogu P2934 [USACO09JAN]安全出行Safe Travel 题解 对于不在最短路树上的边(x, y) 1 | | t / \ / \ x-----y 考虑这样一种形态的图 ...

  2. P2934 [USACO09JAN]安全出行Safe Travel

    P2934 [USACO09JAN]安全出行Safe Travel https://www.luogu.org/problemnew/show/P2934 分析: 建出最短路树,然后考虑一条非树边u, ...

  3. 洛谷—— P2934 [USACO09JAN]安全出行Safe Travel || COGS ——279|| BZOJ——1576

    https://www.luogu.org/problem/show?pid=2934 题目描述 Gremlins have infested the farm. These nasty, ugly ...

  4. ●洛谷P2934 [USACO09JAN]安全出行Safe Travel

    题链: https://www.luogu.org/problemnew/show/P2934 题解: 最短路(树),可并堆(左偏堆),并查集. 个人感觉很好的一个题. 由于题目已经明确说明:从1点到 ...

  5. 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集

    [BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...

  6. [USACO09JAN]安全出行Safe Travel 最短路,并查集

    题目描述 Gremlins have infested the farm. These nasty, ugly fairy-like creatures thwart the cows as each ...

  7. [USACO09JAN]安全出行Safe Travel

    题目 什么神仙题啊,我怎么只会\(dsu\)啊 我们考虑一个非常暴力的操作,我们利用\(dsu\ on \ tree\)把一棵子树内部的非树边都搞出来,用一个堆来存储 我们从堆顶开始暴力所有的边,如果 ...

  8. 【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel

    有趣的思考题 Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第 ...

  9. bzoj 1576: [Usaco2009 Jan]安全路经Travel 树链剖分

    1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 665  Solved: 227[Sub ...

随机推荐

  1. 纯CSS焦点轮播效果-功能可扩展

    个人博客: http://mcchen.club 纯CSS3实现模拟焦点轮播效果,支持JQ等扩展各项功能.废话少说,直接贴代码. <!DOCTYPE html> <html> ...

  2. 版本控制之Git小结

    一.版本控制 1.1 什么是版本控制 版本控制是一种记录一个或若干个文件内容变化,以便将来查阅特定版本修订情况的系统.可以对任何类型的文件进行版本控制. 1.2 为什么需要版本控制 有了版本控制就可以 ...

  3. mydumper 介绍及使用

    1 Mydumper 介绍 Mydumper是一个针对MySQL和Drizzle的高性能多线程备份和恢复工具. Mydumper主要特性: 轻量级C语言写的 多线程备份,备份后会生成多个备份文件 事务 ...

  4. B-概率论-条件概率

    目录 条件概率 一.条件概率简介 二.条件概率推广 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblo ...

  5. 局部敏感哈希LSH(Locality-Sensitive Hashing)——海量数据相似性查找技术

    一. 前言     最近在工作中需要对海量数据进行相似性查找,即对微博全量用户进行关注相似度计算,计算得到每个用户关注相似度最高的TOP-N个用户,首先想到的是利用简单的协同过滤,先定义相似性度量(c ...

  6. Unreal Engine 4 系列教程 Part 1:入门

    原文:Unreal Engine 4 Tutorial for Beginners: Getting Started 作者:Tommy Tran 译者:Shuchang Liu 本篇教程将引导你安装U ...

  7. Unreal Engine 4 系列教程 Part 2:蓝图教程

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  8. 攻防世界(XCTF)WEB(进阶区)write up(一)

      cat ics-05 ics-06 lottery Cat XCTF 4th-WHCTF-2017 输入域名  输入普通域名无果  输入127.0.0.1返回了ping码的结果 有可能是命令执行 ...

  9. USACO环绕岛屿Surround the Islands 并查集 枚举暴力

    题目描述 Farmer John has bought property in the Caribbean and is going to try to raise dairy cows on a b ...

  10. Python开发【第五篇】字符串

    字符串 作用:用来记录文字信息 例子: 空字符串 '' #单引号空字符串 "" #双引号空字符串 ''' ''' #三单引号空字符串 """ &quo ...