【最短路径问题】计蒜客:圣诞树_数据结构

 

【最短路径问题】计蒜客:圣诞树_数据结构_02

以每个节点为起点,求到根节点的最短路,所有  最短路*权值 加起来即为结果。

解释如图

实现用迪杰斯特拉 算法

代码:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int w[50001];
struct node{
	int v;
	int w;
	node(int _v,int _w){
		v=_v;
		w=_w;
	}
};
vector<node>G[50001];
void insert1(int i,int j,int w)
{
	G[i].push_back(node(j,w));
}
void insert2(int i,int j,int w)
{
	insert1(i,j,w);
	insert1(j,i,w);
}
int n,m;
void input()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>w[i];
	}
	int a,b,c;
	for(int i=1;i<=m;i++){
		cin>>a>>b>>c;
		insert2(a,b,c);
	}
}
int dis[50001];
bool vis[50001];
void dij(int u)
{
	memset(dis,0x3f,sizeof(dis));
	memset(vis,false,sizeof(vis));
	dis[u]=0;
	
	for(int i=0;i<n;i++){
		int mindis=0x3f-1;
		int minj=-1;
		for(int j=1;j<=n;j++){
			if(!vis[j]&&dis[j]<mindis){
				mindis=dis[j];
				minj=j;
			}
		}
		
		if(minj==-1)return;
		vis[minj]=true;
		
		for(int j=0;j<G[minj].size();j++){
			int v=G[minj][j].v;
			int w=G[minj][j].w;
			if(!vis[j]&&dis[minj]+w<dis[v])
			{
				dis[v]=dis[minj]+w;
			}
		}
	}
}
int main()
{
	input(); 
	int res=0;
	for(int i=2;i<=n;i++)
	{
		dij(i);
		res+=w[i]*dis[1];
	}
	cout<<res;
}