L2-001 紧急救援 (25分)

//在查找迪杰斯特拉 优先级做法的时候看到了 优先队列优化的dijkstra不是万能的!L2-001 紧急救援 (25分)

主要有以下错误:

1.必须采用优先队列  并需要按路径大小排序(即pair需要些cmp函数才可实现)

2.
        if (d[v] !=   p.first)
        continue;//因为每次松弛操作后,要删除堆中原有的节点,这样很不方便,所以就加上这一句话判断是否被删除过。

需要加visit标记,否则可能有一条路径多次寻找到

 

 

 

#include<iostream>
#include<stdio.h>

#include<vector>

#include<queue>

#include<string.h>

using namespace std;
void printPath(int si);
struct edge{

	int to;

	int cost;

};

typedef pair<int,int> P;

vector<edge> e[1005];

int peo[1005];

int peo2[1005];

int d[1005];

int pre[1005];

int next2[1005]; 

int n,m,s,di;

int Num[1005];

bool visit[1005];


struct cmp
{
    bool operator()(const P p1, const P p2)

    {

        return p1.first > p2.first; //距离小值优先

    }

};

void dijkstra(int s, int end)

{

	memset(visit,false,sizeof(visit));

	fill(d,d+n,2140000);

	d[s]=0;Num[s]=1;

	priority_queue<P, vector<P>, cmp> que;

	que.push(P(0,s));

	while (!que.empty())

	{

		P p=que.top();que.pop();

		int v=p.second;
		if(visit[v]) continue;

		visit[v]=true;

		if (d[v]<p.first)
		continue;//因为每次松弛操作后,要删除堆中原有的节点,这样很不方便,所以就加上这一句话判断是否被删除过。
//cout<< "用" << v << "为起点:" << endl;
		for (int i=0;i<e[v].size();i++){

			edge tmp=e[v][i];

			if (d[tmp.to]==d[v]+tmp.cost){

				Num[tmp.to]+=Num[v];

				if (peo2[tmp.to]<peo2[v]+peo[tmp.to]){

				    que.push(P(d[tmp.to],tmp.to));
				    peo2[tmp.to]=peo2[v]+peo[tmp.to];
				    pre[tmp.to]=v;
	//			    	cout << tmp.to << "入栈," << d[tmp.to] << endl;


				}

			}

			if (d[tmp.to]>d[v]+tmp.cost)

			{
			
				Num[tmp.to]=Num[v];

				d[tmp.to]=d[v]+tmp.cost;
	//cout << tmp.to << "入栈," << d[tmp.to] << endl;

				que.push(P(d[tmp.to],tmp.to));

				peo2[tmp.to]=peo2[v]+peo[tmp.to];

				pre[tmp.to]=v;

			}else{
					//cout << tmp.to << "buxuyao入栈," << d[tmp.to] << endl;

			}
			if(tmp.to == end){
		//		printPath(end);
			}

		}

	}

}

void printPath(int di){
	
	int tmp2=di;

	int j=1;

	next2[0]=tmp2;

	while (tmp2!=s){	

		tmp2=pre[tmp2];

		next2[j++]=tmp2;

	}

	for (int i=j-1;i>0;i--)

	printf("%d ",next2[i]);

	printf("%d\n",di);

}

int main()

{

	memset(Num,0,sizeof(Num));

	scanf("%d%d%d%d",&n,&m,&s,&di);

	for (int i=0;i<n;i++)

	{

		scanf("%d",&peo[i]);

		peo2[i]=peo[i];

	}

	for (int i=0;i<m;i++)

	{

		edge tmp;int start,x1,x2;

		scanf("%d%d%d",&start,&x1,&x2);

		tmp.to=x1;tmp.cost=x2;

		e[start].push_back(tmp);

		tmp.to=start;tmp.cost=x2;

		e[x1].push_back(tmp);

	}

	dijkstra(s, di);


	printf("%d %d\n",Num[di],peo2[di]);
	printPath(di);	
	return 0; 

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值