zoukankan      html  css  js  c++  java
  • 51-nod(1443)(最短路)

    解题思路:最短路+记录前驱和,刚开始一直以为是最短路+MST,结果发现,因为无向图的原因,有些边权很小的边再最短路处理后可能这条边也符合某两个点的最短路径,所以我们觉得这条边也是可以在MST处理中使用的,然而,发现选了这条边后,会导致剩下的点因为选定了不该选的边,因为MST中每条边的选定会确定两个点,所以,在计算最短路的时候记录最小前驱就可以了:2 3 50,2 5 40 ,5 3 10,3的最小前驱为10。。。;

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define ll long long
    #define maxn 1000050
    #define inf 1e15
    using namespace std;
    struct Edge
    {
        int to;
        int next;
        int w;
    }edge[maxn];
    struct node
    {
        int num;
        int dist;
        node(int _num,int _dist):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    int head[maxn];
    int cnt;
    int pre[maxn];
    ll dist[maxn];
    int f[maxn];
    int n,m;
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];
        edge[cnt].w=w;
        edge[cnt].to=v;
        head[u]=cnt++;
    }
    void dij(int x)
    {
        priority_queue<node>que;
        for(int i=1;i<=n;i++)
            dist[i]=inf;
        dist[x]=0;
        que.push(node(x,0));
        while(!que.empty())
        {
            //cout<<"x"<<endl;
            node u=que.top();
            que.pop();
            int now=u.num;
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(dist[v]>dist[now]+edge[i].w)
                {
                    dist[v]=dist[now]+edge[i].w;
                    que.push(node(v,dist[v]));
                    pre[v]=edge[i].w;
                }
                if(dist[v]==dist[now]+edge[i].w)
                {
                    pre[v]=min(pre[v],edge[i].w);
                }
            }
        }
    }
    int main()
    {
        int x,y,w;
        int e;
        memset(pre,0,sizeof(pre));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            f[i]=i;
        memset(head,-1,sizeof(head));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&w);
            add(x,y,w);
            add(y,x,w);
        }
        scanf("%d",&e);
        dij(e);
        ll as=0;
        for(int i=1;i<=n;i++)
            as+=pre[i];
       printf("%lld
    ",as);
    }
    

      

  • 相关阅读:
    垂直margin为什么会重叠
    forEach()和for/in循环的缺点与for-of循环
    使用CleanWebpackPlugin插件报错原因:CleanWebpackPlugin is not a constructor
    Vue中常用的组件库
    Vue中使用keep-alive优化网页性能
    Vue中router路由异步加载组件-优化性能
    面试题-JS中的作用域相关问题
    JS中的垃圾回收机制
    【转】 SpringMVC详解(三)------基于注解的入门实例
    【转】 SpringMVC详解(二)------详细架构
  • 原文地址:https://www.cnblogs.com/huangdao/p/9196934.html
Copyright © 2011-2022 走看看