201903-5 317号子任务(100分)

测试用例
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分
总结一下获得满分的几个条件(猜测):

  1. 求取最短路径时只求行星发动机据点到所有点的最短距离;使用一个二维数组存储,distance(行星发动机据点->普通点)=distance(普通点->行星发动机据点)
  2. 使用邻接链表存图
  3. 使用迪杰斯特拉算法,并且使用堆优化
  4. 求前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;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值