日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ2125 最短路

發布時間:2024/9/5 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ2125 最短路 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

每個點有兩個值,一個是從根到這個點的最短路d[i],一個是從根沿dfs樹到這個點的距離rd[i].

之后是一個很牛逼的建圖,把環上的點都連到環中深度最淺的點得到一顆樹,并維護每個點所在的環以及每個環的環長。

對于一個詢問(x,y),假設dep[x]>dep[y],分情況:

1.如果x和y的lca是y,那么答案為d[x]-d[y].

2.如果x和y的lca沒在環里,那么答案為d[x]+d[y]-2*d[lca].

3.如果x和y的lca在環里,設x,y向上走遇到的第一個環上節點分別是a,b,那么答案為d[x]-d[a]+d[y]-d[b]+min(abs(rd[a]-rd[b]),環長-abs(rd[a]-rd[b])).

#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std;const int N=10005,M=100005; int n,m,q,e=1,x,y,z,ti,cn,hd[N],nx[M],to[M],w[M],dl[M],dfn[N],st[N],d[N],v[N],rd[N],dp[N],bl[N],ln[N],f[N][14]; void ad(int x,int y,int z) {to[++e]=y,w[e]=z,nx[e]=hd[x],hd[x]=e;}void spfa() {memset(d,0x3f,sizeof d);queue<int> q; q.push(1),d[1]=0;while(!q.empty()) {int u=q.front(); q.pop();v[u]=0;for(int i=hd[u];i;i=nx[i]) if(d[to[i]]>d[u]+w[i]) {d[to[i]]=d[u]+w[i];if(!v[to[i]]) v[to[i]]=1,q.push(to[i]);}} } void gt(int x,int y) {if(x==y) return;bl[x]=cn,ad(y,x,0),dl[st[x]]=dl[st[x]^1]=1,ln[cn]+=w[st[x]],gt(to[st[x]^1],y); } void dfs(int x) {dfn[x]=++ti;for(int i=hd[x];i;i=nx[i]) if(i!=(st[x]^1)&&i<=m*2+1) {if(!dfn[to[i]]) rd[to[i]]=rd[x]+w[i],st[to[i]]=i,dfs(to[i]);else if(dfn[to[i]]<dfn[x]) ln[++cn]=w[i],gt(x,to[i]);} } void dfs2(int x) {for(int i=hd[x];i;i=nx[i]) if(!dl[i]&&!dp[to[i]]) f[to[i]][0]=x,dp[to[i]]=dp[x]+1,dfs2(to[i]); }int qry(int x,int y) {if(dp[x]<dp[y]) swap(x,y);int a=x,b=y;for(int i=13;~i;i--) if(dp[f[x][i]]>=dp[y]) x=f[x][i];if(x==y) return d[a]-d[b];for(int i=13;~i;i--) if(f[x][i]^f[y][i]) x=f[x][i],y=f[y][i];if(bl[x]&&bl[x]==bl[y]) {int r=abs(rd[x]-rd[y]);return d[a]-d[x]+d[b]-d[y]+min(r,ln[bl[x]]-r);}return d[a]+d[b]-2*d[f[x][0]]; }int main() {scanf("%d%d%d",&n,&m,&q);for(int i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&z),ad(x,y,z),ad(y,x,z);spfa(),dfs(1),dp[1]=1,dfs2(1);for(int j=1;j<14;j++)for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];while(q--) scanf("%d%d",&x,&y),printf("%d\n",qry(x,y));return 0; }

轉載于:https://www.cnblogs.com/juruolty/p/6438695.html

總結

以上是生活随笔為你收集整理的BZOJ2125 最短路的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。