zoukankan      html  css  js  c++  java
  • [洛谷1342]请柬

    题目大意:
    给定一个起点,求以其余所有点分别为必经点的最短回路之和。

    思路:
    建立反向图,在正反图上分别跑一遍Dijkstra,最后求和即可。
    注意数据规模,要开long long不然会WA,只能拿25分。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<vector>
     4 #include<ext/pb_ds/priority_queue.hpp>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const long long inf=0x7fffffffffffffff;
    13 const int V=1000001;
    14 struct Edge {
    15     int to;
    16     long long w;
    17 };
    18 std::vector<Edge> e1[V],e2[V];
    19 inline void add_edge(std::vector<Edge> *e,const int u,const int v,const long long w) {
    20     e[u].push_back((Edge){v,w});
    21 }
    22 struct Vertex {
    23     int id;
    24     long long dis;
    25     bool operator > (const Vertex &another) const {
    26         return dis>another.dis;
    27     }
    28 };
    29 int n;
    30 long long dis1[V],dis2[V];
    31 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
    32 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[V];
    33 const int s=1;
    34 inline void Dijkstra(long long *dis,std::vector<Edge> *e) {
    35     q.clear();
    36     for(register int i=1;i<=n;i++) {
    37         p[i]=q.push((Vertex){i,dis[i]=(i==s)?0:inf});
    38     }
    39     while(q.top().dis!=inf) {
    40         int x=q.top().id;
    41         for(register unsigned i=0;i<e[x].size();i++) {
    42             Edge &y=e[x][i];
    43             if(dis[x]+y.w<dis[y.to]) {
    44                 q.modify(p[y.to],(Vertex){y.to,dis[y.to]=dis[x]+y.w});
    45             }
    46         }
    47         q.modify(p[x],(Vertex){x,inf});
    48     }
    49 }
    50 int main() {
    51     n=getint();
    52     for(register int m=getint();m;m--) {
    53         int u=getint(),v=getint();
    54         long long w=getint();
    55         add_edge(e1,u,v,w);
    56         add_edge(e2,v,u,w);
    57     }
    58     Dijkstra(dis1,e1);
    59     Dijkstra(dis2,e2);
    60     long long ans=0;
    61     for(register int i=2;i<=n;i++) {
    62         ans+=dis1[i]+dis2[i];
    63     }
    64     printf("%lld
    ",ans);
    65     return 0;
    66 } 
  • 相关阅读:
    android -------- Data Binding的使用(二)
    牛客网-《剑指offer》-数值的整数次方[快速幂运算]
    牛客网-《剑指offer》-二进制中1的个数
    牛客网-《剑指offer》-矩形覆盖
    牛客网-《剑指offer》-变态跳台阶
    牛客网-《剑指offer》-跳台阶
    牛客网-《剑指offer》-斐波那契数列
    牛客网-《剑指offer》-旋转数组的最小数
    牛客网-《剑指offer》-用两个栈实现队列
    牛客网-《剑指offer》-重建二叉树
  • 原文地址:https://www.cnblogs.com/skylee03/p/7397509.html
Copyright © 2011-2022 走看看