ccf 201903-5
Posted shiliuxinya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于ccf 201903-5的主要内容,如果未能解决你的问题,请参考以下文章