zoukankan      html  css  js  c++  java
  • [SDOI2009]Elaxia的路线

    下面的做法虽然能通过此题数据,但其实是错误的。请有兴趣的读者自行研究该算法的错误在哪里。

    思路:
    标算是跑四趟SPFA,然后拓扑排序求最长链。
    我的做法是对于两个起点、终点分别跑一个Dijkstra,然后枚举每个点对,判断是否都在最短路上,并对其距离取$max$。
    BZOJ上跑了440ms,内存6556KB,代码长度1906B,比标算不知miao到哪里去了。

     

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<functional>
     4 #include<ext/pb_ds/priority_queue.hpp>
     5 inline int getint() {
     6     char ch;
     7     while(!isdigit(ch=getchar()));
     8     int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int inf=0x7fffffff;
    13 const int V=1501;
    14 struct Edge {
    15     int to,w;
    16 };
    17 std::vector<Edge> e[V];
    18 inline void add_edge(const int u,const int v,const int w) {
    19     e[u].push_back((Edge){v,w});
    20 }
    21 struct Vertex {
    22     int id,dis;
    23     bool operator > (const Vertex &another) const {
    24         return dis>another.dis;
    25     }
    26 };
    27 int n,s1,t1,s2,t2;
    28 int ds1[V],dt1[V],ds2[V],dt2[V];
    29 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
    30 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[V];
    31 inline void Dijkstra(const int s,int *dis) {
    32     q.clear();
    33     for(int i=1;i<=n;i++) {
    34         p[i]=q.push((Vertex){i,dis[i]=(i==s?0:inf)});
    35     }
    36     while(q.top().dis!=inf) {
    37         int x=q.top().id;
    38         for(unsigned i=0;i<e[x].size();i++) {
    39             Edge &y=e[x][i];
    40             if(dis[x]+y.w<dis[y.to]) {
    41                 q.modify(p[y.to],(Vertex){y.to,dis[y.to]=dis[x]+y.w});
    42             }
    43         }
    44         q.modify(p[x],(Vertex){x,inf});
    45     }
    46 }
    47 inline bool check(const int x) {
    48     return (ds1[x]+dt1[x]==ds1[t1])&&(ds2[x]+dt2[x]==ds2[t2]);
    49 }
    50 int main() {
    51     n=getint();
    52     int m=getint();
    53     s1=getint(),t1=getint(),s2=getint(),t2=getint();
    54     for(int i=0;i<m;i++) {
    55         int u=getint(),v=getint(),w=getint();
    56         add_edge(u,v,w);
    57         add_edge(v,u,w);
    58     }
    59     Dijkstra(s1,ds1);
    60     Dijkstra(t1,dt1);
    61     Dijkstra(s2,ds2);
    62     Dijkstra(t2,dt2);
    63     int ans=0;
    64     for(int i=1;i<=n;i++) {
    65         if(!check(i)) continue;
    66         for(int j=i+1;j<=n;j++) {
    67             if(!check(j)) continue;
    68             ans=std::max(ans,std::abs(ds1[i]-ds1[j]));
    69         }
    70     }
    71     printf("%d
    ",ans);
    72     return 0;
    73 }

     后来把vector改成了数组,跑了436ms,只快了一点点,然而内存翻了三倍。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<functional>
     4 #include<ext/pb_ds/priority_queue.hpp>
     5 inline int getint() {
     6     char ch;
     7     while(!isdigit(ch=getchar()));
     8     int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int inf=0x7fffffff;
    13 const int V=1501;
    14 struct Edge {
    15     int to,w;
    16 };
    17 Edge e[V][V];
    18 int sz[V]={0};
    19 inline void add_edge(const int u,const int v,const int w) {
    20     e[u][sz[u]++]=(Edge){v,w};
    21 }
    22 struct Vertex {
    23     int id,dis;
    24     bool operator > (const Vertex &another) const {
    25         return dis>another.dis;
    26     }
    27 };
    28 int n,s1,t1,s2,t2;
    29 int ds1[V],dt1[V],ds2[V],dt2[V];
    30 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
    31 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[V];
    32 inline void Dijkstra(const int s,int *dis) {
    33     q.clear();
    34     for(int i=1;i<=n;i++) {
    35         p[i]=q.push((Vertex){i,dis[i]=(i==s?0:inf)});
    36     }
    37     while(q.top().dis!=inf) {
    38         int x=q.top().id;
    39         for(int i=0;i<sz[x];i++) {
    40             Edge &y=e[x][i];
    41             if(dis[x]+y.w<dis[y.to]) {
    42                 q.modify(p[y.to],(Vertex){y.to,dis[y.to]=dis[x]+y.w});
    43             }
    44         }
    45         q.modify(p[x],(Vertex){x,inf});
    46     }
    47 }
    48 inline bool check(const int x) {
    49     return (ds1[x]+dt1[x]==ds1[t1])&&(ds2[x]+dt2[x]==ds2[t2]);
    50 }
    51 int main() {
    52     n=getint();
    53     int m=getint();
    54     s1=getint(),t1=getint(),s2=getint(),t2=getint();
    55     for(int i=0;i<m;i++) {
    56         int u=getint(),v=getint(),w=getint();
    57         add_edge(u,v,w);
    58         add_edge(v,u,w);
    59     }
    60     Dijkstra(s1,ds1);
    61     Dijkstra(t1,dt1);
    62     Dijkstra(s2,ds2);
    63     Dijkstra(t2,dt2);
    64     int ans=0;
    65     for(int i=1;i<=n;i++) {
    66         if(!check(i)) continue;
    67         for(int j=i+1;j<=n;j++) {
    68             if(!check(j)) continue;
    69             ans=std::max(ans,std::abs(ds1[i]-ds1[j]));
    70         }
    71     }
    72     printf("%d
    ",ans);
    73     return 0;
    74 }
    View Code

    洛谷上跑出来152ms,Rank3。Rank2的做法是Dijkstra+拓扑排序。Rank1怎么跑这么快?

  • 相关阅读:
    线段树(单点更新) HDOJ 2795 Billboard
    线段树(单点更新) HDU 1754 I Hate It
    线段树(单点更新)/树状数组 HDOJ 1166 敌兵布阵
    递推DP URAL 1031 Railway Tickets
    记忆化搜索(DFS+DP) URAL 1223 Chernobyl’ Eagle on a Roof
    递推DP URAL 1244 Gentlemen
    DFS水题 URAL 1152 False Mirrors
    记忆化搜索(DFS+DP) URAL 1501 Sense of Beauty
    DP+高精度 URAL 1036 Lucky Tickets
    DP/最短路 URAL 1741 Communication Fiend
  • 原文地址:https://www.cnblogs.com/skylee03/p/7390094.html
Copyright © 2011-2022 走看看