P1529 [USACO2.4] 回家 Bessie Come Home
https://www.luogu.com.cn/problem/P1529
dji模板,不过是从终点反向跑。
不用vis数组写dij
dis数组就够了。
如果不加continue判断, 框图处多次出队会遍历相邻节点,导致复杂度最差变为N^2
具体例子参考:
https://usaco.guide/gold/shortest-paths?lang=cpp

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
struct edge {
int to, nxt, w;
}e[N*2];
int h[N], cnt;
void add(int u, int v, int w){
e[++cnt]={v, h[u], w};
h[u]=cnt;
}
int dis[256];
struct node {
int id, dis;
};
bool operator < (node a, node b){
return a.dis>b.dis;
}
void dij(int s){
memset(dis, 0x3f, sizeof dis);
priority_queue<node> q;
dis[s]=0;
q.push({s, 0});
while(!q.empty()){
int u, d;
u=q.top().id, d=q.top().dis; q.pop();
if(d!=dis[u]) continue;//不用vis数组, 也可以判断是否已经确定。 因为第一次出来的肯定是 d==dis[u]
for(int i=h[u]; i; i=e[i].nxt){
int v=e[i].to, w=e[i].w;
if(dis[v]>d+w){
dis[v]=d+w;
q.push({v, dis[v]});
}
}
}
}
int main(){
int m;
cin>>m;
for(int i=1;i<=m;i++){
int u, v, w;
char a, b;
cin>>a>>b>>w;
add(a, b, w);
add(b, a, w);
}
dij('Z');
int ans=INT_MAX;
char ansc;
for(char c='A';c<'Z'; c++){
// cout<<dis[c]<<" ";
if(dis[c]<ans) {
ans=dis[c];
ansc=c;
}
}
cout<<ansc<<" "<<ans;
return 0;
}

浙公网安备 33010602011771号