zoukankan      html  css  js  c++  java
  • [HNOI2014]道路堵塞

    题目描述

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    4 5 2
    1 2 2
    1 3 2
    3 4 4
    3 2 1
    2 4 3
    1 5
    输出样例#1:
    6
    6

    说明

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

    题解:

    玄学大火题,有这样一个结论:

    去掉最短路上的一条边后,那么现在的最短路一定是 先沿原最短路走一段->再绕原非最短路走一端->再走回原最短路.

    所以我们就可以开始乱搞,从1开始枚举删除最短路上的边,然后用该边的左端点,在断掉该边后,去松弛原最短路上编号大于该点的点,

    然后答案就是f[u]+last[u] (last[u]为u到n的最短路) 注意此题f数组不需要清空,然后我们就把f[u]+last[u]加入堆中,然后每一组询问我们先删除不合法的点(u在最短路上的编号小于当前边左端点编号),然后当前的堆顶就是答案,堆为空就是-1

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <queue>
     8 using namespace std;
     9 const int N=100005,M=200005;
    10 int gi(){
    11     int str=0;char ch=getchar();
    12     while(ch>'9' || ch<'0')ch=getchar();
    13     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
    14     return str;
    15 }
    16 int n,m,ps,num=0,head[N];
    17 struct Lin{
    18     int next,to,dis,id;
    19 }a[M];
    20 void init(int x,int y,int dis,int ids){
    21     a[++num].next=head[x];a[num].to=y;a[num].dis=dis;a[num].id=ids;head[x]=num;
    22 }
    23 struct edge{
    24     int x,y,dis;
    25 }e[M];
    26 struct node{
    27     int id,dist;
    28     bool operator <(const node &pp)const{
    29         return dist>pp.dist;
    30     }
    31 };
    32 priority_queue<node>st;
    33 int last[N],imp[M],f[N],q[N*10],mod=N*10,id[N];bool vis[N],mark[N];
    34 void spfa(int k)
    35 {
    36     memset(vis,0,sizeof(vis));
    37     int t=0,sum=1,x,u;q[1]=e[k].x;vis[e[k].x]=true;
    38     while(t!=sum){
    39         t++;if(t==mod)t-=mod;x=q[t];
    40         for(int i=head[x];i;i=a[i].next){
    41             if(a[i].id==k)continue;
    42             u=a[i].to;
    43             if(f[x]+a[i].dis<f[u]){
    44                 f[u]=a[i].dis+f[x];
    45                 if(mark[u] && id[u]>id[e[k].x]){
    46                     st.push((node){u,f[u]+last[u]});
    47                 }
    48                 if(!vis[u] && !mark[u]){
    49                     vis[u]=true;
    50                     sum++;if(sum==mod)sum-=mod;q[sum]=u;
    51                 }
    52             }
    53         }
    54         vis[x]=false;
    55     }
    56 }
    57 void work()
    58 {
    59     n=gi();m=gi();ps=gi();
    60     for(int i=1;i<=m;i++){
    61         e[i].x=gi();e[i].y=gi();e[i].dis=gi();
    62         init(e[i].x,e[i].y,e[i].dis,i);
    63     }
    64     for(int i=1;i<=ps;i++)imp[i]=gi(),id[e[imp[i]].y]=id[e[imp[i]].x]+1;
    65     for(int i=ps;i>=1;i--){
    66         last[e[imp[i]].x]=last[e[imp[i]].y]+e[imp[i]].dis;
    67         mark[e[imp[i]].x]=true;mark[e[imp[i]].y]=true;
    68     }
    69     int x,y;
    70     memset(f,127/3,sizeof(f));f[1]=0;
    71     for(int i=1;i<=ps;i++){
    72         x=e[i].x;y=e[i].y;
    73         if(i>1)f[e[imp[i-1]].y]=f[e[imp[i-1]].x]+e[imp[i-1]].dis;
    74         spfa(imp[i]);
    75         while(!st.empty() && id[st.top().id]<=id[e[imp[i]].x])st.pop();
    76         if(st.empty())printf("-1
    ");
    77         else{
    78             printf("%d
    ",st.top().dist);
    79         }
    80     }
    81 }
    82 int main()
    83 {
    84     work();
    85     return 0;
    86 }
  • 相关阅读:
    UIImageView动画 UISlider控制速度
    python学习笔记——装饰器
    python学习笔记——继承
    python学习笔记——异步IO
    思路清楚的最大堆实现
    推荐几个IDEA必备的好用插件
    记工作中遇到的Date类相关的坑
    navicat数据库表数据复制到excel产生的列错位问题
    submit提交时进行页面验证
    SublimeText3常用快捷键和优秀插件(转载)
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7218530.html
Copyright © 2011-2022 走看看