1003 Emergency (25 分) 求最短路径条数+点权

题目链接

思路

就是模板题,在Dijkstra算法中每次更新到出发点距离是,判断一下,如果相等,那么就更新路径条数

AC代码

#include<bits/stdc++.h>
#define mem(a,b) memset(a ,b,sizeof a)
using namespace std;
const int N = 520;
int h[N*2],a[N],dis[N],cnt[N],num[N];
bool st[N];
int n,m,c1,c2,idx;
struct node
{
	int e,ne,w;
}node[N*2];
void add(int a,int b,int c)
{
	node[idx]={b,h[a],c};
	h[a]=idx++;
}
struct Node
{
	int d,p;
	bool operator<(const Node &t) const
	{
		return d>t.d;
	}
};
void Dijkstra()
{
	priority_queue<Node> q;
	mem(dis,0x3f);
	dis[c1]=0,num[c1]=a[c1],cnt[c1]=1;
	q.push({0,c1});
	while(q.size())
	{
		Node tmp=q.top();q.pop();
		int p=tmp.p,d=tmp.d;
		if(st[p]) continue;
		st[p]=true;
		for(int i=h[p]; i!=-1; i=node[i].ne)
		{
			int j=node[i].e,w=node[i].w;
			if(dis[j]>d+w)
			{
				dis[j]=d+w;
				q.push({dis[j],j});
				cnt[j]=cnt[p];//路径条数不变 
				num[j]=num[p]+a[j];//跟新救援人数 
			}//注意这里是else if 
			else if(dis[j]==d+w) 
			{
				//说明j多次被更新,每次更新一次,就多cnt[p]条路 
				cnt[j]+=cnt[p];
				if(num[j]<num[p]+a[j]) num[j]=num[p]+a[j];
			}
		}
	} 
}
int main()
{
    mem(h,-1);
    cin>>n>>m>>c1>>c2;
    for(int i=0; i<n; i++) scanf("%d",a+i);
    for(int i=0; i<m; i++)
    {
    	int u,v,w;
    	cin>>u>>v>>w;
    	add(u,v,w),add(v,u,w);
	}
	Dijkstra();
	cout<<cnt[c2]<<" "<<num[c2];
	return 0;
 } 
posted @ 2022-08-28 08:43  翔村亲亲鸟  阅读(11)  评论(0编辑  收藏  举报