zoukankan      html  css  js  c++  java
  • [BZOJ2125]最短路

    题目大意:
      给定一个$n(nleq10000)$个点的仙人掌,$q$组询问,每次询问两点间的最短路。

    思路:
      将仙人掌上问题转化为树上问题。以$1$为根,求出单源最短路。然后选择每个环中深度最小的点作为环的关键点,将原来环中的边删除,并让环中每个点都连向这个关键点,这样原图就变成了一个树。这样两点间距离可以通过LCA求出,最后如果两点路径中连向LCA的两条边在同一条环上,需要特判环上的两种情况。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<climits>
      4 #include<functional>
      5 #include<ext/pb_ds/priority_queue.hpp>
      6 inline int getint() {
      7     register char ch;
      8     while(!isdigit(ch=getchar()));
      9     register int x=ch^'0';
     10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     11     return x;
     12 }
     13 const int N=10001,logN=14,M=40000;
     14 int n,m,sz,dis[N],dep[N],dfn[N],head[N],last[N],cir[N],len[N],dis2[N],anc[N][logN];
     15 struct Edge {
     16     int from,to,w,next;
     17 };
     18 Edge e[M];
     19 inline void add_edge(const int &u,const int &v,const int &w=0) {
     20     e[sz]=(Edge){u,v,w,head[u]},head[u]=sz++;
     21     e[sz]=(Edge){v,u,w,head[v]},head[v]=sz++;
     22 }
     23 struct Vertex {
     24     int id,dis;
     25     bool operator > (const Vertex &another) const {
     26         return dis>another.dis;
     27     }
     28 };
     29 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
     30 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[N];
     31 void dijkstra() {
     32     for(register int i=1;i<=n;i++) {
     33         p[i]=q.push((Vertex){i,dis[i]=i==1?0:INT_MAX});
     34     }
     35     while(!q.empty()) {
     36         const int &x=q.top().id;
     37         for(register int i=head[x];~i;i=e[i].next) {
     38             const int &y=e[i].to,&w=e[i].w;
     39             if(dis[x]+w<dis[y]) {
     40                 q.modify(p[y],(Vertex){y,dis[y]=dis[x]+w});
     41             }
     42         }
     43         q.pop();
     44     }
     45 }
     46 inline int lg2(const float &x) {
     47     return ((unsigned&)x>>23&255)-127;
     48 }
     49 void cut(int x,const int y,const int &id) {
     50     e[id].to=e[id^1].to=0;
     51     len[++cir[0]]=e[id].w;
     52     for(;x!=y;x=e[last[x]].from) {
     53         e[last[x]].to=e[last[x]^1].to=0;
     54         len[cir[x]=cir[0]]+=e[last[x]].w;
     55         add_edge(x,y);
     56     }
     57 }
     58 void dfs(const int &x) {
     59     dfn[x]=++dfn[0];
     60     for(register int i=head[x];~i;i=e[i].next) {
     61         if(i==(last[x]^1)||i>=m*2) continue;
     62         const int &y=e[i].to,&w=e[i].w;
     63         if(!dfn[y]) {
     64             last[y]=i;
     65             dis2[y]=dis2[x]+w;
     66             dfs(y);
     67         } else if(dfn[y]<dfn[x]) {
     68             cut(x,y,i);
     69         }
     70     }
     71 }
     72 void dfs2(const int &x,const int &par) {
     73     dep[x]=dep[anc[x][0]=par]+1;
     74     for(register int i=1;i<=lg2(dep[x]);i++) {
     75         anc[x][i]=anc[anc[x][i-1]][i-1];
     76     }
     77     for(register int i=head[x];~i;i=e[i].next) {
     78         const int &y=e[i].to;
     79         if(y&&y!=par) dfs2(y,x);
     80     }
     81 }
     82 int calc(const int &u,const int &v) {
     83     int x=u,y=v;
     84     if(dep[x]!=dep[y]) {
     85         if(dep[x]<dep[y]) std::swap(x,y);
     86         for(register int i=lg2(dep[x]-dep[y]);~i;i--) {
     87             if(dep[anc[x][i]]>=dep[y]) x=anc[x][i];
     88         }
     89     }
     90     if(x==y) return dis[u]+dis[v]-dis[x]*2;
     91     for(register int i=lg2(dep[x]);~i;i--) {
     92         if(anc[x][i]!=anc[y][i]) {
     93             x=anc[x][i];
     94             y=anc[y][i];
     95         }
     96     }
     97     if(cir[x]&&cir[x]==cir[y]) return dis[u]+dis[v]-dis[x]-dis[y]+std::min(std::abs(dis2[x]-dis2[y]),len[cir[x]]-std::abs(dis2[x]-dis2[y]));
     98     return dis[u]+dis[v]-dis[anc[x][0]]*2;
     99 }
    100 int main() {
    101     n=getint(),m=getint();
    102     const int q=getint();
    103     for(register int i=1;i<=n;i++) head[i]=last[i]=-1;
    104     for(register int i=0;i<m;i++) {
    105         const int u=getint(),v=getint(),w=getint();
    106         add_edge(u,v,w);
    107     }
    108     dijkstra();
    109     dfs(1);
    110     dfs2(1,0);
    111     for(register int i=0;i<q;i++) {
    112         printf("%d
    ",calc(getint(),getint()));
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    [置顶] kubernetes资源类型--DaemonSet
    Docker容器的自动化监控实现
    [置顶] docker--基础镜像和dockerfile
    Target runtime Apache Tomcat v8.0 is not defined
    jeecg-org.jeecgframework.web.system.listener.InitListener
    tomcat:利用tomcat部署war包格式的项目
    更换jdk版本:jdk1.8更换为jdk1.7之后输入java -version还是出现1.8的版本号
    Maven项目下WEB-INFO目录下没有编译的classes文件
    解决maven web项目Cannot detect Web Project version. Please specify version of Web Project through...的错误
    如何提高maven的下载速度:享受一下mvn时飞的感觉
  • 原文地址:https://www.cnblogs.com/skylee03/p/8526302.html
Copyright © 2011-2022 走看看