Dijkstra 邻接表+优先队列


#include<iostream>
#include<vector>
#include<queue>

using namespace std;

int dp[100005];

typedef long long ll;
const ll inf =  ~0LLU >> 2;
const int Num = 1e5+5;

struct edge{
    int from,to,w;
    edge(int a,int b,int c){from=a;to=b;w=c;}
};

vector<edge>e[Num];

struct s_node{
    int id;
    ll n_dis;
    s_node(int b,ll c){id=b;n_dis=c;}
    bool operator < (const s_node &a)const// 自身元素在前 相当于(int a,int b) n_dis 相当于 a
    {
        return n_dis>a.n_dis;
    }
};

int n,m;
int pre[Num];

void print_path(int s,int t)
{
    if(s==t)
    {
        printf("%d ",s);
        return;
    }
    print_path(s, pre[t]);
    printf("%d",t);
}


void dijkstra(int beigin,int dist)
{
    int s = beigin;  //s为起点
    ll dis[Num];//所有节点到起点的位置
    bool done[Num];
    for(int i =1;i<=n;i++)
    {
        dis[i]=inf;
        done[i]=false;
    }
    dis[s]=0;
    priority_queue<s_node>Q;
    Q.push(s_node(s,dis[s]));
    while (!Q.empty()) {
        s_node u =Q.top();
        Q.pop();
        if(done[u.id])
            continue;//丢弃已经找到最短路径的结点
        done[u.id] = true;
        for(int i =0;i<e[u.id].size();i++)
        {
            edge y = e[u.id][i];
            if(done[y.to])
                continue;
            if(dis[y.to]>y.w + u.n_dis)
            {
                dis[y.to] = y.w + u.n_dis;
                Q.push(s_node(y.to,dis[y.to]));
                pre[y.to] = u.id;
            }
        }
    }
    printf("%lld\n",dis[dist]);
    print_path(s, n);
}

string ss;
int s,t,x;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int num ;
    cin>>num;
    while (num--) {
       
        cin>>n>>m>>s>>t>>x;//有n个村庄 m条道路 s为起点 t为终点
        cin>>ss;
        for(int i =1;i<=n;i++)
        {
            e[i].clear();
        }
        while (m--) {
            int a,b,c;//a b之间的路径长度为c
            cin>>a>>b>>c;
            e[a].push_back(edge(a,b,c));
            e[b].push_back(edge(b,a,c));
        }
        dijkstra(s,t);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值