zoukankan      html  css  js  c++  java
  • P1119 灾后重建(floyd进阶)

    思路:这道题看n的范围很小(n<=200),显然就用floyd可以解决的问题,但又并不是简单的floyd算法,还是需要一些小小的变化。一开始我的思路是先跑一次弗洛伊德最短路,这样子显然复杂度很高,并且题目中的路径长度是时刻可能更新的,所以我们应该在修建的时候再跑最短路。可以用一个变量来记录修改的点,这样子就可以大幅度的优化。

    代码如下

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    const int N=250;
    int n,m,x,y,v,T;
    int t[maxn];
    int f[N][N];
    int flag[N][N];
    int xx,yy,tt;
    int start;//动态变化的那个点
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&t[i]);
            f[i][i]=0;
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                f[i][j]=1e9;
            }
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&v);
            f[x][y]=f[y][x]=v;
        }
        scanf("%d",&T);
        for(int o=1;o<=T;o++)
        {
            start=0;//Tle原因
            scanf("%d%d%d",&xx,&yy,&tt);
            while(t[start]<=tt&&start<n)
            {
                for(int i=0;i<n;i++)
                {
                    for(int j=0;j<n;j++)
                    {
                        f[i][j]=min(f[i][start]+f[start][j],f[i][j]);
                    }
                }
                start++;
            }
            if(f[xx][yy]==1e9||t[xx]>tt||t[yy]>tt)
            {
                printf("-1
    ");
            }
            else
            {
                printf("%d
    ",f[xx][yy]);
            }
        }
        return 0;
    }

    等等,但这样似乎只有30分,吸氧50 ,T了7个点

    究其原因,是因为每次跑弗洛伊德的时候,start都是又从零开始枚举的,这样显然是没有必要的

    所以我们就将他简单改一下

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    const int N=250;
    int n,m,x,y,v,T;
    int t[maxn];
    int f[N][N];
    int flag[N][N];
    int xx,yy,tt;
    int start;
    int Read(){
        int X = 0 ; char ch = getchar() ;
        while(ch > '9' || ch < '0') ch = getchar() ;
        while(ch >= '0' && ch <= '9')
        X = (X << 1) + (X << 3) + (ch ^ 48), ch = getchar() ;
        return X ;
    }
    int main()
    {
        n=Read(),m=Read();
        for(int i=0;i<n;i++)
        {
            t[i]=Read();
            f[i][i]=0;
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                f[i][j]=1e9;
            }
        }
        for(int i=1;i<=m;i++)
        {
            x=Read();
            y=Read();
            v=Read();
            f[x][y]=f[y][x]=v;
        }
        T=Read();
        for(int o=1;o<=T;o++)
        {
            xx=Read(),yy=Read(),tt=Read();
            while(t[start]<=tt&&start<n)
            {
                for(int i=0;i<n;i++)
                {
                    for(int j=0;j<n;j++)
                    {
                        f[i][j]=min(f[i][start]+f[start][j],f[i][j]);
                    }
                }
                start++;
            }
            if(f[xx][yy]==1e9||t[xx]>tt||t[yy]>tt)
            {
                printf("-1
    ");
            }
            else
            {
                printf("%d
    ",f[xx][yy]);
            }
        }
        return 0;
    }

    因为修建的时候那个点都是一遍更新的,并且时间是单调递增的

    所以只需要更新一遍就得了,那个动态的点就不用再次清零了。

  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/LJB666/p/10665886.html
Copyright © 2011-2022 走看看