链接:https://ac.nowcoder.com/acm/contest/547/E
来源:牛客网
题目描述
旅行商来到了一个新的国家,这个国家有N个城市,他们直接由N-1条道路相连接,每条道路的长度不尽相同
旅行商现在在1号城市,若他要每一个城市都游览一遍,他需要行走的最短路程是多少?
题解;城市很多,朴素地dijstra 存不下图,用堆优化的dij; 然后就是每个城市都走还要求最短路程 那就把最长的的一段路走一遍,其余路走两遍,(因为还有返回啊) (文中加粗意思是题中给出的数据就是每两点间的边值且唯一!!)
vector存图 牛客数据最后跑了85+ ~ 100+ms
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<queue>
#include<vector>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
typedef pair<int,int> p;
vector<p> e[maxn];
int dis[maxn];
int n;
void dij(int s){
priority_queue<p,vector<p>, greater<p> > q;
dis[s]=0;
q.push(make_pair(s,dis[s]));
while(!q.empty()){
pair<int,int>tmp;
tmp=q.top();
q.pop();
int u=tmp.first;
int size=e[u].size();
for(int i=0;i<size;i++){
int v=e[u][i].first;
if(dis[v]>dis[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<<dis[i]<<" ";
mxx=max(mxx,dis[i]);
}
//cout<<endl;
cout<<sum*2-mxx<<endl;
}
邻接表存图 跑了 37ms!! 可能领接表跑图快?还是加了VIS数组呐
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<queue>
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_queue<qnode>q;
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<<dis[i]<<" ";
mxx=max(mxx,dis[i]);
}
//cout<<endl;
cout<<sum*2-mxx<<endl;
return 0;
}