牛客网 旅行商问题 堆优化dijstr

链接:https://ac.nowcoder.com/acm/contest/547/E
来源:牛客网
 

题目描述

旅行商来到了一个新的国家,这个国家有N个城市,他们直接由N-1条道路相连接,每条道路的长度不尽相同

旅行商现在在1号城市,若他要每一个城市都游览一遍,他需要行走的最短路程是多少?

题解;城市很多,朴素地dijstra 存不下图,用堆优化的dij;  然后就是每个城市都走还要求最短路程  那就把最长的的一段路走一遍,其余路走两遍,(因为还有返回啊)  (文中加粗意思是题中给出的数据就是每两点间的边值且唯一!!)

vector存图   牛客数据最后跑了85+ ~ 100+ms

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
typedef pair p;
vector

e[maxn]; int dis[maxn]; int n; void dij(int s){ priority_queue, greater

> q; dis[s]=0; q.push(make_pair(s,dis[s])); while(!q.empty()){ pairtmp; tmp=q.top(); q.pop(); int u=tmp.first; int size=e[u].size(); for(int i=0;idis[u]+e[u][i].second){ dis[v]=dis[u]+e[u][i].second; q.push(make_pair(v,dis[v])); } } } } int main(){ cin>>n; int m=n-1; for(int i=0;i<=n;i++){ dis[i]=inf; e[i].clear(); } int sum=0; while(m--){ int x,y,z; cin>>x>>y>>z; sum+=z; e[x].push_back(make_pair(y,z)); e[y].push_back(make_pair(x,z)); } dij(1); int mxx=0; for(int i=1;i<=n;i++){ // cout<

 邻接表存图  跑了 37ms!!    可能领接表跑图快?还是加了VIS数组呐

#include
#include
#include
#include
#include
#include
#include 
using namespace std;
const int maxn=1000005;
const int inf=0x3f3f3f3f;
struct Edge{
	int v,w;//w为距离 
	int next;
};
Edge edge[maxn];//边编号  从1开始   
struct qnode{    //堆优化 
     int u;	//起点 
     int w;//距离
     
   qnode(int u=0,int w=0):u(u),w(w){}//构造函数 
  
	bool operator < (const qnode& a) const{//重载小于号 
	return w>a.w;
	} 
};
int dis[maxn];
int head[maxn];
bool vis[maxn];
int x[maxn],y[maxn],z[maxn];
int n,m;
int size; 
void add_edge(int u,int v,int w){//邻接表加边 
	  edge[size].v=v;
	  edge[size].w=w;
	  edge[size].next=head[u];
	  head[u]=size;
	  size++; 
}
void dijkstra(int s){
	priority_queueq;
	while(!q.empty())
	q.pop();
	
    q.push(qnode(s,0));
	dis[s]=0;

	while(!q.empty()){
		qnode t=q.top();
		q.pop();
		int u=t.u;
		if(vis[u])continue;
		vis[u]=true;//找到一个点就标记一次 
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].v;
			int w=edge[i].w; 
			if(!vis[v]&&dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				q.push(qnode(v,dis[v]));//存到队堆里会自动利用堆 进行排序; 
			} 
		}	
	}
}
int main(){
	size=1;	
	scanf("%d",&n);
	for(int i=0;i<=n;i++){//初始化 
		head[i]=-1;
		dis[i]=inf;
		vis[i]=false; 
	}
	m=n-1;
	int sum=0;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x[i],&y[i],&z[i]);	
		sum+=z[i];
	}	
	for(int i=1;i<=m;i++){
		add_edge(x[i],y[i],z[i]);
		add_edge(y[i],x[i],z[i]);
	}
	
    dijkstra(1);
    int mxx=0;
	for(int i=1;i<=n;i++){
	//	cout<

 

你可能感兴趣的:(dijstra)