• 汕头市赛srm8 C-3


    n<=100000个点m<=300000条边有权无向联通图,给出K<=10000个特殊点求K个点中任意两点最短路的最小值。

    方法一:K小,随便搞。先构造最短路树,在最短路树上Dijkstra,遇到第一个特殊点就返回。代码如下:

    如下个头。首先时间复杂度显然超了,其次建树时要考虑重边,比较难搞。

    方法二:多源最短路。

    插播:多源最短路方法:把每个源加进初始队列即可。

    (1)利用多源最短路求出每个特殊点到其它点的最短路和次短路,利用两个的和来更新。一位大神在比赛中用该方法A过。

    (2)直接求每个特殊点到其它点的最短路,把Dijkstra中的vis数组去掉,就是凡是松弛过的点都扔进优先队列里,然后,在松弛前,如果该点已经有最短路了,(我认为)现在访问的这条路径是次短路,直接更新答案。

    注意不能用  来自同个特殊点的最短路  更新答案,所以记每个点的最短路来自哪个特殊点。

    (3)随机化。把K分成两部分S,T,求S到T的最短路,这样得到正确答案的概率为1/2,多分几次就可以把错误概率降到极低。

    代码为方法二(2)。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<queue>
     6 //#include<iostream>
     7 using namespace std;
     8 
     9 int n,m,K;
    10 #define maxn 100011
    11 #define maxm 600011
    12 const int inf=0x7fffffff;
    13 struct Edge{int to,v,next;};
    14 struct Graph
    15 {
    16     Edge edge[maxm];int le;
    17     int first[maxn],dis[maxn],id[maxn],start[maxn];bool vis[maxn];
    18     Graph()
    19     {
    20         memset(first,0,sizeof(first));
    21         le=2;
    22     }
    23     void add_edge(int x,int y,int v)
    24     {
    25         Edge &e=edge[le];
    26         e.to=y;e.v=v;
    27         e.next=first[x];
    28         first[x]=le++;
    29     }
    30     void insert(int x,int y,int v)
    31     {
    32         add_edge(x,y,v);
    33         add_edge(y,x,v);
    34     }
    35     struct heapnode
    36     {
    37         int x,v;
    38         bool operator < (const heapnode &b) const {return v<b.v;}
    39         bool operator > (const heapnode &b) const {return v>b.v;}
    40     };
    41     priority_queue<heapnode,vector<heapnode>,greater<heapnode> > q;
    42     int ans;
    43     int dijkstra()
    44     {
    45         for (int i=1;i<=n;i++) dis[i]=inf;
    46         memset(id,0,sizeof(id));
    47         for (int i=1;i<=K;i++)
    48         {
    49             dis[start[i]]=0;
    50             id[start[i]]=start[i];
    51             q.push((heapnode){start[i],0});
    52         }
    53         ans=inf;
    54         while (!q.empty())
    55         {
    56             const int now=q.top().x,d=q.top().v;
    57             q.pop();
    58             if (d!=dis[now]) continue;
    59             for (int i=first[now];i;i=edge[i].next)
    60             {
    61                 const Edge &e=edge[i];
    62                 if (dis[e.to]!=inf && id[now]!=id[e.to])
    63                     ans=min(ans,dis[e.to]+d+e.v);
    64                 if (dis[e.to]>d+e.v)
    65                 {
    66                     dis[e.to]=d+e.v;
    67                     id[e.to]=id[now];
    68                     q.push((heapnode){e.to,dis[e.to]});
    69                 }
    70             }
    71         }
    72         return ans;
    73     }
    74 }G;
    75 int x,y,v;
    76 int main()
    77 {
    78     scanf("%d%d%d",&n,&m,&K);
    79     for (int i=1;i<=K;i++) scanf("%d",&G.start[i]);
    80     for (int i=1;i<=m;i++)
    81     {
    82         scanf("%d%d%d",&x,&y,&v);
    83         G.insert(x,y,v);
    84     }
    85     printf("%d
    ",G.dijkstra());
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    查看客户端的IP地址,机器名,MAC地址,登陆名等信息
    查看sqlserver 2008中性能低下的语句
    搜索包含指定关键字的存储过程
    获得客户端详细信息以及每个进程的sql语句
    实战:sqlserver 日常检查脚本
    NIO的学习总结
    JavaWEB过滤器和监听器技术
    抽象工厂模式代码:
    详解 equals() 方法和 hashCode() 方法
    net.sf.json JSONObject与JSONArray使用实例
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7246115.html
Copyright © 2020-2023  润新知