• ccf 201903-5


    题解:vector + 优先队列 -> 迪杰斯特拉算法

    不必求任何两点的距离,只求行星据点到其余每个点的距离即可

    把count个行星据点到其余每个点的距离存入二维数组

    每一列就是对应顶点i到每个行星据点的最短距离,取出放入一维数组sort,然后取前k个即可,如果遇到INF则跳过不取

    //迪杰斯特拉算法 (Vector + 优先队列)
    #include <stdio.h>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #include <string.h>
    #include <iostream>
    
    #define MAX 10001
    #define MAX_EDG 500001
    
    using namespace std;
    
    typedef pair<int, int> P;        //fisrt:dis[]  second:下标 
    vector<P> map[MAX_EDG];      //用vector优化
    priority_queue<P, vector<P>, greater<P> > q;
    const int INF = 0x3f3f3f3f;
    
    int d[MAX];
    int vis[MAX];
    
    int dis[MAX];
    int flag[MAX];            //标志是否为行星据点 
    int all[MAX][MAX];        //行星据点到其余顶点的最短距离 
    
    void Dijkstra(int s, int count, int n){
        memset(dis,INF,sizeof(dis));     
        memset(vis,0,sizeof(vis));
        dis[s]=0;
        q.push(P(0,s));        //将起始点push入队列 
        while(!q.empty()){
            P p =q.top();
            q.pop();
            int u=p.second;
            if(vis[u])    continue;
            vis[u]=1;
            for(int i=0;i<map[u].size();i++){        //i并不是边的终点,只是顺序存储的东西 
                int v=map[u][i].second;                //边的终点v     
                int w=map[u][i].first;                //u到v的距离 
                if(!vis[v]){
                    if(dis[v]>dis[u]+w){
                        dis[v]=dis[u]+w;
                        q.push(P(dis[v],v));
                    }    
                }
            }
        }
        for(int i=1;i<=n;i++)    all[count][i]=dis[i];
    }
    
    
    int main(){
        int n,m,k;    
        int u,v,w; 
        int c,r,count;                                        //求S到其他点的最短路径上的权值和        
        while(scanf("%d %d %d",&n,&m,&k)!=EOF){        //N顶点数 M边数 S开始点 
            for(int i=1;i<=n;i++)
                map[i].clear();        //清空vector  注意 vector 不能用二维数组初始化    
            memset(flag,0,sizeof(flag));
            count=0;
            for(int i=1;i<=n;i++){
                cin >> flag[i];
                if(flag[i])        count++;
            }
            for(int i=1;i<=m;i++){
                scanf("%d %d %d",&u,&v,&w);
                  map[u].push_back({w,v});        //无向图 
                map[v].push_back({w,u});        //有向图只push一次 
            }
            c=0;
               for(int i=1;i<=n;i++){
                if(flag[i]){                //求行星据点到每个顶点的距离,不必求任意两点之间的距离 
                    Dijkstra(i, c, n);
                    c++;
                }
            }
            for(int i=1;i<=n;i++){            //求n个顶点 
                memset(d,0,sizeof(d));        
                for(int j=0;j<count;j++)        //count个行星据点,count行 
                    d[j] = all[j][i];        //顶点i到行星据点的距离等于对应的列的值 
                sort(d,d+count);
                r=0;
                for(int p=0;p<k; p++)
                    if(d[p]!=INF)    r+=d[p];
                printf("%d
    ",r);
            }
        }
        return 0;
    }
  • 相关阅读:
    EF6 在原有数据库中使用 CodeFirst 总复习(三、重建迁移)
    EF6 在原有数据库中使用 CodeFirst 总复习(四、新建实体对象)
    EF6 在原有数据库中使用 CodeFirst 总复习(五、生成发帖页面)
    实体框架 (EF) 入门 => 一、我该用哪个工作流?
    实体框架 (EF) 入门 => 二、在全新的数据库中使用 Code First
    asp.net core 2.0 webapi集成signalr
    实体框架 (EF) 入门 => 三、CodeFirst 支持的完整特性列表
    ORM框架之------Dapper,Net下无敌的ORM
    Dapper Helper
    .NET平台微服务项目汇集
  • 原文地址:https://www.cnblogs.com/shiliuxinya/p/12179667.html
Copyright © 2020-2023  润新知