zoukankan      html  css  js  c++  java
  • AcWing345 牛站(floyd+倍增)

    设计状态为走了k步,从i-j的最短路,由于加法满足结合律,因此可以用倍增来优化逼近n

    这样可以log复杂度逼近,代码与floyd相似,但是状态的定义完全不同,本题还需要离散化一下,因为原数太大

    #include<bits/stdc++.h>
    using namespace std;
    const int N=210;
    int g[N][N];
    int res[N][N];
    int n,t,s,e;
    int cnt;
    void mul(int c[][N],int a[][N],int b[][N]){
        int tmp[N][N];
        memset(tmp,0x3f,sizeof tmp);
        int i,j,k;
        for(k=1;k<=cnt;k++){
            for(i=1;i<=cnt;i++){
                for(j=1;j<=cnt;j++){
                    tmp[i][j]=min(tmp[i][j],a[i][k]+b[k][j]);
                }
            }
        }
        memcpy(c,tmp,sizeof tmp);
    }
    void qmi(){
        memset(res,0x3f,sizeof res);
        for(int i=1;i<N;i++)
        res[i][i]=0;
        while(n){
            if(n&1){
                mul(res,res,g);
            }
            mul(g,g,g);
            n>>=1;
        }
    }
    int main(){
        memset(g,0x3f,sizeof g);
        cin>>n>>t>>s>>e;
        int i;
        map<int,int> id;
         cnt=1;
        if(!id.count(s))
            id[s]=cnt++;
        if(!id.count(e))
        id[e]=cnt++;
        s=id[s];
        e=id[e];
        for(i=1;i<=t;i++){
            int a,b,c;
            scanf("%d%d%d",&c,&a,&b);
            if(!id.count(a)) id[a]=cnt++;
            if(!id.count(b)) id[b]=cnt++;
            a=id[a],b=id[b];
            g[a][b]=g[b][a]=min(g[a][b],c);
        }
        cnt--;
        qmi();
        printf("%d
    ",res[s][e]);
    }
    View Code
  • 相关阅读:
    致亲爱的304
    C语言中简单的for循环和浮点型变量
    C程序内存管理
    变量
    我哭了
    那一场邂逅
    如何修改安卓项目的图标
    Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead.解决方法
    Android 异步加载
    大家好,第一次用博客记录一些东西
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12833009.html
Copyright © 2011-2022 走看看