• Bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路 dijkstra,堆,A*,次短路


    1726: [Usaco2006 Nov]Roadblocks第二短路

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 969  Solved: 468
    [Submit][Status][Discuss]

    Description

    贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。 

    Input

    * 第1行: 两个整数,N和R,用空格隔开 

    * 第2..R+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为 D(1 <= D <= 5000)的路连接农场A和农场B

    Output

    * 第1行: 输出一个整数,即从农场1到农场N的第二短路的长度 

    Sample Input

    4 4
    1 2 100
    2 4 200
    2 3 250
    3 4 100


    Sample Output

    450

    输出说明:

    最短路:1 -> 2 -> 4 (长度为100+200=300)
    第二短路:1 -> 2 -> 3 -> 4 (长度为100+250+100=450)

    HINT

     

    Source

    Gold

    dijkstra+堆优化+A*

    这道题可以正着跑个最短路,倒着跑个最短路,然后枚举每一条边,依次替换即可。

    然而我刚学习了A*,就拿A*水了水。

    A*果然快的飞起。。。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define MAXN 5010
      4 #define MAXM 100010
      5 #define INF 1e9
      6 struct node
      7 {
      8     int begin,end,value,next;
      9 }edge[2*MAXM];
     10 int cnt,Head[MAXN],cdl,pos[MAXN],Heap[MAXN*2],Heap1[MAXN*2],dis[MAXN],n,SIZE,Time[MAXN];
     11 void addedge(int bb,int ee,int vv)
     12 {
     13     edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
     14 }
     15 void addedge1(int bb,int ee,int vv)
     16 {
     17     addedge(bb,ee,vv);addedge(ee,bb,vv);
     18 }
     19 int read()
     20 {
     21     int s=0,fh=1;char ch=getchar();
     22     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     23     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     24     return s*fh;
     25 }
     26 void Push1(int k)
     27 {
     28     int now=k,root;
     29     while(now>1)
     30     {
     31         root=now/2;
     32         if(dis[Heap[root]]<=dis[Heap[now]])return;
     33         swap(Heap[root],Heap[now]);
     34         swap(pos[Heap[root]],pos[Heap[now]]);
     35         now=root;
     36     }
     37 }
     38 void Insert(int k)
     39 {
     40     Heap[++SIZE]=k;pos[k]=SIZE;Push1(SIZE);
     41 }
     42 void Pop1(int k)
     43 {
     44     int now,root=k;
     45     pos[Heap[k]]=0;Heap[k]=Heap[SIZE--];if(SIZE>0)pos[Heap[k]]=k;
     46     while(root<=SIZE/2)
     47     {
     48         now=root*2;
     49         if(now<SIZE&&dis[Heap[now+1]]<dis[Heap[now]])now++;
     50         if(dis[Heap[root]]<=dis[Heap[now]])return;
     51         swap(Heap[root],Heap[now]);
     52         swap(pos[Heap[root]],pos[Heap[now]]);
     53         root=now;
     54     }
     55 }
     56 void dijkstra(int start)
     57 {
     58     int i,u,v;
     59     for(i=1;i<=n;i++)dis[i]=INF;dis[start]=0;
     60     for(i=1;i<=n;i++)Insert(i);
     61     while(SIZE>0)
     62     {
     63         u=Heap[1];Pop1(pos[u]);
     64         for(i=Head[u];i!=-1;i=edge[i].next)
     65         {
     66             v=edge[i].end;
     67             if(dis[v]>dis[u]+edge[i].value){dis[v]=dis[u]+edge[i].value;Push1(pos[v]);}
     68         }
     69     }
     70 }
     71 void Push2(int k,int k1)
     72 {
     73     int now,root;
     74     Heap[++SIZE]=k;Heap1[SIZE]=k1;now=SIZE;
     75     while(now>1)
     76     {
     77         root=now/2;
     78         if(Heap1[root]<=Heap1[now])return;
     79         swap(Heap[root],Heap[now]);
     80         swap(Heap1[root],Heap1[now]);
     81         now=root;
     82     }
     83 }
     84 void Pop2()
     85 {
     86     int now,root;
     87     Heap[1]=Heap[SIZE];Heap1[1]=Heap1[SIZE--];root=1;
     88     while(root<=SIZE/2)
     89     {
     90         now=root*2;
     91         if(now<SIZE&&Heap1[now+1]<Heap1[now])now++;
     92         if(Heap1[root]<=Heap1[now])return;
     93         swap(Heap[root],Heap[now]);
     94         swap(Heap1[root],Heap1[now]);
     95         root=now;
     96     }
     97 }
     98 void astar(int start)
     99 {
    100     int u1,u2,i,v;
    101     Push2(start,dis[start]);
    102     while(SIZE>0)
    103     {
    104         u1=Heap[1];u2=Heap1[1];Pop2();
    105         Time[u1]++;
    106         if(u1==n&&Time[u1]==2){cdl=u2;return;}
    107         if(Time[u1]>2)continue;
    108         for(i=Head[u1];i!=-1;i=edge[i].next)
    109         {
    110             v=edge[i].end;
    111             Push2(v,u2-dis[u1]+dis[v]+edge[i].value);
    112         }
    113     }
    114 }
    115 int main()
    116 {
    117     freopen("block.in","r",stdin);
    118     freopen("block.out","w",stdout);
    119     int bb,ee,vv,m,i;
    120     n=read();m=read();
    121     memset(Head,-1,sizeof(Head));cnt=1;
    122     for(i=1;i<=m;i++)
    123     {
    124         bb=read();ee=read();vv=read();
    125         addedge1(ee,bb,vv);
    126     }
    127     dijkstra(n);
    128     cdl=0;SIZE=0;
    129     astar(1);
    130     printf("%d",cdl);
    131     fclose(stdin);
    132     fclose(stdout);
    133     return 0;
    134 }
  • 相关阅读:
    Business English E-mail
    向数据库更新数据
    遍历DataTable
    Convert SqlDataReader to DataTable
    (十七)map、flatMap和reduce方法的补充
    (4)六顶思考帽
    (3)学习方法思维导图
    (十六)call、apply、bind的实现以及区别
    (十五)关于继承
    (十四)防抖和节流
  • 原文地址:https://www.cnblogs.com/Var123/p/5337739.html
Copyright © 2020-2023  润新知