L2-001 紧急救援 (25分)

在这里插入图片描述
与一般最短路题目相比,多了节点的权重以及输出路径。
在简单的djs基础上,多了到达每个节点的最大救援数以及更新路径:倒序更新,使用pre函数,如在pre[s(终点)]可能的值中找到最大救援的路径,这样就不仅满足>关系更新,=时也要更新。

inline void djs()
{
	for(re int i=1;i<=n;i++)dis[i]=2147483647;
	dis[s]=0;
	priority_queue<node>Q;//初始化
	
	node a ={s,0};
	Q.push(a);//第一个node
	
	while(!Q.empty())
	{
		node fr=Q.top();Q.pop();
		int u=fr.u,d=fr.d;
		//取出并记录
		if(d!=dis[u])continue;//避免处理无用数据,也就是dis[u]已经更新,之前未更新数据直接出栈,比如有一组数据 2 5,但是后面又入栈一组数据2 3,则2 5是无用数据
		for(re int j=0;j<g[u].size();j++)
		{
			int tm=g[u][j].to;
			if(dis[u]+g[u][j].cost<dis[tm])
			{			 
            	dis[tm]=dis[u]+g[u][j].cost;
				Q.push((node){tm,dis[tm]});
			}
		}
	}
}
#include<bits/stdc++.h>
#define intn long long
#define ls(k) (k)<<1
#define inf 2147483647
#define re register
#define rs(k) (k)<<1|1
#define _0for(i, a) for(int i = 0; i < (a); ++i)
#define _1for(i, a) for(int i = 1; i <=(a); ++i)
#define lowbit(x) ((x)&(-x))
#define debug(x) \
(void)(cerr << "L" << __LINE__\
			<< " : " << #x << " = " \
			<< (x) << endl )

using namespace std;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct edge
{
	int to,cost;
};
struct node
{
	int u,d;
	bool operator <(const node&rhs)const
	{
		return d>rhs.d;
	}
};
int n,dis[20000],s,m,d;
vector<edge>g[50000];
int road[20000];
int jy[200000];
int pre[200000];
int gejy[200000];
void djs()
{
	for(re int i=0;i<=n;i++)dis[i]=inf;
	dis[s]=0;
	priority_queue<node>Q;
	node a={s,0};
	Q.push(a);
	while(!Q.empty())
	{
		node fr=Q.top();
		Q.pop();
		int u=fr.u,d=fr.d;
		if(road[u]==0)road[u]=1;
		if(d!=dis[u])continue;
		for(re int j=0;j<g[u].size();j++)
		{
			int tm=g[u][j].to;
			if(dis[u]+g[u][j].cost<dis[tm])
			{
				dis[tm]=dis[u]+g[u][j].cost;
				Q.push((node){tm,dis[tm]});
				road[tm]=road[u];
				pre[tm]=u;
				gejy[tm]=gejy[u]+jy[tm];
			}
			else if(dis[u]+g[u][j].cost==dis[tm])
			{
				road[tm]+=road[u];
				if(gejy[tm]<gejy[u]+jy[tm])//找到最大救援数的节点。
				{
					pre[tm]=u;
				}
				gejy[tm]=max(gejy[tm],gejy[u]+jy[tm]);
			}
		}
	}
}
void outpath()
{
	stack<int> st;
	st.push(d);
	for(int i=pre[d];i!=-1;i=pre[i])
	{
		st.push(i);
	}
	int x=st.top();
	printf("%d",x);
	st.pop();
	while(!st.empty())
	{
		int x=st.top();
		printf(" %d",x);
		st.pop();
	}
}
main(void)
{
	cin>>n>>m>>s>>d;
	fill(pre,pre+10000,-1);
	for(int i=0;i<n;i++)
	{
		cin>>jy[i];
		gejy[i]=jy[i];
	}
	for(int i=0;i<m;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		g[a].push_back(edge{b,c});
		g[b].push_back(edge{a,c});
	}
	djs();
	printf("%d %d\n",road[d],gejy[d]);
	outpath();
}

posted @ 2020-11-27 20:06  王乾宇  阅读(126)  评论(0编辑  收藏  举报