图论瞎搞......

solution:

按例化简:给定一个无向图,保证单源最短路唯一,求每个点到1号点的最短路最后一条边被封锁的情况下的最短路

乍一看,应该是次短路,但是稍微用脚趾头想想都能发现不是次短路.....

然后就乱搞了一发。秉承着我们的口号

暴力碾标算,n方过百万

我试着搞了一发暴力:先求出最短路径树(很重要),然后对于每一个点的父亲(前一个节点)进行dij拓展,不走被封的边,然后遇到目标点就退出(思路来源:旅行者

然后我发现,不仅仅会T,甚至这个思路就是错的!!!

1、为什么会T:旅行者那题相当于只找一个最短边权当做最短路,因此dij的拓展过程可以认为是O(1)的;

2、为什么会wa:来看样例:

我弄出来的最短路径树是这样的:

根据以上思路,只需要求出dis(最短路),还有从父亲节点拓展的dis,加起来即可。

但是,当走到2,拓展4的时候:拓展的非树边和之前的最短路加起来,变成了7!?

但是,如果换一条路走,答案应该是6......

所以,这个思路到此终结(我170+lines的代码啊!!!!)

正解:(对,没错,这里才开始正解)

首先,最短路径树的思路要保留,这里有一个比较玄学的式子:

min(dis(u,v)(边权)+dis(u)-dis(v)+dis(v));

要求根到f的路径径,只需要知道根到u的最短路-根到f的最短路(也就是f到u的一条路径)加上根到v的最短路,再加上u到v的边权,这样就完成了一次拓展。

于是,就维护这个式子,用并查集维护联通(据机房大佬说这是并查集缩边233)

  • 把所有非树边 记录下来
  • 枚举点
  • 更新式子
  • 维护连通
  • 进行n-1次

说明一下,为什么要用并查集:

因为排序,所以每一个点更新的第一次就是它的最优解,不需要更新第二次,所以用一个并查集来保证每个点只跑一次。

就是这样....据说spfa会被卡?本人专门卡各种卡spfa.....

就这样,我用玄学读优、流氓spfa,各种常数优化(好吧其实没有进行常数优化),跑进了某谷的最优解榜....

注意一下,要判断无解.....

(注释代码)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+;
int n,m;
inline int read()//当时为了跟旁边大佬比赛速度而加的读入优化
{
int x=,f=;char s=getchar();
while(s>''||s<''){if(s=='-')f=-;s=getchar();}
while(s<=''&&s>=''){x=x*+s-'';s=getchar();}
return f*x;
}
struct edge//前向星存边
{
int to,next,dis;
}e[maxn];
int cnt,head[maxn];
inline void addedge(int from,int to,int dis)
{
e[++cnt].next=head[from];
e[cnt].to=to;
e[cnt].dis=dis;
head[from]=cnt;
}
int fa[maxn];
int dis[maxn];
struct cmp
{
bool operator ()(int a,int b)
{
return dis[a]>dis[b];
}
};//spfa优化
priority_queue <int,vector<int>,cmp> q;
int vis[maxn];
inline void spfa(int s)//比较普通得spfa
{
for(int i=;i<=n;i++)
{
dis[i]=0x7fffffff;
vis[i]=;
}
vis[s]=;
dis[s]=;
q.push(s);
while(!q.empty())
{
int u=q.top();
q.pop();
vis[u]=;
for(register int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[u]+e[i].dis)
{
dis[v]=dis[u]+e[i].dis;
fa[v]=u;//注意,最短路径树在此建立,在更新最短路的同时更新最短路径树上当前点的fa,也就是父节点,跑完spfa就能得到最短路径树了
if(vis[v]==)
{
vis[v]=;
q.push(v);
}
}
}
}
} struct tree
{
int u,v,w;
}a[maxn];//记录非树边
bool cmp(tree a,tree b)
{
return a.w<b.w;//快排
}
int f[maxn],ans[maxn];
int num;
//int find(int x){return f[x]==x?x:f[x]=find(f[x]));}令附一行并查集
int find(int x)//不想一行并查集
{
if(f[x]==x)
return x;
return f[x]=find(f[x]);
}
void solve(tree x)
{
int u=x.u,v=x.v,t=x.w;
while(find(u)!=find(v))//维护每个点只跑一次
{
num++;
if(dis[find(u)]<dis[find(v)])
swap(u,v);//确保两个点的顺序
ans[find(u)]=min(ans[find(u)],t-dis[find(u)]);//更新
u=f[find(u)]=fa[find(u)];//合并
}
}
int tot;
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int x,y,z;
x=read();y=read();z=read();//scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
addedge(y,x,z);
}
spfa();
for(int i=;i<=cnt;i+=)
{
int u=e[i].to;//寻找非树边
int v=e[i-].to;;
if(u!=fa[v]&&v!=fa[u])//如果u和v不是最短路径树上的父子关系但是是一条边上的两个点
{
a[++tot].u=u;//它就是非树边
a[tot].v=v;
a[tot].w=e[i].dis+dis[u]+dis[v];//根据上述式子更新边权
}
} sort(a+,a++tot,cmp);//记得排序
for(int i=;i<=n;i++)
{
f[i]=i;//并查集要初始化
ans[i]=;
}
for(int i=;i<=tot&&num<n-;i++)
{
solve(a[i]);//对每个点进行更新
}
for(int i=;i<=n;i++)
{
if(ans[i]!=)
printf("%d\n",ans[i]);
else//判断无解
printf("-1\n");
}
return ;
}

(完)

P2934 [USACO09JAN]安全出行的更多相关文章

  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

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

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

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

  5. [USACO09JAN]安全出行Safe Travel

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

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

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

  7. 「BZOJ1576」[Usaco2009 Jan] 安全路经Travel------------------------P2934 [USACO09JAN]安全出行Safe Travel

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

  8. 几校联考——day1题解

    T1 约数的个数(好像不可提交) 如果一个整数a能够整除整数b,那么a叫做b的约数.现在有N(1 <= N <= 100,000)个整数,对于其中的每一个数,请找出它在其余N - 1个整数 ...

  9. 算法是什么我记不住,But i do it my way. 解一道滴滴出行秋招编程题。

    只因在今日头条刷到一篇文章,我就这样伤害我自己,手贱. 刷头条看到一篇文章写的滴滴出行2017秋招编程题,后来发现原文在这里http://www.cnblogs.com/SHERO-Vae/p/588 ...

随机推荐

  1. BT面板安装php报错configure: error: C preprocessor “/lib/cpp” fails sanity check

    使用宝塔面板安装扩展时已经显示添加安装成功了,待我刷新浏览器之后没有安装成功.看了一下执行日志. 缺少必要的C++库,如下命令重装解决. yum reinstall glibc-headers gcc ...

  2. IntelliJ IDEA使用JUnit单元测试

    转载:https://www.cnblogs.com/huaxingtianxia/p/5563111.html 前言 单元测试的基本使用 一.环境配置 使用idea IDE 进行单元测试,首先需要安 ...

  3. wamp server mysql数据库中事件不执行的解决办法

    先看看看event 事件是否开启 直接执行下列语句即可, show variables like '%sche%'; 如没开启,则开启. (需要数据库超级权限) set global event_sc ...

  4. Kubernetes集群的部署方式及详细步骤

    一.部署环境架构以及方式 第一种部署方式 1.针对于master节点 将API Server.etcd.controller-manager.scheduler各组件进行yum install.编译安 ...

  5. SDL建设-三方依赖库扫描

    说明: 本文首发自 https://www.secpulse.com/archives/73373.html,转载请注明出处. 文章综述 本文主要介绍Dependency-Check工具的工作原理和使 ...

  6. PHP call_user_func的一些用法和注意点

    版本:PHP 5.6.28 在call_user_func的调用中: 1.参数的传递过程,并不是引用传值. 1 error_reporting(E_ERROR); // 此处不是E_ALL 2 $cu ...

  7. 《Java并发编程实战》读书笔记-第3章 对象的共享

    可见性 在没有同步的情况下,编译器.处理器以及运行时都可能做指令重排.执行结果可能会出现错误 volatile变量 编译器与运行时不会进行指令重排,不会进行缓存,使用volatile变量要满足以下条件 ...

  8. MS09-020 iis6.0提权

    漏洞编号:MS09-020 披露日期: 2009/6/9 受影响的操作系统:Windows 2003 x64 sp1 sp2;XP; 测试系统:windows 2003 x64   上传 执行 iis ...

  9. 『嗨威说』算法设计与分析 - 动态规划思想小结(HDU 4283 You Are the One)

    本文索引目录: 一.动态规划的基本思想 二.数字三角形.最大子段和(PTA)递归方程 三.一道区间动态规划题点拨升华动态规划思想 四.结对编程情况 一.动态规划的基本思想: 1.1 基本概念: 动态规 ...

  10. 百万年薪python之路 -- 文件操作

    1.文件操作: f = open("zcy.txt" , mode="r" , encoding="UTF-8") open() 打开 第一 ...