• POJ-1511 Invitation Cards---Dijkstra+队列优化+前向星正向反向存图


    题目链接:

    https://vjudge.net/problem/POJ-1511

    题目大意:

    给定节点数n,和边数m,边是单向边.

    问从1节点出发到2,3,...n 这些节点路程和从从这些节点回来到节点1的路程和最小值。

    n,m不超过1e6

    思路:

    POJ-3268是一样的,大概思路都是正向从源点求最短路,然后把图反向,再从源点求最短路,但是这道题是它的进阶版本,由于点数过多,不可以用邻接矩阵存图,这里用前向星存图,同时存下两张图,一张正向,一张反向。Dijkstra算法用队列优化,注意用long long存答案和dist最短路距离。其他的就是模板题了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<map>
     9 #include<set>
    10 #include<sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int maxn = 1e6 + 10;
    14 const int INF = 1e9 + 7;
    15 int T, n, m, cases;
    16 struct edge
    17 {
    18     int next, u, v, w;
    19 };
    20 edge a[2][maxn];//a[0][]存正边 a[1][]存反边
    21 ll d[maxn];
    22 int head[2][maxn];
    23 bool v[maxn];
    24 void init()
    25 {
    26     memset(head, -1, sizeof(head));
    27 }
    28 struct HeapNode
    29 {
    30     int d, u;//d是距离,u是顶点
    31     HeapNode(){}
    32     HeapNode(int d, int u):d(d), u(u){}
    33     bool operator <(const HeapNode & a)const
    34     {
    35         return d > a.d;
    36     }
    37 };
    38 void dijkstra(int cnt)
    39 {
    40     priority_queue<HeapNode>q;
    41     for(int i = 0; i <= n; i++)d[i] = INF;
    42     d[1] = 0;
    43     memset(v, 0, sizeof(v));
    44     q.push(HeapNode(0, 1));
    45     while(!q.empty())
    46     {
    47         HeapNode now = q.top();
    48         q.pop();
    49         int u = now.u;
    50         if(v[u])continue;
    51         v[u] = 1;//标记
    52         for(int i = head[cnt][u]; ~i; i = a[cnt][i].next)
    53         {
    54             edge& e = a[cnt][i];
    55             int v = e.v, w = e.w;
    56             if(d[v] > d[u] + w)
    57             {
    58                 d[v] = d[u] + w;
    59                 q.push(HeapNode(d[v], v));
    60             }
    61         }
    62     }
    63 }
    64 int main()
    65 {
    66     scanf("%d", &T);
    67     while(T--)
    68     {
    69         init();
    70         scanf("%d%d", &n, &m);
    71         int u, v, w;
    72         for(int i = 1; i <= m; i++)
    73         {
    74             scanf("%d%d%d", &u, &v, &w);
    75             //正向存边
    76             a[0][i].u = u;
    77             a[0][i].v = v;
    78             a[0][i].w = w;
    79             a[0][i].next = head[0][u];
    80             head[0][u] = i;
    81             //反向存边
    82             a[1][i].u = v;
    83             a[1][i].v = u;
    84             a[1][i].w = w;
    85             a[1][i].next = head[1][v];
    86             head[1][v] = i;
    87         }
    88         ll ans = 0;
    89         dijkstra(0);
    90         for(int i = 1; i <= n; i++)ans += d[i];
    91         dijkstra(1);
    92         for(int i = 1; i <= n; i++)ans += d[i];
    93         cout<<ans<<endl;
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    51. (转) Android学习路线
    Java字符串操作汇总
    49.Android中线程同步异步方式小结
    (转) Java多线程同步与异步
    (转) 40个Java多线程问题总结
    48.Android中android studio导入ApiDemos 问题小结
    47.Android View的加载过程 (转)
    46.Android View绘制过程 (转)
    45.Android 第三方开源库收集整理(转)
    三级联动
  • 原文地址:https://www.cnblogs.com/fzl194/p/8736210.html
Copyright © 2020-2023  润新知