BZOJ 2725: [Violet 6]故乡的梦
求出最短路径树,对于一个询问(x,y) 若不在树上S->T的链上,则答案不变,若在链上,考虑用一条非树边替换这条边,这条非树边必须跨越x->y这条边,线段树维护区间最小值
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define pr pair<long long,int>
#define mp make_pair
#define sc second
using namespace std;
int cnt,n,m,last[200005],Lv[200005],stack[200005],Fa[200005],vis[200005],pre[200005],Vis[1000005];
long long dis[200005][2],Dep[200005],ANS[200005],tree[800005];
priority_queue<pr,vector<pr>,greater<pr> > q;
struct node{
int to,next;
long long val;
}e[400005];
struct node1{
int x,y,val;
}E[200005];
void add(int a,int b,int c){
e[++cnt].to=b;
e[cnt].next=last[a];
e[cnt].val=c;
last[a]=cnt;
}
void Dijkstra(int S,int cas){
for (int i=1; i<=n; i++) dis[i][cas]=1ll<<60,vis[i]=0;
dis[S][cas]=0;
q.push(mp(0ll,S));
while (!q.empty()){
int x=q.top().sc;
q.pop();
if (vis[x]) continue;
vis[x]=1;
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (dis[V][cas]>dis[x][cas]+e[i].val){
dis[V][cas]=dis[x][cas]+e[i].val;
if (cas==0) pre[V]=x;
q.push(mp(dis[V][cas],V));
}
}
}
}
void Pre(int x,int fa,long long dep){
Fa[x]=fa,Dep[x]=dep;
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (V==fa) continue;
Pre(V,x,dep+e[i].val);
}
}
void solve(int x,int lv){
vis[x]=1;
Lv[x]=lv;
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (vis[V]) continue;
solve(V,lv);
}
}
bool cmp(node a,node b){
return a.to<b.to;
}
void insert(int t,int l,int r,int x,long long key){
if (l==r){
tree[t]=min(tree[t],key);
return;
}
int mid=(l+r)>>1;
if (x<=mid) insert(t<<1,l,mid,x,key);
else insert(t<<1|1,mid+1,r,x,key);
tree[t]=min(tree[t<<1],tree[t<<1|1]);
}
long long query(int t,int l,int r,int x,int y){
if (r<x || l>y) return 1ll<<60;
if (l>=x && r<=y) return tree[t];
int mid=(l+r)>>1;
return min(query(t<<1,l,mid,x,y),query(t<<1|1,mid+1,r,x,y));
}
void build(int t,int l,int r){
if (l==r){
tree[t]=1ll<<60;
return;
}
int mid=(l+r)>>1;
build(t<<1,l,mid);
build(t<<1|1,mid+1,r);
tree[t]=max(tree[t<<1],tree[t<<1|1]);
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1; i<=m; i++){
scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].val);
add(E[i].x,E[i].y,E[i].val);
add(E[i].y,E[i].x,E[i].val);
}
int S,T;
scanf("%d%d",&S,&T);
Dijkstra(S,0);
Dijkstra(T,1);
cnt=0;
memset(vis,0,sizeof(vis));
for (int i=1; i<=n; i++) last[i]=0;
for (int i=1; i<=n; i++)
if (pre[i]) {
add(pre[i],i,dis[i][0]-dis[pre[i]][0]);
add(i,pre[i],dis[i][0]-dis[pre[i]][0]);
}
Lv[S]=1;
Pre(S,0,0);
int now=T,top=0;
while (now){
stack[++top]=now;
vis[now]=1;
Vis[now]=top;
now=Fa[now];
}
for (int i=1; i<=top/2; i++) swap(stack[i],stack[top-i+1]);
for (int i=1; i<=top; i++) solve(stack[i],i);
int cnt=0;
for (int i=1; i<=m; i++){
int x=E[i].x,y=E[i].y;
if (Vis[x] && Vis[y] && (Vis[y]==Vis[x]+1 || Vis[x]==Vis[y]+1)) continue;
int X=Lv[x],Y=Lv[y];
if (X>Y) swap(X,Y),swap(x,y);
e[++cnt]=(node){X,Y,dis[x][0]+dis[y][1]+E[i].val};
}
sort(e+1,e+cnt+1,cmp);
build(1,1,top);
int Top=1;
for (int i=1; i<top; i++){
while (Top<=cnt && e[Top].to<=i){
insert(1,1,top,e[Top].next,e[Top].val);
Top++;
}
ANS[i]=query(1,1,top,i+1,top);
}
int q;
scanf("%d",&q);
int cc=0;
while (q--){
cc++;
int x,y;
scanf("%d%d",&x,&y);
if (Vis[x] && Vis[y] && (Vis[x]==Vis[y]+1 || Vis[y]==Vis[x]+1)){
if (dis[T][0]==1ll<<60) printf("Infinity\n");
else{
int X=Lv[x],Y=Lv[y];
if (X>Y) swap(X,Y);
if (ANS[X]!=1ll<<60) printf("%lld\n",ANS[X]);
else printf("Infinity\n");
}
}
else {
if (dis[T][0]!=1ll<<60) printf("%lld\n",dis[T][0]);
else printf("Infinity\n");
}
}
return 0;
}
BZOJ 2725: [Violet 6]故乡的梦的更多相关文章
- BZOJ 2725: [Violet 6]故乡的梦 最短路+线段树
2725: [Violet 6]故乡的梦 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 678 Solved: 204[Submit][Status ...
- [原博客] BZOJ 2725 : [Violet 6]故乡的梦
这个题在bzoj上好像是个权限题,想做的可以去Vani的博客下载测试数据.这里有题面. 简单叙述一下题意:给你一个n个点.m条边的带权无向图,S点和T点,询问Q次删一条给定的边的S-T最短路. 其中 ...
- BZOJ 2725 [Violet 6]故乡的梦 线段树+最短路树
\(\color{#0066ff}{ 题目描述 }\) \(\color{#0066ff}{输入格式}\) \(\color{#0066ff}{输出格式}\) \(\color{#0066ff}{输入 ...
- BZOJ2725 : [Violet 6]故乡的梦
如果S==T,那么答案为0. 如果S与T不连通,那么答案为inf. 否则,S到T的最短路径上至少有一条边. 求出以S为源点的最短路图,是个DAG,随便抓一条S到T的最短路,记为P. 设dpS[x]表示 ...
- 【BZOJ-2725】故乡的梦 Dijsktra + Tarjan + Dinic + BFS + 堆
2725: [Violet 6]故乡的梦 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 502 Solved: 173[Submit][Status ...
- 二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园
BZOJ 2709: [Violet 1]迷宫花园 Sample Input 5 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ## ...
- [violet6] 故乡的梦
题目 描述 不知每日疲于在城市的水泥森林里奔波的你会不会有时也曾向往过乡村的生活.你会不会幻想过,在夏日一个静谧的午后,你沉睡于乡间路边的树荫里,一片叶子落在了你的肩上, 而你正做着一个悠长的梦,一个 ...
- BZOJ 2716: [Violet 3]天使玩偶
2716: [Violet 3]天使玩偶 Time Limit: 80 Sec Memory Limit: 128 MBSubmit: 1473 Solved: 621[Submit][Statu ...
- BZOJ 2724: [Violet 6]蒲公英
2724: [Violet 6]蒲公英 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1633 Solved: 563[Submit][Status ...
随机推荐
- 工作的时候 用到了 获取时间 DateTime 整理了一下
获得当前系统时间: DateTime dt = DateTime.Now; Environment.TickCount可以得到“系统启动到现在”的毫秒值 DateTime now = DateTime ...
- JTable运行的时候抛出NullPointerException的问题
在一个需要动态更新JTable的程序中,为了实现动态刷修数据.在主线程之外开了个新线程来进行算法的执行还有数值计算,然后最后调用 jTable.updateUi(); 的方法. 然后图形界面上是一点问 ...
- DDX和DDV——控件与变量之间值的传递
DoDataExchange由框架调用,作用是交互并且验证对话框数据,主要由(DDX) 和 (DDV)宏实现. 永远不要直接调用这个函数,而是通过UpdateData(TRUE/FALSE)实现控件与 ...
- HTML 5的革新——更简洁的结构
今天我们阐述HTML 5的革新之一:更简洁的结构. 新的文档类型 DOCTYPE 先来解释一下文档类型 DOCTYPE:文档类型位于HTML源文件的第一行,在HTML4的标准中,DOCTYPE在被归在 ...
- javaScript中的严格模式 (译)
“use strict”状态指示浏览器使用严格模式,是javaScript中一个相对少且安全的特征集. 特征列表(非完全列举) 不允许定义全局变量.(捕获没有用var声明的变量和变量名的拼写错误) 在 ...
- 前端生成全球唯一码GUID
function GUID() { this.date = new Date(); //先new一个时间备用 GUID.prototype.newGUID = function () { this. ...
- Java编程基础-异常
一.异常 1.什么是异常 在java中,程序在运行时出现的不正常情况称为异常,以异常类的形式对这些非正常情况进行封装,通过异常处理机制对程序运行时发生的各种问题进行处理.其实就是java对不正常情况进 ...
- CF1081E Missing Numbers
思路: 贪心乱搞. 实现: #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll m = ...
- iOS上线check_list
iOS 上线前 check_list 类型 序号 检查项 结果(pass/no) 安装 卸载 1 非越狱环境下的安装.卸载 2 越狱环境下的安装.卸载 3 安装文件检查,无泄漏用户信息的隐患 4 卸载 ...
- codevs 1155 金明的预算方案
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房 ...