测试用例
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
千辛万苦获得100分
总结一下获得满分的几个条件(猜测):
- 求取最短路径时只求行星发动机据点到所有点的最短距离;使用一个二维数组存储,distance(行星发动机据点->普通点)=distance(普通点->行星发动机据点)
- 使用邻接链表存图
- 使用迪杰斯特拉算法,并且使用堆优化
- 求前k个的算法需要优化(我猜大部分60分的是没有优化这里):具体思路是使用一个大根堆,这个堆的最大大小是k个。在堆的size比k小的时候,向堆中push元素;在堆size>=k的时候,比较堆顶和distance(到当前行星据点),如果堆顶大于到当前行星据点的距离,就将堆顶pop出,push新的distance(到当前行星据点)。这样寻找前k个的复杂度是nklogk。
具体代码:
for(int i = 0; i < n;i++){
int count = 0;
priority_queue<int,vector<int>,less<int> > myqueue;
for(int w = 0; w < important.size();w++){
int j = important[w];
int weight = mindis[i*n+j];
if(count >= k){
if(weight < myqueue.top()){
myqueue.pop();
myqueue.push(weight);
}
}else{
if(weight != INF){
myqueue.push(weight);
count++;
}
}
}
int size = myqueue.size();
int sum = 0;
for(int p = 0; p <size && p < k; p++){
sum += myqueue.top();
myqueue.pop();
}
//cout << sum<<endl;
printf("%d\n",sum);
}
全部代码附上:
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 0x7fffffff
using namespace std;
struct node{
int id;
int dis;
};
struct cmp{
bool operator()(const node& a,const node& b){
return a.dis > b.dis;
}
};
int main()
{
int n,m,k;
while(scanf("%d %d %d",&n,&m,&k)!= EOF){
vector<int> important;
for(int i = 0; i < n; i++){
int temp;
//cin>> temp;
scanf("%d",&temp);
if(temp == 1){
important.push_back(i);
}
}
//int* eage = new int[n*n];
vector<vector<node> > eage(n);
//init
for(int i = 0; i < n; i++){
node temp;
temp.id = i;
temp.dis = 0;
eage[i].push_back(temp);
}
for(int j = 0; j < m; j++){
int left;
int right;
int weight;
//cin>>left>>right>>weight;
scanf("%d %d %d",&left,&right,&weight);
node temp;
temp.id = right-1;
temp.dis = weight;
eage[left-1].push_back(temp);
temp.id = left-1;
eage[right-1].push_back(temp);
}
int* mindis = new int[n*n];
//cal
for(int w = 0; w< important.size(); w++){
int i = important[w];
//vector<int> currdis;
priority_queue<node,vector<node>,cmp> heap;
vector<bool> visit;
for(int j = 0; j < n; j++){
visit.push_back(false);
}
for(int j = 0; j < eage[i].size(); j++){
heap.push(eage[i][j]);
}
while(!heap.empty()){
//min one
node minnode = heap.top();
heap.pop();
int postion = minnode.id;
int min = minnode.dis;
if(visit[postion]){
continue;
}
//printf("from: %d;min: %d;position: %d\n",i,min,postion);
//visit
visit[postion] = true;
mindis[i*n+postion] = min;
mindis[postion*n+i] = mindis[i*n+postion];
//update
for(int j = 0; j < eage[postion].size(); j++){
if(!visit[eage[postion][j].id]){
node tempnode;
tempnode.id = eage[postion][j].id;
tempnode.dis = min+eage[postion][j].dis;
heap.push(tempnode);
}
}
}
for(int j = 0; j < n; j++){
if(!visit[j]){
mindis[i*n+j] = INF;
mindis[j*n+i] = mindis[i*n+j];
}
}
}
//求前k个距离最短的行星发动机据点
for(int i = 0; i < n;i++){
int count = 0;
priority_queue<int,vector<int>,less<int> > myqueue;
for(int w = 0; w < important.size();w++){
int j = important[w];
int weight = mindis[i*n+j];
if(count >= k){
if(weight < myqueue.top()){
myqueue.pop();
myqueue.push(weight);
}
}else{
if(weight != INF){
myqueue.push(weight);
count++;
}
}
}
int size = myqueue.size();
int sum = 0;
for(int p = 0; p <size && p < k; p++){
sum += myqueue.top();
myqueue.pop();
}
//cout << sum<<endl;
printf("%d\n",sum);
}
delete [] mindis;
}
return 0;
}