1.下面是30分的暴力代码,仅仅使用常规的未优化的Dijkstra算法做的。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAX=10010;
const int INF=1e8;
int n,m,k;
int f[MAX];
struct node
{
int v,w;
node(int _v,int _w)
{
v=_v;
w=_w;
}
};
vector<int> x[MAX];
vector<node> g[MAX];
int d[MAX];
int vis[MAX];
void dijk(int s)
{
fill(d,d+MAX,INF);
memset(vis,0,sizeof(vis));
d[s]=0;
for(int i=1;i<=n;i++)
{
int u=-1;
int MIN=INF;
for(int j=1;j<=n;j++)
{
if(vis[j]==0 && d[j]<MIN)
{
u=j;
MIN=d[j];
}
}
if(u==-1)
return ;
vis[u]=1;
for(int j=0;j<g[u].size();j++)
{
int v=g[u][j].v;
if(vis[v]==0 && d[u]+g[u][j].w<d[v])
{
d[v]=d[u]+g[u][j].w;
}
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
cin>>f[i];
}
while(m--)
{
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
for(int i=1;i<=n;i++)
{
dijk(i);
ll sum=INF;
for(int j=1;j<=n;j++)
{
if(f[j]==1 && d[j]!=INF)
x[i].push_back(d[j]);
}
sort(x[i].begin(),x[i].end());
ll tmp=0;
if(x[i].size()>=k)
{
for(int j=0;j<k;j++)
{
tmp+=x[i][j];
}
}
else
{
for(int j=0;j<x[i].size();j++)
{
tmp+=x[i][j];
}
}
sum=min(sum,tmp);
cout<<sum<<endl;
}
return 0;
}
2.下面是100分的优化代码,使用优化过的优先队列+Dijkstra算法做的,有一点需要注意,做题的时候需要把握数据范围的“魅力”,由上图可知,对于60%的数据,保证行星发动机的数量与k相同,这点很重要,我开始仅仅只优化过了“优先队列+Dijkstra算法”,后面对每一个点计算他与K个行星发动机的最短距离,交上去还是30分,于是我把后面的计算距离“由遍历所有节点到行星发动机的距离改为遍历行星发动机结点到每个结点的距离”,即for循环里的遍历由1e4
变为了1e2
,极大的减少了计算过程,不过我这样的想法本来是只想着通过60%的数据,没想到100分了。
以下是满分代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
const int INF=0x3f3f3f3f;
#define ll long long
int n,m,k;
struct Node
{
int v;
int w;
Node(int _v,int _w)
{
v=_v; w=_w;
}
friend bool operator < (const Node& a,const Node& b)
{
return a.w>b.w;
}
};
int type[N];
vector<Node> adj[N];
vector<int> dis[N];
ll d[N];
bool vis[N];
priority_queue<Node> q;
void dijkstra(int s)
{
fill(d,d+N,INF);
memset(vis,0,sizeof(vis));
d[s]=0;
q.push(Node(s,d[s]));
while(!q.empty())
{
Node x=q.top();
q.pop();
int u=x.v;
if(vis[u]==1) continue;
vis[u]=1;
for(int i=0;i<adj[u].size();i++)
{
int v=adj[u][i].v;
if(vis[v]==0 && d[u]+adj[u][i].w<d[v])
{
d[v]=d[u]+adj[u][i].w;
q.push(Node(v,d[v]));
}
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=n;i++) cin>>type[i];
for(int i=0;i<m;i++)
{
int u,v,w;
cin>>u>>v>>w;
adj[u].push_back(Node(v,w));
adj[v].push_back(Node(u,w));
}
for(int i=1;i<=n;i++)
{
if(type[i])
{
dijkstra(i);
for(int j=1;j<=n;j++)
{
if(d[j]!=INF) dis[j].push_back(d[j]);
}
}
}
for(int i=1;i<=n;i++)
{
sort(dis[i].begin(),dis[i].end());
ll res=INF,tmp=0;
if(dis[i].size()<=k)
{
tmp=accumulate(dis[i].begin(),dis[i].end(),0);
}
else tmp=accumulate(dis[i].begin(),dis[i].begin()+k,0);
cout<<min(res,tmp)<<endl;
}
return 0;
}