zoukankan      html  css  js  c++  java
  • [ BZOJ 3445 ] Roadblock

    (\)

    (Description)


    给出一张(N) 个点(M)条边的无向图,选择一条边使其权值翻倍,求操作后比操作前最短路长度增量最大值。

    • (1le Nle 250)(1le Mle 250000)

    (\)

    (Solution)


    首先这么稠密的图SPFA肯定爆炸

    • 注意到枚举哪条边权值翻倍再跑一遍最短路的做法复杂度是(Theta(M^2logN)),显然会超时。
    • 发现如果不使最短路上的边权翻倍最短路并不会发生变化,所以只需要考虑对原图最短路上的边操作即可。
    • 确定最短路的边可以通过反向枚举,若发现(dis[v]=dis[u]-e[i].w)则找到了上一个点。

    (\)

    (Code)


    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 255
    #define M 250010
    #define R register
    #define gc getchar
    using namespace std;
    
    bool vis[N];
    int n,m,res,ans,tot=1,hd[N],dis[N];
    
    struct edge{int to,nxt,w;}e[M<<1];
    inline void add(int u,int v,int w){
      e[++tot].w=w; e[tot].to=v;
      e[tot].nxt=hd[u]; hd[u]=tot;
    }
    
    inline int rd(){
      int x=0; bool f=0; char c=gc();
      while(!isdigit(c)){if(c=='-')f=1;c=gc();}
      while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
      return f?-x:x;
    }
    
    priority_queue<pair<int,int> > q;
    inline void dij(){
      memset(vis,0,sizeof(vis));
      memset(dis,0x3f,sizeof(dis));
      dis[1]=0; q.push(make_pair(0,1));
      while(!q.empty()){
        int u=q.top().second; q.pop();
        if(vis[u])continue; vis[u]=1;
        for(R int i=hd[u],v;i;i=e[i].nxt)
          if(dis[v=e[i].to]>dis[u]+e[i].w){
            dis[v]=dis[u]+e[i].w;
            q.push(make_pair(-dis[v],v));
          }
      }
    }
    
    vector<int> s;
    inline void find(){
      int u=n;
      while(u!=1){
          for(R int i=hd[u],v;i;i=e[i].nxt)
          if(dis[v=e[i].to]==dis[u]-e[i].w){
            s.push_back(i); u=v; break;
          }
      }
    }
    
    int main(){
      n=rd(); m=rd();
      for(R int i=1,u,v,w;i<=m;++i){
        u=rd(); v=rd(); w=rd();
        add(u,v,w); add(v,u,w);
      }
      dij(); res=dis[n]; find();
      for(R int i=0;i<(int)s.size();++i){
        e[s[i]].w<<=1; e[s[i]^1].w<<=1;
        dij(); ans=max(ans,dis[n]-res);
        e[s[i]].w>>=1; e[s[i]^1].w>>=1;
      }
      printf("%d
    ",ans);
      return 0;
    }
    
  • 相关阅读:
    ThreadLocal分析学习
    探究.NET的bin引用程序集运行机制看.NET程序集部署原理
    ASP.NET网页代码模型分析
    JBPM与设计模式之职责链模式
    根据webform页面大小的变化动态调整控件的大小
    jbpm binding类深入解析
    JBPM与软件架构模式之命令模式
    JBPM对象主键生成机制
    主键思维定势导致的惨案
    电脑安装windows server 2008 导致磁盘分区消失解决方法
  • 原文地址:https://www.cnblogs.com/SGCollin/p/9587977.html
Copyright © 2011-2022 走看看