机房测试3:ZGY的早餐(Floyd+倍增)

Posted mowanying

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机房测试3:ZGY的早餐(Floyd+倍增)相关的知识,希望对你有一定的参考价值。

题目:

技术图片

 

技术图片

 

 

 分析:

由数据范围可知:前五个点是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
",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
",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
*/
View Code

 

以上是关于机房测试3:ZGY的早餐(Floyd+倍增)的主要内容,如果未能解决你的问题,请参考以下文章

模板倍增+Floyd

bzoj4773: 负环

bzoj4773: 负环(倍增floyd)

[边数限制最短路 倍增floyd 矩阵优化]Cow Relays G

bzoj 2165: 大楼Floyd+矩阵乘法+倍增+贪心

Luogu1613 跑路-倍增+Floyd