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

image

#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;
}
posted @ 2025-05-06 17:23  katago  阅读(15)  评论(0)    收藏  举报