BZOJ2725 : [Violet 6]故乡的梦
如果S==T,那么答案为0。
如果S与T不连通,那么答案为inf。
否则,S到T的最短路径上至少有一条边。
求出以S为源点的最短路图,是个DAG,随便抓一条S到T的最短路,记为P。
设dpS[x]表示在这个图上,能到达x点的离S最近的在P上的点,可以通过拓扑排序+DP求出。
然后求出以T为源点的最短路图,在T的最短路图里找到P。
设dpT[x]表示在这个图上,能到达x点的离T最近的在P上的点,同样可以通过拓扑排序+DP求出。
然后把P路径上的边按S到T的方向,从1开始标号。
对于一条边,如果不在P上,那么答案显然为S到T的最短路。
否则,对于一条不在P上的边长为w的有向边x->y,P中dpS[x]到dpT[y]-1之间的边删掉后,均可以用disS[x]+disT[y]+w代替。
用线段树维护即可,时间复杂度$O((n+m)\log n+q)$。
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<ll,int> P;
const int N=200010;
const ll inf=1LL<<60;
int n,m,que,S,T,i,x,y,g[N],v[N<<1],w[N<<1],nxt[N<<1],ed;
int G[N],V[N],NXT[N],pre[N],d[N];
int path[N],cnt,id[N],fs[N],ft[N];
int q[N],h,t;
ll ds[N],dt[N];
struct E{int x,y,z;}e[N];
priority_queue<P,vector<P>,greater<P> >Q;
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
inline void ADD(int x,int y){pre[y]=x;d[y]++;V[++ed]=y;NXT[ed]=G[x];G[x]=ed;}
inline int onpath(int x,int y){
if(!id[x]||!id[y])return 0;
if(id[x]+1==id[y])return id[x];
if(id[y]+1==id[x])return id[y];
return 0;
}
ll val[525000],ans[N];
void build(int x,int a,int b){
val[x]=inf;
if(a==b)return;
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
}
void change(int x,int a,int b,int c,int d,ll p){
if(c<=a&&b<=d){val[x]=min(val[x],p);return;}
int mid=(a+b)>>1;
if(c<=mid)change(x<<1,a,mid,c,d,p);
if(d>mid)change(x<<1|1,mid+1,b,c,d,p);
}
void dfs(int x,int a,int b){
if(a==b){ans[a]=val[x];return;}
int mid=(a+b)>>1;
val[x<<1]=min(val[x<<1],val[x]),dfs(x<<1,a,mid);
val[x<<1|1]=min(val[x<<1|1],val[x]),dfs(x<<1|1,mid+1,b);
}
int main(){
read(n),read(m);
for(i=1;i<=m;i++){
read(e[i].x),read(e[i].y),read(e[i].z);
add(e[i].x,e[i].y,e[i].z);
add(e[i].y,e[i].x,e[i].z);
}
read(S),read(T);
if(S==T){
for(read(que);que--;puts("0"));
return 0;
}
for(i=1;i<=n;i++)ds[i]=inf;Q.push(P(ds[S]=0,S));
while(!Q.empty()){
P t=Q.top();Q.pop();
if(ds[t.second]<t.first)continue;
for(i=g[x=t.second];i;i=nxt[i])if(ds[x]+w[i]<ds[v[i]])Q.push(P(ds[v[i]]=ds[x]+w[i],v[i]));
}
if(ds[T]==inf){
for(read(que);que--;puts("Infinity"));
return 0;
}
for(ed=0,i=1;i<=m;i++){
if(ds[e[i].x]+e[i].z==ds[e[i].y])ADD(e[i].x,e[i].y);
if(ds[e[i].y]+e[i].z==ds[e[i].x])ADD(e[i].y,e[i].x);
}
for(i=T;i!=S;i=pre[i])path[++cnt]=i;path[++cnt]=S;
for(i=1;i<cnt-i+1;i++)swap(path[i],path[cnt-i+1]);
for(i=1;i<=cnt;i++)id[path[i]]=i;
for(i=1;i<=n;i++)fs[i]=N;
for(i=1;i<=cnt;i++)fs[path[i]]=i;
q[h=t=1]=S;
while(h<=t)for(i=G[x=q[h++]];i;i=NXT[i]){
if(!id[V[i]])fs[V[i]]=min(fs[V[i]],fs[x]);
if(!(--d[V[i]]))q[++t]=V[i];
}
for(i=1;i<=n;i++)dt[i]=inf;Q.push(P(dt[T]=0,T));
while(!Q.empty()){
P t=Q.top();Q.pop();
if(dt[t.second]<t.first)continue;
for(i=g[x=t.second];i;i=nxt[i])if(dt[x]+w[i]<dt[v[i]])Q.push(P(dt[v[i]]=dt[x]+w[i],v[i]));
}
for(ed=0,i=1;i<=n;i++)G[i]=d[i]=0;
for(i=1;i<=m;i++){
if(dt[e[i].x]+e[i].z==dt[e[i].y])ADD(e[i].x,e[i].y);
if(dt[e[i].y]+e[i].z==dt[e[i].x])ADD(e[i].y,e[i].x);
}
for(i=1;i<=cnt;i++)ft[path[i]]=i;
q[h=t=1]=T;
while(h<=t)for(i=G[x=q[h++]];i;i=NXT[i]){
if(!id[V[i]])ft[V[i]]=max(ft[V[i]],ft[x]);
if(!(--d[V[i]]))q[++t]=V[i];
}
build(1,1,cnt-1);
for(i=1;i<=m;i++){
x=e[i].x,y=e[i].y;
if(onpath(x,y))continue;
if(fs[x]<N&&ft[y]&&fs[x]<ft[y])change(1,1,cnt-1,fs[x],ft[y]-1,ds[x]+dt[y]+e[i].z);
if(fs[y]<N&&ft[x]&&fs[y]<ft[x])change(1,1,cnt-1,fs[y],ft[x]-1,ds[y]+dt[x]+e[i].z);
}
dfs(1,1,cnt-1);
read(que);
while(que--){
read(x),read(y),i=onpath(x,y);
if(!i){printf("%lld\n",ds[T]);continue;}
if(ans[i]<inf)printf("%lld\n",ans[i]);else puts("Infinity");
}
return 0;
}
BZOJ2725 : [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}{输入 ...
- BZOJ 2725: [Violet 6]故乡的梦
求出最短路径树,对于一个询问(x,y) 若不在树上S->T的链上,则答案不变,若在链上,考虑用一条非树边替换这条边,这条非树边必须跨越x->y这条边,线段树维护区间最小值 #include ...
- 【BZOJ-2725】故乡的梦 Dijsktra + Tarjan + Dinic + BFS + 堆
2725: [Violet 6]故乡的梦 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 502 Solved: 173[Submit][Status ...
- [violet6] 故乡的梦
题目 描述 不知每日疲于在城市的水泥森林里奔波的你会不会有时也曾向往过乡村的生活.你会不会幻想过,在夏日一个静谧的午后,你沉睡于乡间路边的树荫里,一片叶子落在了你的肩上, 而你正做着一个悠长的梦,一个 ...
- bzoj violet系列 (2708~2725)
cbh大爷说:写博客不能弃坑. orz cbh 那我就来更新博客了. violet这个系列的题好神啊……出题人好劲啊…… ……怎么最近都在理性愉悦啊…… 另外bzoj400题纪念~ 2708: [Vi ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
5395: [Ynoi2016]谁的梦 Time Limit: 80 Sec Memory Limit: 128 MBSubmit: 22 Solved: 7[Submit][Status][Di ...
随机推荐
- 关于seajs
(这些文章都是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 最近经常听到各种JS前缀的名称,瞬间感觉自己弱爆了,啥都没用过呢,这么下去将来怎么嫁人呢. ...
- 8个开发必备的PHP功能
做过PHP开发的程序员应该清楚,PHP中有很多内置的功能,掌握了它们,可以帮助你在做PHP开发时更加得心应手,本文将分享8个开发必备的PHP功能,个个都非常实用,希望各位PHP开发者能够掌握. 1.传 ...
- PHP 逻辑思维题
约瑟夫环 一群猴子排成一圈,按1,2,...,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去...,如此不停的进行下去,直到最后只剩下一只猴子为止 ...
- 【Hibernate】Hibernate系列3之配置文件详解
配置文件详解 3.1.配置文件 连接池性能优化:http://www.cnblogs.com/xdp-gacl/p/4002804.html
- TCP的几个状态 (SYN, FIN, ACK, PSH, RST, URG)
在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG. 其中,对于我们日常的分析有用的就是前面的五个字段. 它们的含义是: SYN表示建立连 ...
- canva实践小实例 —— 马赛克效果
前面给大家带来了操作像素的API,此时此刻,我觉得应该配以小实例来进行进一步的说明和演示,以便给大家带来更宽广的视野和灵感,你们看了我的那么多的文章,应该是懂我的风格,废话不多说,进入正题: 这次给大 ...
- [Android Pro] UI设计师不可不知的安卓屏幕知识
reference to : http://www.android100.org/html/201505/24/149342.html 不少设计师和工程师都被安卓设备纷繁的屏幕搞得晕头转向,我既做UI ...
- 使用apktool工具遇到could not decode arsc file的解决办法
问题详情: 当前环境为 win7 64位 jdk1.7 apktool.jar(版本1.5.2) apktool(版本windows-r05-ibot) 使用的反编译工具和apk文件为 反编译 ...
- Windows下安装Cygwin及包管理器apt-cyg(转)
本文为转载文章: http://www.2cto.com/os/201212/176551.html Cygwin可以在Windows下使用unix环境Bash和各种功能强大的工具,对于Linux管理 ...
- Session的使用(登录例案+其它页面访问)
本程序功能是使用Session将用户输入的用户名保存在Session中(登录成功情况下,登录失败不会有Session值),其它页面想访问时会先判断是否有之前存的Session值. 登录Login.ht ...