zoukankan      html  css  js  c++  java
  • ※P1119 灾后重建

    \(TLE\)代码

    const int N=210;
    vector<PII> g[N];
    int tim[N];
    int dist[N];
    bool vis[N];
    int n,m,q;
    
    int dijkstra(int st,int ed,int limit)
    {
        if(tim[st]>limit || tim[ed]>limit) return -1;
    
        memset(dist,0x3f,sizeof dist);
        memset(vis,0,sizeof vis);
        priority_queue<PII,vector<PII>,greater<PII> > heap;
        dist[st]=0;
        heap.push({0,st});
    
        while(heap.size())
        {
            int t=heap.top().second;
            heap.pop();
    
            if(vis[t]) continue;
            vis[t]=true;
    
            for(int i=0;i<g[t].size();i++)
            {
                int j=g[t][i].fi,w=g[t][i].se;
                if(tim[j] <= limit && dist[j] > dist[t]+w)
                {
                    dist[j]=dist[t]+w;
                    heap.push({dist[j],j});
                }
            }
        }
    
        if(dist[ed] == INF) return -1;
        return dist[ed];
    }
    
    int main()
    {
        cin>>n>>m;
    
        for(int i=0;i<n;i++) cin>>tim[i];
    
        while(m--)
        {
            int a,b,c;
            cin>>a>>b>>c;
            g[a].push_back({b,c});
            g[b].push_back({a,c});
        }
    
        cin>>q;
        while(q--)
        {
            int x,y,t;
            cin>>x>>y>>t;
            cout<<dijkstra(x,y,t)<<endl;
        }
        //system("pause");
    }
    

    注意输入条件

    • \(第二行包含N个非负整数t_0, t_1,…, t_{N-1},表示了每个村庄重建完成的时间,数据保证了t_0 ≤ t_1 ≤ … ≤ t_{N-1}\)

    即每个村庄的重建完成时间按村庄编号递增

    观察到数据范围

    • \(N≤200\),不免联想到\(O(n^3)\)的最短路floyd算法

    floyd算法本质:动态规划,d[k,i,j]表示从i号顶点到j号顶点只经过前k号点的最短距离

    我们再回头看题意:

    所有的边全部给出,按照时间顺序更新每一个可用的点(即修建好村庄),对于每个时间点进行两点之间询问,求对于目前建设的所有村庄来说任意两点之间的最短路。

    不正好就是Floyd算法中使用前k个节点更新最短路的思维吗?

    出题人还是很良心的,保证所有的数据都是用时间顺序给出的,所以我们只用读取+操作就可以了,不用再存储+排序。

    时间复杂度:\(O(q+n^3)\)

    const int N=210;
    int g[N][N];
    int tim[N];
    int n,m,q;
    
    void floyd(int k)
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
    }
    
    int main()
    {
        cin>>n>>m;
    
        for(int i=0;i<n;i++) cin>>tim[i];
    
        memset(g,0x3f,sizeof g);
        for(int i=0;i<n;i++) g[i][i]=0;
    
        while(m--)
        {
            int a,b,c;
            cin>>a>>b>>c;
            g[a][b]=g[b][a]=min(g[a][b],c);
        }
    
        cin>>q;
        int k=0;
        while(q--)
        {
            int x,y,t;
            cin>>x>>y>>t;
    
            while(k<n && tim[k] <= t)
            {
                floyd(k);
                k++;
            }
    
            if(g[x][y] == INF || tim[x] > t || tim[y] > t) puts("-1");
            else cout<<g[x][y]<<endl;
        }
    
        //system("pause");
    }
    
  • 相关阅读:
    php的下载与安装
    apache 的下载与配置
    Composer 安装与使用
    WampServer 的安装
    SQLServer主键约束和唯一约束的区别
    Mac如何修改Host
    解决XCode11中 [Application] The app delegate must implement the window property if it wants to use a main storyboard file.的问题
    Xcode10.1 import头文件无法索引
    iOS
    如何让windows服务器IIS支持.apk/.ipa文件下载
  • 原文地址:https://www.cnblogs.com/fxh0707/p/13617860.html
Copyright © 2011-2022 走看看