【样例 1 输入】
7 6 2
1 0 1 0 1 1 0
1 4 1
1 2 3
2 4 4
2 3 5
2 5 7
6 7 5
【样例 1 输出】
8
8
10
10
0
5
思路:
用dijkstra算法求n次单源最短路,时间复杂度O(n^3)
用优先队列优化,O(n*mlogm)
n指的是什么呢?
如果是据点数量,那只能拿30分。
注意:“行星发动机的数量和k相等”,说明可以从行星发动机的数量入手拿到60分。
题目要求的是任一据点到最近k个行星发动机据点的最短路之和,于是我们可以求k个行星发动机据点的最短路,
复杂度:O(k*mlogm)
#include <bits/stdc++.h>
using namespace std;
struct E
{
int v,w;
bool operator < (const E&b)const
{
return w>b.w;
}
};
int n,m,k;
int ff[10000+10];
priority_queue<int,vector<int>,greater<int> > d[10000];
vector<E> edge[10000];
void dijkstra(int k)
{
priority_queue<E> Q;
int dis[10000];
for(int i=0;i<n;i++)
dis[i]=0x3f3f3f3f;
dis[k]=0;
Q.push((E){k,0});
while(!Q.empty())
{
E t=Q.top();
Q.pop();
if (t.w!=dis[t.v]) continue;
d[t.v].push(t.w);
int m=edge[t.v].size();
int u,w;
for (int i=0;i<m;i++)
{
u=edge[t.v][i].v;
w=edge[t.v][i].w;
if (dis[u]>dis[t.v]+w)
dis[u]=dis[t.v]+w,
Q.push((E){u,dis[u]});
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int num=0,x;
for(int i=0;i<n;i++)
{
scanf("%d",&x);
if(x)ff[num++]=i;
}
int u,v,w;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
u--;v--;
edge[u].push_back((E){v,w});
edge[v].push_back((E){u,w});
}
for(int i=0;i<num;i++)
dijkstra(ff[i]);
long long ans;
for(int i=0;i<n;i++)
{
int cnt=k;
ans=0;
while(!d[i].empty()&&cnt--)
{
ans+=d[i].top();
d[i].pop();
}
printf("%lld\n",ans);
}
return 0;
}