题目:
分析:
由数据范围可知:前五个点是Floyd,后五个点是一颗树,两两点之间的路径是唯一的,只需要求lca即可。
Floyd注意实现细节:
1.初始化时要把dis[i][i]赋成0
2.只有1个dis数组
倍增注意:
统计答案的时候要先统计在跳fa!!
#include<bits/stdc++.h> using namespace std; #define ll long long #define N 1005 #define nn 100005 #define M 250005 #define ri register int const ll inf=1ll<<60; int f[nn][22],nex[M<<1],head[nn],to[M<<1],tot=0,dep[nn],n,m; ll sum[nn][22],ww[M<<1]; int read() { int x=0,fl=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) fl=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*fl; } ll dis[N][N]; void work1() { ll a,b,c; for(ri i=1;i<=n;++i){ for(ri j=1;j<=n;++j) if(i!=j) dis[i][j]=inf; } for(ri i=1;i<=m;++i) a=read(),b=read(),c=read(),dis[a][b]=min(dis[a][b],c),dis[b][a]=min(dis[b][a],c); for(ri k=1;k<=n;++k) for(ri i=1;i<=n;++i) for(ri j=1;j<=n;++j) if(dis[i][k]+dis[k][j]<dis[i][j]) dis[i][j]=dis[i][k]+dis[k][j],dis[j][i]=dis[i][j]; int Q=read(); while(Q--){ int s=read(), h=read(), t=read(); printf("%lld\n",dis[s][h]+dis[h][t]); } } void add(int a,int b,int c) { to[++tot]=b; nex[tot]=head[a]; head[a]=tot; ww[tot]=c; to[++tot]=a; nex[tot]=head[b]; head[b]=tot; ww[tot]=c; } void dfs(int u,int fa) { for(ri i=head[u];i;i=nex[i]){ int v=to[i]; if(v==fa) continue; dep[v]=dep[u]+1; f[v][0]=u; sum[v][0]=ww[i]; for(ri j=1;j<=20;++j) f[v][j]=f[f[v][j-1]][j-1]; for(ri j=1;j<=20;++j) sum[v][j]=sum[f[v][j-1]][j-1]+sum[v][j-1]; dfs(v,u); } } ll query(int a,int b) { ll summ=0; if(dep[a]<dep[b]) swap(a,b); for(ri i=20;i>=0;--i) if(dep[f[a][i]]>=dep[b]) summ+=sum[a][i],a=f[a][i];//!!! if(a==b) return summ;// for(ri i=20;i>=0;--i) if(f[a][i]!=f[b][i]) summ+=sum[a][i]+sum[b][i], a=f[a][i], b=f[b][i]; return summ+sum[a][0]+sum[b][0]; } void work2() { int a,b,c; for(ri i=1;i<=m;++i) a=read(),b=read(),c=read(),add(a,b,c); dfs(1,0); int Q=read(); while(Q--){ int s=read(), h=read(), t=read(); printf("%lld\n",query(s,h)+query(h,t));// }/**/ } int main() { freopen("mindis.in","r",stdin); freopen("mindis.out","w",stdout); int T=read(); n=read(), m=read() ; if(T<=6) work1(); else work2(); } /* 0 5 5 1 2 1 2 3 1 3 4 2 4 5 1 2 5 1 2 1 4 5 5 4 5 0 5 6 1 2 3 2 3 4 2 4 2 1 3 2 3 5 4 4 5 5 2 1 3 5 1 2 5 7 6 5 1 2 100000000 1 3 500000000 2 5 400000000 2 4 300000000 4 6 200000000 3 4 5 3 6 2 1 6 1 3 */
原文地址:https://www.cnblogs.com/mowanying/p/11623357.html
时间: 2024-10-07 00:06:01