最短路径树

最短路径树

Define

最短路径树即为由一个给定的点出发,到每一个点的最短路径所构成的一棵树

求法

在图中设置一个根节点,进行一遍 dijkstra ,在过程中就可以处理出它的一棵最短路径树

例题

本题只需求得所用的最短路径树的数量即可

code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#define ll long long

const ll mod=2147483647ll;
const ll maxn=1e3+10;
ll n,m,tot,ans=1; 
ll head[maxn*maxn],dis[maxn],vis[maxn],num[maxn];
struct node
{
	ll u,v,w,nxt;
}s[maxn*maxn];

inline void add(ll u,ll v,ll w)
{
	s[++tot].v=v;
	s[tot].w=w;
	s[tot].nxt=head[u];
	head[u]=tot;
}

inline void dij(ll x)
{
	std::priority_queue<std::pair<ll,ll> > q;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[x]=0;
	q.push(std::make_pair(-dis[x],x));
	
	while(q.size())
	{
		ll u=q.top().second;
		q.pop();
		
		if(vis[u]) continue;
		vis[u]=1;
		
		for(int i=head[u];i;i=s[i].nxt)
		{
			ll v=s[i].v;
			ll w=s[i].w;
			
			if(dis[v]>dis[u]+w)
			{
				dis[v]=dis[u]+w;
				
				if(!vis[v])
				{
					q.push(std::make_pair(-dis[v],v));
				} 
			}
		}
	}
}

int main(void)
{
	scanf("%lld %lld",&n,&m);
	
	for(int i=1;i<=m;i++)
	{
		ll x,y,z;
		scanf("%lld %lld %lld",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	
	dij(1);
	
	for(int i=1;i<=n;i++)
	{
		for(int j=head[i];j;j=s[j].nxt)
		{
			ll v=s[j].v;
			ll w=s[j].w;
			
			if(dis[v]==dis[i]+w)
			{
				num[v]++;
			}
		}
	}
	
	for(int i=1;i<=n;i++)
	{
		if(num[i]) ans=ans*num[i]%mod;
	}
	
	printf("%lld\n",ans);
	
	return 0;
}
posted @ 2020-12-04 10:48  雾隐  阅读(108)  评论(0编辑  收藏  举报