BZOJ3575 HNOI2014 道路阻塞

3575: [Hnoi2014]道路堵塞

Time Limit: 10 Sec  Memory Limit: 128 MB

Description

A国有N座城市,依次标为1到N。同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数。现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的。不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞。现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少。

Input

输入文件第一行是三个用空格分开的正整数N、M和L,分别表示城市数目、单向道路数目和交通部指定的最短路径包含多少条道路。
按下来M行,每行三个用空格分开的整数a、b和c,表示存在一条由城市a到城市b的长度为c的单向道路。这M行的行号也是对应道路的编号,即其中第1行对应的道路编号为1,第2行对应的道路编号为2,…,第M行对应的道路编号为M。最后一行为L个用空格分开的整数sp(1)…,,sp(L),依次表示从城市1到城市N的由交通部指定的最短路径上的道路的编号。

Output

输出文件包含L行,每行为一个整数,第i行(i=1,2…,,L)的整数表示删去编号为sp(i)的道路后从城市1到城市N的最短路径长度。如果去掉后没有从城市1到城市N的路径,则输出一1。

Sample Input

4 5 2
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
1 5

Sample Output

6
6

HINT

100%的数据满足2<N<100000,1<M<200000。所用道路长度大于0小于10000。
数据已加强By Vfleaking

  你看见我的跳蚤国王了吗?哦它被FFF了?资磁!

  这题真是火的冒烟,劲爆无比,谁也想不到正解来自一个很扯淡的证明。

  正解:SPFA鬼畜技巧。

  因为它已经钦定了最短路,而且要对最短路上每一条边输出一次答案,所以很容易想到正解是枚举BAN哪条边再鬼一鬼。

  这里有个十分扯淡的证明:新·最短路一腚是S->之前最短路上某一点p->之前最短路上某一点q->T;

  感觉并不知道怎么证明是吧,但如果我说S和p,q和T 可以为同一个点呢?

  那么所有的情况都被包含了是的吗?没错是的。您强×把答案放在了一个鬼证明上。

  所以按照这个证明的思想,我们枚举删掉最短路上的哪条边,然后把这条边的s加进队列做SPFA。

  但是这样不加优化的做法会让你过吗?答案是显然否定的。那么来点更劲的:

  先把最短路上的所有边都BAN掉,然后从S到T开始恢复边,并把s丢进队列。

  然后每次就可以不清空dis数组了,因为你之前SPFA的结果你都可以调用以前的结果。

  然后统计答案就是把走到的钦定最短路上的点的距离加上它到T的距离取个min就好了。这里有一个玄妙的做法就是把答案加上这个点放成结构体扔进堆里,每次弹出到达点在s之前的点因为这是在这条路被BAN的时候SPFA到的,不一定是当前的合法方案,也不会比最优答案更好。所以判完-1后,第一个在s之后的点就不管是不是s更新的点了,却又是一个合法的点,就避免了很多麻烦。

  代码还是很好看懂的。

#include    <iostream>
#include    <cstdio>
#include    <cstdlib>
#include    <algorithm>
#include    <vector>
#include    <cstring>
#include    <queue>
#include    <complex>
#include    <stack>
#define LL long long int
#define dob double
using namespace std;

const int N = 200010;
struct Node{int from,to,val,next;}E[N];
struct Data{int p,val;bool operator <(const Data &b)const{return val>b.val;}};
int n,m,L,head[N],tot,ban[N],rk[N],In[N],far[N],dis[N],fr[N],s[N];
queue<int>Q;priority_queue<Data>T;

int gi()
{
  int x=0,res=1;char ch=getchar();
  while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)res*=-1;ch=getchar();}
  while(ch<=‘9‘&&ch>=‘0‘)x=x*10+ch-48,ch=getchar();
  return x*res;
}

inline void link(int u,int v,int c)
{
  E[++tot]=(Node){u,v,c,head[u]};
  head[u]=tot;
}

inline void SPFA(int st)
{
  queue<int>Q;Q.push(st);
  while(!Q.empty()){
    int x=Q.front();Q.pop();In[x]=0;
    for(int e=head[x];e;e=E[e].next){
      if(ban[e])continue;int y=E[e].to;
      if(far[x]+E[e].val<far[y]){
        far[y]=far[x]+E[e].val;
        if(fr[y])T.push((Data){fr[y],far[y]+dis[fr[y]]});
        else if(!In[y])Q.push(In[y]=y);
      }
    }
  }
}

int main()
{
  n=gi();m=gi();L=gi();
  for(int i=1;i<=m;++i){
    int u=gi(),v=gi(),c=gi();
    link(u,v,c);
  }
  s[1]=1;fr[1]=1;
  for(int i=1;i<=L;++i){
    ban[rk[i]=gi()]=1;
    s[i+1]=E[rk[i]].to;
    fr[s[i+1]]=i+1;
  }
  for(int i=L;i;--i)
    dis[i]=dis[i+1]+E[rk[i]].val;
  memset(far,127/3,sizeof(far));far[1]=0;
  SPFA(1);
  for(int i=1;i<=L;++i){
    while(!T.empty() && T.top().p<=i)T.pop();
    if(T.empty())printf("-1\n");
    else printf("%d\n",T.top().val);
    far[E[rk[i]].to]=far[s[i]]+E[rk[i]].val;
    SPFA(s[i+1]);
  }
  return 0;
}

  

  这还真TMD妙不可言,玄之又玄,精妙绝伦啊(伦boy:嗯?)。

时间: 2024-09-30 07:03:43

BZOJ3575 HNOI2014 道路阻塞的相关文章

bzoj3575 [Hnoi2014]道路堵塞

Description A 国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径, 并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞. 现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少. Input 输入文件第一行是三个用空格分开的正整数N.M和L,分别表示城市数目.单向道路数目

bzoj 3575: [Hnoi2014]道路堵塞

Description A 国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径, 并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞. 现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少. Input 输入文件第一行是三个用空格分开的正整数N.M和L,分别表示城市数目.单向道路数目

[HNOI2014]道路堵塞

题目描述 A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞.现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少. 输入输出格式 输入格式: 输入文件第一行是三个用空格分开的正整数N.M和L,分别表示城市数目.单向道路数目和交通

第10章 智能交通

10.1智能交通概述 10.1.1传统交通与智能交通   10.1.2智能交通的定义 智能交通在世界各地迅速推进,已成为现代交通的重要标志,然而,对于这个专用名词,国际上至今没有一个明确的定义.在美.欧.日的ITS推进组织的网页或有关资料中,我们看到分别有如下的叙述. “美国智能运输协会”(ITS America网址为型:i!望:Q蟹):ITS是由一些技术组成的,这些技术包括信息处理.通信.控制和电子技术.交通事故.拥挤使我们为生活.为损失的 生产率和浪费的能源付出了昂贵的代价.ITS可以通过新

bzoj 3572 [Hnoi2014]世界树(虚树+DP)

3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 645  Solved: 362[Submit][Status][Discuss] Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石.     世界树的形态可以用一个数学模型来描述:世界树中有n个

JVM 并发性: 阻塞还是不阻塞?

在任何并发性应用程序中,异步事件处理都至关重要.事件来源可能是不同的计算任务.I/O 操作或与外部系统的交互.无论来源是什么,应用程序代码都必须跟踪事件,协调为响应事件而采取的操作.Java 应用程序可采用两种基本的异步事件处理方法:该应用程序有一个协调线程等待事件,然后采取操作,或者事件可在完成时直接执行某项操作(通常采取执行应用程序所提供的代码的方式).让线程等待事件的方法被称为阻塞 方法.让事件执行操作.线程无需显式等待事件的方法被称为非阻塞 方法. 旧的 java.util.concur

【HNOI2014】世界树

P2354 - [HNOI2014]世界树 Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石. 世界树的形态可以用一个数学模型来描述:世界树中有n个种族,种族的编号分别从1到n,分别生活在编号为1到n的聚居地上,种族的编号与其聚居地的编号相 同.有的聚居地之间有双向的道路相连,道路的长度为1.保证连接的方式会形成一棵树结构,即所有

从零讲Java,给你一条清晰地学习道路!该学什么就学什么!

从零讲JAVA ,给你一条 清晰地学习道路!该学什么就学什么! 1.计算机基础: 1.1数据机构基础: 主要学习:1.向量,链表,栈,队列和堆,词典.熟悉2.树,二叉搜索树.熟悉3.图,有向图,无向图,基本概念4.二叉搜索A,B,C类熟练,9大排序熟悉.5.树的前中后,层次,之字,最短路.6.KMP等字符串算法. 1.2操作系统: 主要学习:1.进程,线程,进程线程区别.进程间通信2.进程调度算法理解3.存储,虚拟内存,分页分段,内存调度算法4.文件系统,链式,索引5.死锁:原因,避免,解除k6

[HNOI2014][BZOJ3572] 世界树|虚树|树上倍增LCA|树型dp|dfs序

3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 555  Solved: 319[Submit][Status][Discuss] Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石.    世界树的形态可以用一个数学模型来描述:世界树中有n个种