#include <bits/stdc++.h>
using namespace std;
const int MAX_EDGE = 200005;
const int MAX_VERTICES = 100005;
struct Edge{
int v, len, last;
} edge[2 * MAX_EDGE];
//开始是80分,后来改了一下就对了,原因是无向图的边集上限应该是题目给出上限的两倍而不是相同
bool vst[MAX_VERTICES];
int latest_edge_of_u[MAX_VERTICES];
int dis[MAX_VERTICES];
int eid, nv, ne;
void init(){
for(int i = 0 ; i < MAX_VERTICES ; i++){
vst[i] = false;
dis[i] = 200000000;
latest_edge_of_u[i] = -1;
}
eid = 0;
}
void insert(int w, int u, int v){
edge[eid].v = v;
edge[eid].len = w;
edge[eid].last = latest_edge_of_u[u];
latest_edge_of_u[u] = eid++;
edge[eid].v = u;
edge[eid].len = w;
edge[eid].last = latest_edge_of_u[v];
latest_edge_of_u[v] = eid++;
}
int find_min(){
int min_weight = 0, min_index = 0;
for(int i = 1 ; i < nv + 1 ; i++){
if(!vst[i]){
min_weight = dis[i];
min_index = i;
break;
}
}
for(int i = 1 ; i < nv + 1 ; i++){
if(!vst[i] && dis[i] < min_weight){
min_weight = dis[i];
min_index = i;
}
}
vst[min_index] = true; //这里易错
return min_index;
}
void dijkstra(int start){
dis[start] = 0;
for(int i = 1 ; i < nv + 1 ; i++){
int u = find_min();
for(eid = latest_edge_of_u[u] ; eid != -1 ; eid = edge[eid].last){
if(dis[edge[eid].v] > dis[u] + edge[eid].len){ //说明需要更新值
if(edge[eid].len <= dis[u]){
dis[edge[eid].v] = dis[u];
}
else dis[edge[eid].v] = edge[eid].len;
}
}
}
}
int main(){
cin >> nv >> ne;
init();
int a, b, c;
for(int i = 0 ; i < ne ; i++){
cin >> a >> b >> c;
insert(c, a, b);
}
dijkstra(1);
cout << dis[nv];
return 0;
}
问题描述 甲市有Ñ个交通枢纽,其中1号和Ñ号非常重要,为了加强运输能力,A市决定在1号到Ñ号枢纽间修建一条地铁。 输入格式 输入的第一行包含两个整数n,m,用一个空格分隔,分别表示交通枢纽的数量和候选隧道的数量。 输出格式 输出一个整数,修建整条地铁线路最少需要的天数。 样例输入 6 6 样例输出 6 样例说明 可以修建的线路有两种。 评测用例规模与约定 对于20%的评测用例,1≤ Ñ ≤10,1≤ 米 ≤20; |
目前只有80分,基于迪杰斯特拉改的,松弛方法改了一下,但是提交后显示有一组运行错误,还有一种基于最小生成树写的,在下一篇小结里面
20181209在青豪犀利的目光下,一眼看出了错误,就是边集数组开小了,应该开给出的边集数组的两倍,因为每两个顶点之间有两条边,将edge[MAX_EDGE]改为edge[2* MAX_EDGE]之后就过了最后一组数据,但依然是80分,不过这次的报错原因是超时,所以有了基于shaffer提供的heap X dijkstra 的100分解答:
//21:30
//这个代码目前有问题,需要找到一种合理有效的
//heap+dijkstra的优化算法
//对传统的算法/V/**2的时间复杂度可以过8组数据
//然而对于这个版本的理论上应该是(/V/ + /E/ )*log /V/的复杂度却有问题
//耗时几乎是前面基础版本的两倍,而且还有两组数据没过
#include <bits/stdc++.h>
using namespace std;
const int MAX_EDGE = 400050;
const int MAX_VERTICES = 100005;
int nv, ne;
struct Edge{
int v, last, w;
} edge[MAX_EDGE];
int eid, dist[MAX_VERTICES];
bool vst[MAX_VERTICES];
int latest_edge_of_u[MAX_VERTICES];
struct Dis{
int v;
int d;
Dis(){}
Dis(int v, int d){
this->v = v;
this->d = d;
}
bool operator < (const Dis & another) const{
return d > another.d;
}
} dis[MAX_VERTICES];
void init(){
eid = 0;
for(int i = 0 ; i <= nv ; i++){
vst[i] = false;
dis[i].d = 200000000;
dis[i].v = i;
dist[i] = 200000000;
latest_edge_of_u[i] = -1;
}
}
void insert(int w, int u, int v){
edge[eid].v = v;
edge[eid].w = w;
edge[eid].last = latest_edge_of_u[u];
latest_edge_of_u[u] = eid++;
edge[eid].v = u;
edge[eid].w = w;
edge[eid].last = latest_edge_of_u[v];
latest_edge_of_u[v] = eid++;
}
void dijkstra(int start){
dist[start] = 0;
dis[start].d = 0;
priority_queue <Dis> q;
Dis temp(start, 0);
int temp_vertex;
q.push(temp);
for(int i = 1 ; i <= nv ; i++){
do{
temp = q.top();
temp_vertex = temp.v;
q.pop();
}while(!q.empty() && vst[temp_vertex]);
vst[temp_vertex] = true;
for(eid = latest_edge_of_u[temp_vertex]; eid != -1; eid = edge[eid].last){
if(dist[edge[eid].v] > max(dist[temp_vertex] , edge[eid].w)){
dist[edge[eid].v] = max(dist[temp_vertex] , edge[eid].w);
}
temp.d = dist[edge[eid].v];
temp.v = edge[eid].v;
if(!vst[temp.v]){
q.push(temp);
}
}
}
}
int main(){
cin >> nv >> ne;
init();
int w, u, v;
for(int i = 0 ; i < ne ; i++){
cin >> u >> v >> w;
insert(w, u, v);
}
dijkstra(1);
cout << dist[nv];
return 0;
}
AC,本题结束