Dijkstra算法 Atcoder-070-D

来源:互联网 发布:数据库查询去除重复 编辑:程序博客网 时间:2024/05/17 18:42

题意:

给你一棵无向树,然后给你一个点K,q个查询,每个查询一个x一个y,问从x到y经过k的最短路径


题目链接:点击打开链接

其实这个就是一个单源最短路的问题,以k为单源点,求k到每个点的最短距离,d[i],然后,从x到y的最短路径就是d[x]+d[y];

这个题目转化一下思维方式就行了


注意点:

这是一个无向树,在构造边的时候要注意,两个方向都要加上

代码如下:

#include <iostream>#include <cstdio>#include <vector>#include <algorithm>#include <cstring>#include <queue>using namespace std;const int MAXN=1e5+50;const long long INF=1e18;int n;int k,p;long long dis[MAXN];int vis[MAXN];struct Edge{    int from;    int to;    int cost;    Edge(int a,int b,int c)    {        from=a;        to=b;        cost=c;    }};vector<Edge> edges;vector<int> G[MAXN];void Init(){    for(int i=0; i<=n; i++)        G[i].clear();    edges.clear();}struct Heap{    int d,u;    Heap(int a,int b)    {        d=a,u=b;    }    bool operator<(Heap h)const    {        return d>h.d;    }};void Dijkstra(int s){    priority_queue<Heap> p;    p.push(Heap(0,s));    for(int i=0; i<=n; i++) dis[i]=INF;    dis[s]=0;    memset(vis,0,sizeof(vis));    while(!p.empty())    {        Heap h=p.top();        p.pop();        int  u=h.u;        if(vis[u]) continue;        for(int i=0; i<G[u].size(); i++)        {            Edge &e=edges[G[u][i]];            if(vis[e.to]) continue;            if(dis[e.to]>dis[u]+e.cost)            {                dis[e.to]=dis[u]+e.cost;                p.push(Heap(dis[e.to],e.to));            }        }    }}int main(){    scanf("%d",&n);    Init();    for(int i=0; i<n-1; i++)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        edges.push_back(Edge(x,y,z));        G[x].push_back(2*i);//无向边,两个方向加        edges.push_back(Edge(y,x,z));        G[y].push_back(2*i+1);    }    scanf("%d%d",&p,&k);    Dijkstra(k);    //for(int i=0;i<=n;i++)    //    cout<<dis[i]<<" ";    //  cout<<endl;    for(int i=0; i<p; i++)    {        int x,y;        scanf("%d%d",&x,&y);        cout<<dis[x]+dis[y]<<endl;    }    return 0;}



原创粉丝点击