求出最短路径树,对于一个询问(x,y) 若不在树上S->T的链上,则答案不变,若在链上,考虑用一条非树边替换这条边,这条非树边必须跨越x->y这条边,线段树维护区间最小值

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<queue>
  4. #include<cstring>
  5. #define pr pair<long long,int>
  6. #define mp make_pair
  7. #define sc second
  8. using namespace std;
  9. int cnt,n,m,last[200005],Lv[200005],stack[200005],Fa[200005],vis[200005],pre[200005],Vis[1000005];
  10. long long dis[200005][2],Dep[200005],ANS[200005],tree[800005];
  11. priority_queue<pr,vector<pr>,greater<pr> > q;
  12. struct node{
  13. int to,next;
  14. long long val;
  15. }e[400005];
  16. struct node1{
  17. int x,y,val;
  18. }E[200005];
  19. void add(int a,int b,int c){
  20. e[++cnt].to=b;
  21. e[cnt].next=last[a];
  22. e[cnt].val=c;
  23. last[a]=cnt;
  24. }
  25. void Dijkstra(int S,int cas){
  26. for (int i=1; i<=n; i++) dis[i][cas]=1ll<<60,vis[i]=0;
  27. dis[S][cas]=0;
  28. q.push(mp(0ll,S));
  29. while (!q.empty()){
  30. int x=q.top().sc;
  31. q.pop();
  32. if (vis[x]) continue;
  33. vis[x]=1;
  34. for (int i=last[x]; i; i=e[i].next){
  35. int V=e[i].to;
  36. if (dis[V][cas]>dis[x][cas]+e[i].val){
  37. dis[V][cas]=dis[x][cas]+e[i].val;
  38. if (cas==0) pre[V]=x;
  39. q.push(mp(dis[V][cas],V));
  40. }
  41. }
  42. }
  43. }
  44. void Pre(int x,int fa,long long dep){
  45. Fa[x]=fa,Dep[x]=dep;
  46. for (int i=last[x]; i; i=e[i].next){
  47. int V=e[i].to;
  48. if (V==fa) continue;
  49. Pre(V,x,dep+e[i].val);
  50. }
  51. }
  52. void solve(int x,int lv){
  53. vis[x]=1;
  54. Lv[x]=lv;
  55. for (int i=last[x]; i; i=e[i].next){
  56. int V=e[i].to;
  57. if (vis[V]) continue;
  58. solve(V,lv);
  59. }
  60. }
  61. bool cmp(node a,node b){
  62. return a.to<b.to;
  63. }
  64. void insert(int t,int l,int r,int x,long long key){
  65. if (l==r){
  66. tree[t]=min(tree[t],key);
  67. return;
  68. }
  69. int mid=(l+r)>>1;
  70. if (x<=mid) insert(t<<1,l,mid,x,key);
  71. else insert(t<<1|1,mid+1,r,x,key);
  72. tree[t]=min(tree[t<<1],tree[t<<1|1]);
  73. }
  74. long long query(int t,int l,int r,int x,int y){
  75. if (r<x || l>y) return 1ll<<60;
  76. if (l>=x && r<=y) return tree[t];
  77. int mid=(l+r)>>1;
  78. return min(query(t<<1,l,mid,x,y),query(t<<1|1,mid+1,r,x,y));
  79. }
  80. void build(int t,int l,int r){
  81. if (l==r){
  82. tree[t]=1ll<<60;
  83. return;
  84. }
  85. int mid=(l+r)>>1;
  86. build(t<<1,l,mid);
  87. build(t<<1|1,mid+1,r);
  88. tree[t]=max(tree[t<<1],tree[t<<1|1]);
  89. }
  90. int main(){
  91. scanf("%d%d",&n,&m);
  92. for (int i=1; i<=m; i++){
  93. scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].val);
  94. add(E[i].x,E[i].y,E[i].val);
  95. add(E[i].y,E[i].x,E[i].val);
  96. }
  97. int S,T;
  98. scanf("%d%d",&S,&T);
  99. Dijkstra(S,0);
  100. Dijkstra(T,1);
  101. cnt=0;
  102. memset(vis,0,sizeof(vis));
  103. for (int i=1; i<=n; i++) last[i]=0;
  104. for (int i=1; i<=n; i++)
  105. if (pre[i]) {
  106. add(pre[i],i,dis[i][0]-dis[pre[i]][0]);
  107. add(i,pre[i],dis[i][0]-dis[pre[i]][0]);
  108. }
  109. Lv[S]=1;
  110. Pre(S,0,0);
  111. int now=T,top=0;
  112. while (now){
  113. stack[++top]=now;
  114. vis[now]=1;
  115. Vis[now]=top;
  116. now=Fa[now];
  117. }
  118. for (int i=1; i<=top/2; i++) swap(stack[i],stack[top-i+1]);
  119. for (int i=1; i<=top; i++) solve(stack[i],i);
  120. int cnt=0;
  121. for (int i=1; i<=m; i++){
  122. int x=E[i].x,y=E[i].y;
  123. if (Vis[x] && Vis[y] && (Vis[y]==Vis[x]+1 || Vis[x]==Vis[y]+1)) continue;
  124. int X=Lv[x],Y=Lv[y];
  125. if (X>Y) swap(X,Y),swap(x,y);
  126. e[++cnt]=(node){X,Y,dis[x][0]+dis[y][1]+E[i].val};
  127. }
  128. sort(e+1,e+cnt+1,cmp);
  129. build(1,1,top);
  130. int Top=1;
  131. for (int i=1; i<top; i++){
  132. while (Top<=cnt && e[Top].to<=i){
  133. insert(1,1,top,e[Top].next,e[Top].val);
  134. Top++;
  135. }
  136. ANS[i]=query(1,1,top,i+1,top);
  137. }
  138. int q;
  139. scanf("%d",&q);
  140. int cc=0;
  141. while (q--){
  142. cc++;
  143. int x,y;
  144. scanf("%d%d",&x,&y);
  145. if (Vis[x] && Vis[y] && (Vis[x]==Vis[y]+1 || Vis[y]==Vis[x]+1)){
  146. if (dis[T][0]==1ll<<60) printf("Infinity\n");
  147. else{
  148. int X=Lv[x],Y=Lv[y];
  149. if (X>Y) swap(X,Y);
  150. if (ANS[X]!=1ll<<60) printf("%lld\n",ANS[X]);
  151. else printf("Infinity\n");
  152. }
  153. }
  154. else {
  155. if (dis[T][0]!=1ll<<60) printf("%lld\n",dis[T][0]);
  156. else printf("Infinity\n");
  157. }
  158. }
  159. return 0;
  160. }

  

BZOJ 2725: [Violet 6]故乡的梦的更多相关文章

  1. BZOJ 2725: [Violet 6]故乡的梦 最短路+线段树

    2725: [Violet 6]故乡的梦 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 678  Solved: 204[Submit][Status ...

  2. [原博客] BZOJ 2725 : [Violet 6]故乡的梦

    这个题在bzoj上好像是个权限题,想做的可以去Vani的博客下载测试数据.这里有题面. 简单叙述一下题意:给你一个n个点.m条边的带权无向图,S点和T点,询问Q次删一条给定的边的S-T最短路. 其中  ...

  3. BZOJ 2725 [Violet 6]故乡的梦 线段树+最短路树

    \(\color{#0066ff}{ 题目描述 }\) \(\color{#0066ff}{输入格式}\) \(\color{#0066ff}{输出格式}\) \(\color{#0066ff}{输入 ...

  4. BZOJ2725 : [Violet 6]故乡的梦

    如果S==T,那么答案为0. 如果S与T不连通,那么答案为inf. 否则,S到T的最短路径上至少有一条边. 求出以S为源点的最短路图,是个DAG,随便抓一条S到T的最短路,记为P. 设dpS[x]表示 ...

  5. 【BZOJ-2725】故乡的梦 Dijsktra + Tarjan + Dinic + BFS + 堆

    2725: [Violet 6]故乡的梦 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 502  Solved: 173[Submit][Status ...

  6. 二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园

    BZOJ 2709: [Violet 1]迷宫花园 Sample Input 5 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ## ...

  7. [violet6] 故乡的梦

    题目 描述 不知每日疲于在城市的水泥森林里奔波的你会不会有时也曾向往过乡村的生活.你会不会幻想过,在夏日一个静谧的午后,你沉睡于乡间路边的树荫里,一片叶子落在了你的肩上, 而你正做着一个悠长的梦,一个 ...

  8. BZOJ 2716: [Violet 3]天使玩偶

    2716: [Violet 3]天使玩偶 Time Limit: 80 Sec  Memory Limit: 128 MBSubmit: 1473  Solved: 621[Submit][Statu ...

  9. BZOJ 2724: [Violet 6]蒲公英

    2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1633  Solved: 563[Submit][Status ...

随机推荐

  1. js操作表格

    js 操作table: insertRow(),deleteRow(),insertCell(),deleteCell()方法 表格有几行: var trCnt = table.rows.length ...

  2. Django 使用allauth报错

    一:报错 RuntimeError: Model class django.contrib.sites.models.Site doesn't declare an explicit app_labe ...

  3. CocoaPods 提交自己的库

    今想把自己写的一个view提交到CocoaPods时候,突然发现pull request被拒了,原来从去年开始就改用trunk了... 网上那些folk 在提交的pull request的教程都不可用 ...

  4. WGET and CURL

    目录 WGET and CURL 对比 wget curl curl使用示例 WGET and CURL 对比 CURL 和WGET都可以用来下载文件,用法也类似:curl/wget [-option ...

  5. Spring之WebContext不使用web.xml启动 初始化重要的类源码分析(Servlet3.0以上的)

    入口: org.springframework.web.SpringServletContainerInitializer implements ServletContainerInitializer ...

  6. mysql添加用户并赋予权限命令

    添加用户: create user 'gouge'@'localhost' identified by 'gouge'; 赋予权限: 给gouge 用户赋予所有test开头的数据库权限 (test% ...

  7. Navicate Premium连接Oracle数据库报错

    Navicat Premium连接MySQL数据库没有问题,在连接Oracle数据库的时候报错,提示:ORA-28547:connection to server failed,probable Or ...

  8. IE如何实现text-shadow文字阴影效果呢?

    让我们头痛的是IE是不支持text-shadow效果,但为了在兼容这一问题,我们只好使用滤镜filter:shadow来处理(本人不提倡使用滤镜).filter:shadow滤镜作用与dropshad ...

  9. jsp实现账户登录、注册!

    jsp连接mysql数据库进行账户登录验证和账户注册 ~jsp: Login.jsp .LoginCl.jsp.Welcome.jsp.Register.jsp.login.css login.css ...

  10. 查看Windows激活信息

    使用 Windows + R组合快捷键打开运行命令框 1.运行: slmgr.vbs -dlv 可以查询到Win10的激活信息,包括:激活ID.安装ID.激活截止日期等信息. 2.运行: slmgr. ...